diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0596e8c..95005da 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -144,6 +144,7 @@ jobs: run: | tfsec --format json --out tfsec_results.json . working-directory: ${{ matrix.dir }} + continue-on-error: true - name: Notify Slack for LOW/MEDIUM tfsec findings # LOW, Medium으로 감지된 내용을 slack 전송하고 알림 if: always() @@ -251,8 +252,11 @@ jobs: git fetch origin ${{ github.base_ref }} git checkout origin/${{ github.base_ref }} -- . terraform init -input=false + terraform plan -input=false -out=tfplan-base.binary + infracost breakdown \ --path=. \ + --terraform-plan-flags="-out=tfplan-base.binary" \ --format=json \ --out-file infracost-baseline.json @@ -260,9 +264,12 @@ jobs: working-directory: ${{ matrix.dir }} run: | git checkout ${{ github.head_ref }} + terraform init -input=false + terraform plan -input=false -out=tfplan-pr.binary infracost diff \ --path=. \ + --terraform-plan-flags="-out=tfplan-pr.binary" \ --compare-to infracost-baseline.json \ --format=json \ --out-file infracost-diff.json @@ -276,26 +283,20 @@ jobs: # 변경사항 없음 메시지 (로그용) echo "✅ No infrastructure cost changes detected." echo "Generating and posting full cost breakdown for current infrastructure." - - # 전체 비용 스냅샷 생성 - infracost breakdown \ - --path=. \ - --format=json \ - --out-file infracost-full.json - - # 전체 비용 분석 댓글 + infracost comment github \ - --path=infracost-full.json \ + --path=infracost-baseline.json \ --repo=${{ github.repository }} \ --pull-request=${{ github.event.pull_request.number }} \ --github-token=${{ secrets.GITHUB_TOKEN }} \ - --behavior=update + --behavior=update \ + --tag=infracost-comment else - # 변경사항이 있을 때는 diff 댓글 infracost comment github \ --path=infracost-diff.json \ --repo=${{ github.repository }} \ --pull-request=${{ github.event.pull_request.number }} \ --github-token=${{ secrets.GITHUB_TOKEN }} \ - --behavior=update + --behavior=update \ + --tag=infracost-comment fi diff --git a/dev-team-account/state/S3/main.tf b/dev-team-account/state/S3/main.tf index 18e9d4d..4c83a34 100644 --- a/dev-team-account/state/S3/main.tf +++ b/dev-team-account/state/S3/main.tf @@ -10,6 +10,13 @@ provider "aws" { region = "ap-northeast-2" } +# KMS 모듈 호출 +module "s3_kms" { + source = "../../../modules/S3_kms" + description = "KMS key for S3 encryption" + s3_bucket_arn = "arn:aws:s3:::cloudfence-dev-state" +} + # S3 버킷 생성 resource "aws_s3_bucket" "state_org" { bucket = "cloudfence-dev-state" @@ -51,55 +58,6 @@ resource "aws_s3_bucket_public_access_block" "state_org_block" { restrict_public_buckets = true } -data "aws_caller_identity" "current" {} - -# S3 암호화를 위한 KMS 키 -resource "aws_kms_key" "s3_key" { - description = "KMS key for S3 encryption" - enable_key_rotation = true - - # KMS 키 정책 추가 - policy = jsonencode({ - Version = "2012-10-17", - Statement = [ - - # 현재 계정에게 모든 KMS 작업 권한 부여 - { - Sid = "AllowRootAccountFullAccess", - Effect = "Allow", - Principal = { - AWS = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:root" - }, - Action = "kms:*", - Resource = "*" - }, - - # S3 서비스에게 암복호화 권한 부여 - { - Sid = "AllowS3ServicePrincipal" - Effect = "Allow" - Principal = { - Service = "s3.amazonaws.com" - } - Action = [ - "kms:Encrypt", - "kms:Decrypt", - "kms:ReEncrypt*", - "kms:GenerateDataKey*", - "kms:DescribeKey" - ] - Resource = "*" - Condition = { - StringEquals = { - "aws:SourceArn" = "arn:aws:s3:::cloudfence-dev-state", - "aws:SourceAccount" = data.aws_caller_identity.current.account_id - } - } - } - ] - }) -} - # S3 버킷 서버 측 암호화 resource "aws_s3_bucket_server_side_encryption_configuration" "encryption" { bucket = aws_s3_bucket.state_org.id @@ -107,7 +65,7 @@ resource "aws_s3_bucket_server_side_encryption_configuration" "encryption" { rule { apply_server_side_encryption_by_default { sse_algorithm = "aws:kms" - kms_master_key_id = aws_kms_key.s3_key.arn + kms_master_key_id = module.s3_kms.kms_key_arn } } } diff --git a/identity-team-account/state/S3/main.tf b/identity-team-account/state/S3/main.tf index bca05d8..990db35 100644 --- a/identity-team-account/state/S3/main.tf +++ b/identity-team-account/state/S3/main.tf @@ -10,6 +10,13 @@ provider "aws" { region = "ap-northeast-2" } +# KMS 모듈 호출 +module "s3_kms" { + source = "../../../modules/S3_kms" + description = "KMS key for S3 encryption" + s3_bucket_arn = "arn:aws:s3:::cloudfence-identity-state" +} + # S3 버킷 생성 resource "aws_s3_bucket" "state_org" { bucket = "cloudfence-identity-state" @@ -51,55 +58,6 @@ resource "aws_s3_bucket_public_access_block" "state_org_block" { restrict_public_buckets = true } -data "aws_caller_identity" "current" {} - -# S3 암호화를 위한 KMS 키 -resource "aws_kms_key" "s3_key" { - description = "KMS key for S3 encryption" - enable_key_rotation = true - - # KMS 키 정책 추가 - policy = jsonencode({ - Version = "2012-10-17", - Statement = [ - - # 현재 계정에게 모든 KMS 작업 권한 부여 - { - Sid = "AllowRootAccountFullAccess", - Effect = "Allow", - Principal = { - AWS = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:root" - }, - Action = "kms:*", - Resource = "*" - }, - - # S3 서비스에게 암복호화 권한 부여 - { - Sid = "AllowS3ServicePrincipal" - Effect = "Allow" - Principal = { - Service = "s3.amazonaws.com" - } - Action = [ - "kms:Encrypt", - "kms:Decrypt", - "kms:ReEncrypt*", - "kms:GenerateDataKey*", - "kms:DescribeKey" - ] - Resource = "*" - Condition = { - StringEquals = { - "aws:SourceArn" = "arn:aws:s3:::cloudfence-identity-state", - "aws:SourceAccount" = data.aws_caller_identity.current.account_id - } - } - } - ] - }) -} - # S3 버킷 서버 측 암호화 resource "aws_s3_bucket_server_side_encryption_configuration" "encryption" { bucket = aws_s3_bucket.state_org.id @@ -107,7 +65,7 @@ resource "aws_s3_bucket_server_side_encryption_configuration" "encryption" { rule { apply_server_side_encryption_by_default { sse_algorithm = "aws:kms" - kms_master_key_id = aws_kms_key.s3_key.arn + kms_master_key_id = module.s3_kms.kms_key_arn } } } diff --git a/management-team-account/state/S3/main.tf b/management-team-account/state/S3/main.tf index b2e4986..e41e553 100644 --- a/management-team-account/state/S3/main.tf +++ b/management-team-account/state/S3/main.tf @@ -10,6 +10,13 @@ provider "aws" { region = "ap-northeast-2" } +# KMS 모듈 호출 +module "s3_kms" { + source = "../../../modules/S3_kms" + description = "KMS key for S3 encryption" + s3_bucket_arn = "arn:aws:s3:::cloudfence-management-state" +} + # S3 버킷 생성 resource "aws_s3_bucket" "state_org" { bucket = "cloudfence-management-state" @@ -51,57 +58,6 @@ resource "aws_s3_bucket_public_access_block" "state_org_block" { restrict_public_buckets = true } - -data "aws_caller_identity" "current" {} - - -# S3 암호화를 위한 KMS 키 -resource "aws_kms_key" "s3_key" { - description = "KMS key for S3 encryption" - enable_key_rotation = true - - # KMS 키 정책 추가 - policy = jsonencode({ - Version = "2012-10-17", - Statement = [ - - # 현재 계정에게 모든 KMS 작업 권한 부여 - { - Sid = "AllowRootAccountFullAccess", - Effect = "Allow", - Principal = { - AWS = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:root" - }, - Action = "kms:*", - Resource = "*" - }, - - # S3 서비스에게 암복호화 권한 부여 - { - Sid = "AllowS3ServicePrincipal" - Effect = "Allow" - Principal = { - Service = "s3.amazonaws.com" - } - Action = [ - "kms:Encrypt", - "kms:Decrypt", - "kms:ReEncrypt*", - "kms:GenerateDataKey*", - "kms:DescribeKey" - ] - Resource = "*" - Condition = { - StringEquals = { - "aws:SourceArn" = "arn:aws:s3:::cloudfence-management-state", - "aws:SourceAccount" = data.aws_caller_identity.current.account_id - } - } - } - ] - }) -} - # S3 버킷 서버 측 암호화 resource "aws_s3_bucket_server_side_encryption_configuration" "encryption" { bucket = aws_s3_bucket.state_org.id @@ -109,7 +65,7 @@ resource "aws_s3_bucket_server_side_encryption_configuration" "encryption" { rule { apply_server_side_encryption_by_default { sse_algorithm = "aws:kms" - kms_master_key_id = aws_kms_key.s3_key.arn + kms_master_key_id = module.s3_kms.kms_key_arn } } } diff --git a/modules/S3_kms/main.tf b/modules/S3_kms/main.tf new file mode 100644 index 0000000..2f9ddf5 --- /dev/null +++ b/modules/S3_kms/main.tf @@ -0,0 +1,42 @@ +data "aws_caller_identity" "current" {} + +resource "aws_kms_key" "this" { + description = var.description + enable_key_rotation = true + + policy = jsonencode({ + Version = "2012-10-17", + Statement = [ + { + Sid = "AllowRootAccountFullAccess", + Effect = "Allow", + Principal = { + AWS = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:root" + }, + Action = "kms:*", + Resource = "*" + }, + { + Sid = "AllowS3ServicePrincipal" + Effect = "Allow" + Principal = { + Service = "s3.amazonaws.com" + } + Action = [ + "kms:Encrypt", + "kms:Decrypt", + "kms:ReEncrypt*", + "kms:GenerateDataKey*", + "kms:DescribeKey" + ] + Resource = "*" + Condition = { + StringEquals = { + "aws:SourceArn" = var.s3_bucket_arn, + "aws:SourceAccount" = data.aws_caller_identity.current.account_id + } + } + } + ] + }) +} \ No newline at end of file diff --git a/modules/S3_kms/outputs.tf b/modules/S3_kms/outputs.tf new file mode 100644 index 0000000..1411c3c --- /dev/null +++ b/modules/S3_kms/outputs.tf @@ -0,0 +1,4 @@ +output "kms_key_arn" { + description = "The ARN of the KMS key used for S3 encryption" + value = aws_kms_key.this.arn +} \ No newline at end of file diff --git a/modules/S3_kms/variables.tf b/modules/S3_kms/variables.tf new file mode 100644 index 0000000..b7db9cd --- /dev/null +++ b/modules/S3_kms/variables.tf @@ -0,0 +1,9 @@ +variable "description" { + type = string + default = "KMS key for S3 encryption" +} + +variable "s3_bucket_arn" { + type = string + description = "ARN of the S3 bucket that will use this KMS key" +} \ No newline at end of file diff --git a/operation-team-account/state/S3/main.tf b/operation-team-account/state/S3/main.tf index 9061094..d843767 100644 --- a/operation-team-account/state/S3/main.tf +++ b/operation-team-account/state/S3/main.tf @@ -10,6 +10,13 @@ provider "aws" { region = "ap-northeast-2" } +# KMS 모듈 호출 +module "s3_kms" { + source = "../../../modules/S3_kms" + description = "KMS key for S3 encryption" + s3_bucket_arn = "arn:aws:s3:::cloudfence-operation-state" +} + # S3 버킷 생성 resource "aws_s3_bucket" "state_org" { bucket = "cloudfence-operation-state" @@ -51,55 +58,6 @@ resource "aws_s3_bucket_public_access_block" "state_org_block" { restrict_public_buckets = true } -data "aws_caller_identity" "current" {} - -# S3 암호화를 위한 KMS 키 -resource "aws_kms_key" "s3_key" { - description = "KMS key for S3 encryption" - enable_key_rotation = true - - # KMS 키 정책 추가 - policy = jsonencode({ - Version = "2012-10-17", - Statement = [ - - # 현재 계정에게 모든 KMS 작업 권한 부여 - { - Sid = "AllowRootAccountFullAccess", - Effect = "Allow", - Principal = { - AWS = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:root" - }, - Action = "kms:*", - Resource = "*" - }, - - # S3 서비스에게 암복호화 권한 부여 - { - Sid = "AllowS3ServicePrincipal" - Effect = "Allow" - Principal = { - Service = "s3.amazonaws.com" - } - Action = [ - "kms:Encrypt", - "kms:Decrypt", - "kms:ReEncrypt*", - "kms:GenerateDataKey*", - "kms:DescribeKey" - ] - Resource = "*" - Condition = { - StringEquals = { - "aws:SourceArn" = "arn:aws:s3:::cloudfence-operation-state", - "aws:SourceAccount" = data.aws_caller_identity.current.account_id - } - } - } - ] - }) -} - # S3 버킷 서버 측 암호화 resource "aws_s3_bucket_server_side_encryption_configuration" "encryption" { bucket = aws_s3_bucket.state_org.id @@ -107,7 +65,7 @@ resource "aws_s3_bucket_server_side_encryption_configuration" "encryption" { rule { apply_server_side_encryption_by_default { sse_algorithm = "aws:kms" - kms_master_key_id = aws_kms_key.s3_key.arn + kms_master_key_id = module.s3_kms.kms_key_arn } } } diff --git a/prod-team-account/state/S3/main.tf b/prod-team-account/state/S3/main.tf index ee89ecf..ff6b675 100644 --- a/prod-team-account/state/S3/main.tf +++ b/prod-team-account/state/S3/main.tf @@ -10,6 +10,13 @@ provider "aws" { region = "ap-northeast-2" } +# KMS 모듈 호출 +module "s3_kms" { + source = "../../../modules/S3_kms" + description = "KMS key for S3 encryption" + s3_bucket_arn = "arn:aws:s3:::cloudfence-prod-state" +} + # S3 버킷 생성 resource "aws_s3_bucket" "state_org" { bucket = "cloudfence-prod-state" @@ -51,55 +58,6 @@ resource "aws_s3_bucket_public_access_block" "state_org_block" { restrict_public_buckets = true } -data "aws_caller_identity" "current" {} - -# S3 암호화를 위한 KMS 키 -resource "aws_kms_key" "s3_key" { - description = "KMS key for S3 encryption" - enable_key_rotation = true - - # KMS 키 정책 추가 - policy = jsonencode({ - Version = "2012-10-17", - Statement = [ - - # 현재 계정에게 모든 KMS 작업 권한 부여 - { - Sid = "AllowRootAccountFullAccess", - Effect = "Allow", - Principal = { - AWS = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:root" - }, - Action = "kms:*", - Resource = "*" - }, - - # S3 서비스에게 암복호화 권한 부여 - { - Sid = "AllowS3ServicePrincipal" - Effect = "Allow" - Principal = { - Service = "s3.amazonaws.com" - } - Action = [ - "kms:Encrypt", - "kms:Decrypt", - "kms:ReEncrypt*", - "kms:GenerateDataKey*", - "kms:DescribeKey" - ] - Resource = "*" - Condition = { - StringEquals = { - "aws:SourceArn" = "arn:aws:s3:::cloudfence-prod-state", - "aws:SourceAccount" = data.aws_caller_identity.current.account_id - } - } - } - ] - }) -} - # S3 버킷 서버 측 암호화 resource "aws_s3_bucket_server_side_encryption_configuration" "encryption" { bucket = aws_s3_bucket.state_org.id @@ -107,7 +65,7 @@ resource "aws_s3_bucket_server_side_encryption_configuration" "encryption" { rule { apply_server_side_encryption_by_default { sse_algorithm = "aws:kms" - kms_master_key_id = aws_kms_key.s3_key.arn + kms_master_key_id = module.s3_kms.kms_key_arn } } } diff --git a/security-team-account/state/S3/main.tf b/security-team-account/state/S3/main.tf index 83cf94d..e39985c 100644 --- a/security-team-account/state/S3/main.tf +++ b/security-team-account/state/S3/main.tf @@ -10,6 +10,13 @@ provider "aws" { region = "ap-northeast-2" } +# KMS 모듈 호출 +module "s3_kms" { + source = "../../../modules/S3_kms" + description = "KMS key for S3 encryption" + s3_bucket_arn = "arn:aws:s3:::cloudfence-security-state" +} + # S3 버킷 생성 resource "aws_s3_bucket" "state_org" { bucket = "cloudfence-security-state" @@ -51,55 +58,6 @@ resource "aws_s3_bucket_public_access_block" "state_org_block" { restrict_public_buckets = true } -data "aws_caller_identity" "current" {} - -# S3 암호화를 위한 KMS 키 -resource "aws_kms_key" "s3_key" { - description = "KMS key for S3 encryption" - enable_key_rotation = true - - # KMS 키 정책 추가 - policy = jsonencode({ - Version = "2012-10-17", - Statement = [ - - # 현재 계정에게 모든 KMS 작업 권한 부여 - { - Sid = "AllowRootAccountFullAccess", - Effect = "Allow", - Principal = { - AWS = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:root" - }, - Action = "kms:*", - Resource = "*" - }, - - # S3 서비스에게 암복호화 권한 부여 - { - Sid = "AllowS3ServicePrincipal" - Effect = "Allow" - Principal = { - Service = "s3.amazonaws.com" - } - Action = [ - "kms:Encrypt", - "kms:Decrypt", - "kms:ReEncrypt*", - "kms:GenerateDataKey*", - "kms:DescribeKey" - ] - Resource = "*" - Condition = { - StringEquals = { - "aws:SourceArn" = "arn:aws:s3:::cloudfence-security-state", - "aws:SourceAccount" = data.aws_caller_identity.current.account_id - } - } - } - ] - }) -} - # S3 버킷 서버 측 암호화 resource "aws_s3_bucket_server_side_encryption_configuration" "encryption" { bucket = aws_s3_bucket.state_org.id @@ -107,7 +65,7 @@ resource "aws_s3_bucket_server_side_encryption_configuration" "encryption" { rule { apply_server_side_encryption_by_default { sse_algorithm = "aws:kms" - kms_master_key_id = aws_kms_key.s3_key.arn + kms_master_key_id = module.s3_kms.kms_key_arn } } } diff --git a/stage-team-account/state/S3/main.tf b/stage-team-account/state/S3/main.tf index 9181e6f..8551691 100644 --- a/stage-team-account/state/S3/main.tf +++ b/stage-team-account/state/S3/main.tf @@ -10,6 +10,13 @@ provider "aws" { region = "ap-northeast-2" } +# KMS 모듈 호출 +module "s3_kms" { + source = "../../../modules/S3_kms" + description = "KMS key for S3 encryption" + s3_bucket_arn = "arn:aws:s3:::cloudfence-stage-state" +} + # S3 버킷 생성 resource "aws_s3_bucket" "state_org" { bucket = "cloudfence-stage-state" @@ -51,55 +58,6 @@ resource "aws_s3_bucket_public_access_block" "state_org_block" { restrict_public_buckets = true } -data "aws_caller_identity" "current" {} - -# S3 암호화를 위한 KMS 키 -resource "aws_kms_key" "s3_key" { - description = "KMS key for S3 encryption" - enable_key_rotation = true - - # KMS 키 정책 추가 - policy = jsonencode({ - Version = "2012-10-17", - Statement = [ - - # 현재 계정에게 모든 KMS 작업 권한 부여 - { - Sid = "AllowRootAccountFullAccess", - Effect = "Allow", - Principal = { - AWS = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:root" - }, - Action = "kms:*", - Resource = "*" - }, - - # S3 서비스에게 암복호화 권한 부여 - { - Sid = "AllowS3ServicePrincipal" - Effect = "Allow" - Principal = { - Service = "s3.amazonaws.com" - } - Action = [ - "kms:Encrypt", - "kms:Decrypt", - "kms:ReEncrypt*", - "kms:GenerateDataKey*", - "kms:DescribeKey" - ] - Resource = "*" - Condition = { - StringEquals = { - "aws:SourceArn" = "arn:aws:s3:::cloudfence-stage-state", - "aws:SourceAccount" = data.aws_caller_identity.current.account_id - } - } - } - ] - }) -} - # S3 버킷 서버 측 암호화 resource "aws_s3_bucket_server_side_encryption_configuration" "encryption" { bucket = aws_s3_bucket.state_org.id @@ -107,7 +65,7 @@ resource "aws_s3_bucket_server_side_encryption_configuration" "encryption" { rule { apply_server_side_encryption_by_default { sse_algorithm = "aws:kms" - kms_master_key_id = aws_kms_key.s3_key.arn + kms_master_key_id = module.s3_kms.kms_key_arn } } }