Terraform ์ผ๋ก AWS Backend(S3 + DynamoDB)๋ฅผ ๊ตฌ์ฑํ ๋, ๋ฌด์ฌ์ฝ AmazonS3FullAccess ๊ฐ์ managed policy ๋ฅผ ๋ถ์ด๋ ๊ฒฝ์ฐ๊ฐ ๋ง๋ค. ํ์ง๋ง ์ด๋ PoLP(์ต์ ๊ถํ ์์น) ์ ์๋ฐฐ๋๋ค. ์ค์ ํ์ํ ๊ถํ๋ง ์์๋ด ์ ํํ ๋ถ์ฌํ๋ ๊ฒ ๋ณด์์ ์ ์ ํ๋ค.
์ด ๊ธ์์ Terraform apply ๋ก๊ทธ๋ฅผ ๋ถ์ํด ์ด๋ค API๊ฐ ํธ์ถ๋๋์ง ์ถ์ถํ๊ณ , ๊ทธ๊ฑธ ๋ฐํ์ผ๋ก ์ ์ ๋ IAM Policy ๋ฅผ ๊ตฌ์ฑํ ๊ณผ์ ์ ๊ณต์ ํ๋ค.
Terraform Debug log ๋ก API ์ฌ์ฉ ๋ด์ญ ์ถ์ถํ๊ธฐ
๋จผ์ ๋๋ฒ๊ทธ ๋ก๊ทธ๋ฅผ ์ผ์, Terraform apply ์คํ ์, ์ด๋ค AWS API ๊ฐ ํธ์ถ๋๋์ง ๊ธฐ๋กํ๋ค.
$ export TF_LOG=DEBUG
$ export TF_LOG_PATH=./terraform.log
$ terraform apply
๊ทธ ํ, log ์์ S3 ์ DynamoDB ๊ด๋ จ AWS API ํธ์ถ ์ ๋ณด๋ฅผ ์ถ์ถํ๋ค.
$ cat terraform.log | grep -E 'rpc.service=(S3|DynamoDB)' | awk '{
for(i=1; i<=NF; i++) {
if($i ~ /^rpc.service=/) service = $i;
if($i ~ /^rpc.method=/) method = $i;
}
if(service && method) print service ":" method;
}' | sed -E 's/rpc.service=([^:]*):rpc.method=([^:]*)$/\1:\2/' | sort | uniq -c
2 DynamoDB:CreateTable
2 DynamoDB:DescribeContinuousBackups
12 DynamoDB:DescribeTable
2 DynamoDB:DescribeTimeToLive
1 DynamoDB:GetBucketTagging
2 DynamoDB:ListTagsOfResource
1 DynamoDB:PutBucketLifecycleConfiguration
2 S3:CreateBucket
2 S3:GetBucketAccelerateConfiguration
2 S3:GetBucketAcl
3 S3:GetBucketCors
2 S3:GetBucketEncryption
32 S3:GetBucketLifecycleConfiguration
2 S3:GetBucketLogging
3 S3:GetBucketPolicy
3 S3:GetBucketReplication
2 S3:GetBucketRequestPayment
4 S3:GetBucketTagging
2 S3:GetBucketVersioning
3 S3:GetBucketWebsite
3 S3:GetObjectLockConfiguration
6 S3:HeadBucket
1 S3:PutBucketLifecycleConfiguration
์ถ๋ ฅ๋ ๊ฒฐ๊ณผ์๋ ์ค์ ๋ก ์กด์ฌํ์ง ์๋ ์ก์ (e.g. DynamoDB:GetBucketTagging ๋ฑ) ์ด ํฌํจ๋๊ฑฐ๋, ๋ก๊ทธ์ ๋ํ๋ ๋ฉ์๋ ์ด๋ฆ๊ณผ IAM Policy ์ Action ์ด๋ฆ๊ณผ ์ผ์นํ์ง ์๋ ๊ฒ์ด ์๋ค. ์ด๋ฐ ๋ถ๋ถ์ GPT์ ๋์์ ๋ฐ์ ์ค์ ํ์ํ ์ก์ ์ผ๋ก ์ ํํ ์ ๋ฆฌํ๋ค.
์ค์ ํ์ํ IAM Policy ๋ชฉ๋ก (์ ์ ํ)
๋ค์์ ์ต์ข ์ ์ผ๋ก ๊ตฌ์ฑํ PoLP ๊ธฐ๋ฐ IAM Policy ์ด๋ค. ์ค์ง์ ์ผ๋ก ํธ์ถ๋๋ ์ก์ ๋ง ํฌํจํ๊ณ , ๋ฆฌ์์ค๋ ๊ตฌ์ฒด์ ์ผ๋ก ์ง์ ํ๋ค.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:CreateBucket",
"s3:ListBucket",
"s3:GetBucketLocation",
"s3:GetBucketAcl",
"s3:GetBucketVersioning",
"s3:GetBucketPolicy",
"s3:GetBucketRequestPayment",
"s3:GetBucketLogging",
"s3:GetEncryptionConfiguration",
"s3:GetLifecycleConfiguration",
"s3:GetBucketObjectLockConfiguration",
"s3:PutLifecycleConfiguration",
"s3:GetBucketTagging",
"s3:GetReplicationConfiguration",
"s3:GetAccelerateConfiguration",
"s3:GetBucketCORS",
"s3:GetBucketWebsite"
],
"Resource": [
"arn:aws:s3:::<BUCKET_NAME>",
"arn:aws:s3:::<BUCKET_NAME>/*"
]
},
{
"Effect": "Allow",
"Action": [
"dynamodb:CreateTable",
"dynamodb:DescribeTable",
"dynamodb:DescribeContinuousBackups",
"dynamodb:DescribeTimeToLive",
"dynamodb:ListTagsOfResource"
],
"Resource": "arn:aws:dynamodb:ap-northeast-1:XXX:table/<TABLE_NAME>"
},
{
"Effect": "Allow",
"Action": "sts:GetCallerIdentity",
"Resource": "*"
}
]
}
์ ๋ฆฌ
- Terraform Debug log ๋ฅผ ๋ถ์ํ๋ฉด ์ค์ ํธ์ถ๋๋ AWS API ์ ๋ณด๋ฅผ ์ถ์ถํ ์ ์๋ค.
- ์ด๋ฅผ IAM Policy (Action) ์ผ๋ก ๋งคํํ๋ฉด ์ ํํ๊ณ ์ต์ํ์ ์ ์ฑ ์ ๊ตฌ์ฑํ ์ ์๋ค.
- "์ ๋ชจ๋ฅด๋ฉด FullAccess" ์ ๊ฐ์ ๊ณผ๋ํ ์ ์ฑ ์ ํผํ๊ณ , "์ค์ ํ์ํ ๊ถํ"๋ง ์ ํํ ์ค์ ํ๋ ๊ฒ์ด ์ข๋ค.
- ๋ก๊ทธ๋ฅผ ๋จผ์ ํ์ธํ๋ฉด PoLP (์ต์ ๊ถํ ์์น) ๋ฅผ ์ ์ฉํ๋ ๋ฐ ํจ์ฌ ์์ํ๋ค.
'๐ง๐ปโ๐ป Develop > DevOps' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| ์ฌ๋ด ํด ํ๋ก์ ํธ์ CI ๋์ ํ๊ธฐ (2) | 2022.09.10 |
|---|
๋๊ธ