あめがえるのITブログ

頑張りすぎない。ほどほどに頑張るブログ。

【AWS】11/18(月) Amazon DynamoDB、属性ベースのアクセス制御(ABAC)の一般提供


11/18(月)Amazon DynamoDB、属性ベースのアクセス制御(ABAC)の一般提供開始したようなので、Terraformで環境作りつつ動作確認してみた。
aws.amazon.com

ABACとは

アクセス制御をリソースのタグやユーザーの属性などの条件に基づいて行う仕組み。ABACを使用することで、IAMポリシーを動的かつ柔軟に管理できる。

構成

こんな感じ

実践!

1.環境作成
1-1.下記ファイルを作成
version.tf

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
  required_version = ">= 1.0.0"
}

provider.tf

provider "aws" {
  profile = "testvault"
  region  = "ap-northeast-1"
}

main.tf

resource "aws_dynamodb_table" "example_table" {
  name         = "ExampleTable"
  billing_mode = "PAY_PER_REQUEST"
  hash_key     = "key"

  attribute {
    name = "key"
    type = "S"
  }

  tags = {
    Environment = "dev"
    Name        = "ExampleTable"
    Team        = "Finance"       # ABACで利用するタグ (例)
    Owner       = "Admin"         # ABACで利用するタグ (例)
  }
}

resource "aws_dynamodb_table_item" "example_item" {
  table_name = aws_dynamodb_table.example_table.name
  hash_key   = aws_dynamodb_table.example_table.hash_key

  item = <<ITEM
{
  "key": {"S": "1"},
  "name": {"S": "テストデータ"}
}
ITEM
}

resource "aws_iam_role" "lambda_execution_role" {
  name = "lambda-execution-role"

  assume_role_policy = jsonencode({
    Version = "2012-10-17",
    Statement = [
      {
        Effect = "Allow",
        Principal = {
          Service = "lambda.amazonaws.com"
        },
        Action = "sts:AssumeRole"
      }
    ]
  })
}

resource "aws_iam_role_policy" "lambda_dynamodb_abac_policy" {
  role = aws_iam_role.lambda_execution_role.id

  policy = jsonencode({
    Version = "2012-10-17",
    Statement = [
      {
        Effect = "Allow",
        Action = [
          "dynamodb:GetItem",
          "dynamodb:PutItem",
          "dynamodb:UpdateItem",
          "dynamodb:DeleteItem"
        ],
        Resource = aws_dynamodb_table.example_table.arn,
        Condition = {
          StringEquals = {
            "aws:ResourceTag/Team": "Finance", 
            "aws:ResourceTag/Owner": "Admin"
             # リソースにタグ "Team=Finance"と"Owner=Admin" がある場合許可
          }
        }
      }
    ]
  })
}

resource "aws_lambda_function" "example_lambda" {
  filename      = "lambda_function.zip" # ZIPファイルのパス
  function_name = "example_lambda"
  role          = aws_iam_role.lambda_execution_role.arn
  handler       = "lambda_function.lambda_handler"
  runtime       = "python3.9"

  environment {
    variables = {
      TABLE_NAME = aws_dynamodb_table.example_table.name
    }
  }
}

lambda_function.py

import boto3
import os

def lambda_handler(event, context):
    # DynamoDBクライアントの初期化
    dynamodb = boto3.resource('dynamodb')
    table_name = os.environ['TABLE_NAME']
    table = dynamodb.Table(table_name)

    # DynamoDBテーブルからデータを取得
    response = table.get_item(Key={"key": "1"})
    item = response.get('Item', {})

    return {
        "statusCode": 200,
        "body": item
    }

1-2.lambda_function.pyをzip化し、tfファイルと同じ階層のフォルダに保存
1-3.terraform実行

> terraform fmt
> terraform init
> terraform plan
> terraform apply


DynamoDBのテーブルにABAC制御用のタグを付与し、接続元のIAMロールでタグを許可するようポリシー設定する。



2.動作確認
2-1.作成したLambda関数のテストを実行し、200OKとアイテム情報が返ってくることを確認