[Terraform] aws_iam_policy_document를 이용한 정책 작성 방법

HYEOB KIM·2022년 6월 8일
1

Terraform

목록 보기
3/11

개요

  • AWS를 이용하다보면 다양한 곳에서 정책을 작성하게 됩니다. 이를 테라폼으로 작성할 때 aws_iam_policy_document data source를 이용해서 정책을 작성하면 깔끔하게 작성할 수 있습니다.

aws_iam_policy_document를 이용한 정책 작성 방법

data sourceaws_iam_policy_document안에 statement를 각 항목에 대해 정해진 형식으로 작성하면 됩니다.

아래와 같은 형식으로 statement를 작성할 수 있습니다.

variable "s3_bucket_name" {
  default = "test-hyeob"
}

data "aws_iam_policy_document" "example" {
  statement {
    sid = "1"

    actions = [
      "s3:ListAllMyBuckets",
      "s3:GetBucketLocation",
    ]

    resources = [
      "arn:aws:s3:::*",
    ]
  }

  statement {
    actions = [
      "s3:ListBucket",
    ]

    resources = [
      "arn:aws:s3:::${var.s3_bucket_name}",
    ]

    condition {
      test     = "StringLike"
      variable = "s3:prefix"

      values = [
        "",
        "home/",
        "home/&{aws:username}/",
      ]
    }
  }

  statement {
    actions = [
      "s3:*",
    ]

    resources = [
      "arn:aws:s3:::${var.s3_bucket_name}/home/&{aws:username}",
      "arn:aws:s3:::${var.s3_bucket_name}/home/&{aws:username}/*",
    ]
  }
}

resource "aws_iam_policy" "example" {
  name   = "example_policy"
  path   = "/"
  policy = data.aws_iam_policy_document.example.json
}

이를 실행시키면 example_policy라는 정책이 생성됩니다.
정책 내용은 아래와 같습니다.

{
    "Statement": [
        {
            "Action": [
                "s3:ListAllMyBuckets",
                "s3:GetBucketLocation"
            ],
            "Effect": "Allow",
            "Resource": "arn:aws:s3:::*",
            "Sid": "1"
        },
        {
            "Action": "s3:ListBucket",
            "Condition": {
                "StringLike": {
                    "s3:prefix": [
                        "",
                        "home/",
                        "home/${aws:username}/"
                    ]
                }
            },
            "Effect": "Allow",
            "Resource": "arn:aws:s3:::test-hyeob",
            "Sid": ""
        },
        {
            "Action": "s3:*",
            "Effect": "Allow",
            "Resource": [
                "arn:aws:s3:::test-hyeob/home/${aws:username}/*",
                "arn:aws:s3:::test-hyeob/home/${aws:username}"
            ],
            "Sid": ""
        }
    ],
    "Version": "2012-10-17"
}

aws_iam_policy_document 안의 내용이 JSON 형식으로 어떻게 변환되는지를 보시기 바랍니다.

s3 정책 생성 예제

위의 예제에서는 data source를 이용해 정책을 직접 생성했지만,
data source를 생성만 하고, s3 bucket 정책에 바로 적용할 수도 있습니다.

resource "aws_s3_bucket" "test" {
  bucket = "tf-test-hyeob-bucket"

  tags = {
    Name        = "tf-test-hyeob"
    Environment = "Dev"
  }
}

resource "aws_s3_bucket_acl" "test" {
  bucket = aws_s3_bucket.test.id
  # `private`, `public-read`, `public-read-write`, `aws-exec-read`, `authenticated-read`, `log-delivery-write` 중 하나 선택. 
  # 기본값은 `private`.
  # `grant`와 대비되는 속성
  acl = "public-read-write"
}

# 버킷 정책
resource "aws_s3_bucket_policy" "allow_access_from_another_account" {
  bucket = aws_s3_bucket.test.id
  policy = data.aws_iam_policy_document.allow_access_from_another_account.json
}

data "aws_iam_user" "test" {
  user_name = var.user_id
}

data "aws_iam_policy_document" "allow_access_from_another_account" {
  statement {
    sid = "bucketPolicyTest"
    principals {
      type        = "AWS"
      identifiers = ["${data.aws_iam_user.test.id}"]
    }

    actions = [
      "s3:GetObject",
      "s3:ListBucket",
    ]

    resources = [
      aws_s3_bucket.test.arn,
      "${aws_s3_bucket.test.arn}/*",
    ]

    effect = "Allow"

    condition {
      test     = "IpAddressIfExists"
      variable = "aws:SourceIp"

      values = [
        "1.1.1.1"
      ]
    }
  }
}

위 테라폼 파일을 실행하면 버킷이 생성되고, 아래와 같은 정책을 가지게 됩니다.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "bucketPolicyTest",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::797587922006:user/khyup0629@hongikit.com"
            },
            "Action": [
                "s3:ListBucket",
                "s3:GetObject"
            ],
            "Resource": [
                "arn:aws:s3:::tf-test-hyeob-bucket/*",
                "arn:aws:s3:::tf-test-hyeob-bucket"
            ],
            "Condition": {
                "IpAddressIfExists": {
                    "aws:SourceIp": "1.1.1.1"
                }
            }
        }
    ]
}

결론

  • 데이터 소스를 활용하면 정책을 모듈화해서 깔끔하게 코드를 관리할 수 있고, 재사용하기 쉬워집니다.
  • aws_iam_policy_document로 원하는 정책을 작성하고 싶다면, 위의 예제를 이해하고 적절히 변형시켜 사용하도록 합시다.
profile
Devops Engineer

0개의 댓글