AWS
를 이용하다보면 다양한 곳에서 정책을 작성하게 됩니다. 이를 테라폼으로 작성할 때 aws_iam_policy_document
data source를 이용해서 정책을 작성하면 깔끔하게 작성할 수 있습니다.data source
인 aws_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
형식으로 어떻게 변환되는지를 보시기 바랍니다.
위의 예제에서는 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
로 원하는 정책을 작성하고 싶다면, 위의 예제를 이해하고 적절히 변형시켜 사용하도록 합시다.