diff --git a/.github/workflows/pre-commit.yaml b/.github/workflows/pre-commit.yaml
index 398767c..daf3160 100644
--- a/.github/workflows/pre-commit.yaml
+++ b/.github/workflows/pre-commit.yaml
@@ -3,6 +3,7 @@ name: pre-commit-check
on:
push:
branches:
+ - main
- master
- prod
- develop
diff --git a/.github/workflows/pullRequest.yaml b/.github/workflows/pullRequest.yaml
index 8f1eba5..101b621 100644
--- a/.github/workflows/pullRequest.yaml
+++ b/.github/workflows/pullRequest.yaml
@@ -24,7 +24,7 @@ jobs:
terraform_tflint_deep,
no-commit-to-branch,
terraform_tflint_nocreds,
- terraform_tfsec
+ terraform_trivy
tflint:
runs-on: ubuntu-latest
steps:
@@ -41,7 +41,7 @@ jobs:
filter_mode: added
flags: --module
level: error
- tfsec:
+ trivy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
diff --git a/.github/workflows/tfsec.yaml b/.github/workflows/tfsec.yaml
deleted file mode 100644
index 2f75a3e..0000000
--- a/.github/workflows/tfsec.yaml
+++ /dev/null
@@ -1,26 +0,0 @@
----
-name: tfsec
-on:
- push:
- branches:
- - main
- - master
- - prod
- - develop
-
-jobs:
- tfsec:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v2
- - name: Install prerequisites
- run: ./bin/install-ubuntu.sh
- - name: Terraform init
- run: terraform init --backend=false
- - name: tfsec
- uses: reviewdog/action-tfsec@master
- with:
- github_token: ${{ secrets.GITHUB_TOKEN }}
- reporter: github-check
- filter_mode: nofilter
- level: error
diff --git a/.github/workflows/trivy.yaml b/.github/workflows/trivy.yaml
new file mode 100644
index 0000000..53a9d16
--- /dev/null
+++ b/.github/workflows/trivy.yaml
@@ -0,0 +1,31 @@
+---
+name: trivy
+on:
+ push:
+ branches:
+ - master
+
+jobs:
+ trivy:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - name: Install prerequisites
+ run: ./bin/install-ubuntu.sh
+ - name: Terraform init
+ run: terraform init --backend=false
+ - name: Trivy scan
+ uses: aquasecurity/trivy-action@master
+ with:
+ scan-type: 'config'
+ hide-progress: false
+ format: 'sarif'
+ output: 'trivy-results.sarif'
+ exit-code: '1'
+ ignore-unfixed: true
+ severity: 'CRITICAL,HIGH'
+
+ - name: Upload Trivy scan results to GitHub Security tab
+ uses: github/codeql-action/upload-sarif@v2
+ with:
+ sarif_file: 'trivy-results.sarif'
diff --git a/.gitignore b/.gitignore
index 1fef4ab..371d818 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,3 +7,9 @@
# .tfvars files
*.tfvars
+
+# macs
+.DS_Store
+
+# temp folders
+tmp
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 8273282..f209b71 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -1,63 +1,27 @@
exclude: ".terraform"
repos:
- repo: https://github.com/antonbabenko/pre-commit-terraform
- rev: v1.77.1
+ rev: v1.92.2
hooks:
- id: terraform_docs
always_run: true
- id: terraform_fmt
+ - id: terraform_validate
+ args:
+ - --hook-config=--retry-once-with-cleanup=true
+ exclude: ^examples
- id: terraform_tflint
alias: terraform_tflint_nocreds
+ exclude: ^examples
name: terraform_tflint_nocreds
- - id: terraform_tfsec
- - repo: local
- hooks:
- - id: terraform_validate
- name: terraform_validate
- entry: |
- bash -c '
- AWS_DEFAULT_REGION=us-east-1
- declare -a DIRS
- for FILE in "$@"
- do
- DIRS+=($(dirname "$FILE"))
- done
- for DIR in $(printf "%s\n" "${DIRS[@]}" | sort -u)
- do
- cd $(dirname "$FILE")
- terraform init --backend=false
- terraform validate .
- cd ..
- done
- '
- language: system
- verbose: true
- files: \.tf(vars)?$
- exclude: examples
- - id: tflock
- name: provider_locks
- entry: |
- bash -c '
- AWS_DEFAULT_REGION=us-east-1
- declare -a DIRS
- for FILE in "$@"
- do
- DIRS+=($(dirname "$FILE"))
- done
- for DIR in $(printf "%s\n" "${DIRS[@]}" | sort -u)
- do
- cd $(dirname "$FILE")
- terraform providers lock -platform=windows_amd64 -platform=darwin_amd64 -platform=linux_amd64
- cd ..
- done
- '
- language: system
- verbose: true
- files: \.tf(vars)?$
- exclude: examples
+ - id: terraform_trivy
+ args:
+ - --args=--skip-dirs="**/.terraform,examples/*"
+ - id: terraform_providers_lock
- repo: https://github.com/pre-commit/pre-commit-hooks
- rev: v4.4.0
+ rev: v4.6.0
hooks:
+ - id: check-added-large-files
- id: check-case-conflict
- id: check-json
- id: check-merge-conflict
@@ -65,6 +29,7 @@ repos:
- id: check-yaml
args:
- --unsafe
+ - id: detect-private-key
- id: end-of-file-fixer
- id: mixed-line-ending
args:
@@ -86,4 +51,4 @@ repos:
- --markdown-linebreak-ext=md
exclude: README.md
ci:
- skip: [terraform_docs, terraform_fmt, terraform_tflint, terraform_tfsec, tflock]
+ skip: [terraform_docs, terraform_fmt, terraform_validate, terraform_tflint, terraform_trivy, terraform_providers_lock]
diff --git a/.terraform-version b/.terraform-version
index 4f20ea7..5a13b33 100644
--- a/.terraform-version
+++ b/.terraform-version
@@ -1 +1 @@
-latest:^1.1
+latest:^1.6
diff --git a/.terraform.lock.hcl b/.terraform.lock.hcl
index f9f245d..f0469ad 100644
--- a/.terraform.lock.hcl
+++ b/.terraform.lock.hcl
@@ -2,26 +2,24 @@
# Manual edits may be lost in future updates.
provider "registry.terraform.io/hashicorp/aws" {
- version = "4.56.0"
- constraints = ">= 3.8.0"
+ version = "5.66.0"
+ constraints = ">= 5.0.0"
hashes = [
- "h1:1I44mXVvhYDRFehbw9MFq2xKxlDoEFBz7Ou8HLaNtXk=",
- "h1:CnpBvf3mH16Kcez47OsjmIeGkY2PUVihKRwbkyOvo48=",
- "h1:koDunHl/LUmCAKy3VFie6MakXN7ng93v8HBRpKI8He8=",
- "zh:1d2b7693a102da015a86b9235b554272b9280597011216c3ddd1a6dc95ad8dab",
- "zh:28c3e8ebaa077f65c4ac5fd051c95887070293fcff0386dfc2e4b7e248a0aefa",
- "zh:2a620bc4a87be06e7acac1bc15e966dba45df643bf6c3efb811e74e6c2122b03",
- "zh:30d3ac148fa0634e7ba1de66e1af1328481c92cd774adcfc0e27f828103b17e0",
- "zh:3d3eebf916f25e11b12dd3c692f8fe1e4c4e9a0c414af9d0d881ddebd28dcd39",
- "zh:3f4600f2881c02fcc69080df68747c9a0b9b11cb002117fd918b7800f2ac402b",
- "zh:7156fb12c3b4f2964f7e78cee97f31d95b43045467f90749d2ed545725c36baa",
+ "h1:yGcVdhj9IKbS/b7BSHtgGjCiFnKK+81ImkK/x7UCgEI=",
+ "zh:071c908eb18627f4becdaf0a9fe95d7a61f69be365080aba2ef5e24f6314392b",
+ "zh:3dea2a474c6ad4be5b508de4e90064ec485e3fbcebb264cb6c4dec660e3ea8b5",
+ "zh:56c0b81e3bbf4e9ccb2efb984f8758e2bc563ce179ff3aecc1145df268b046d1",
+ "zh:5f34b75a9ef69cad8c79115ecc0697427d7f673143b81a28c3cf8d5decfd7f93",
+ "zh:65632bc2c408775ee44cb32a72e7c48376001a9a7b3adbc2c9b4d088a7d58650",
+ "zh:6d0550459941dfb39582fadd20bfad8816255a827bfaafb932d51d66030fcdd5",
+ "zh:7f1811ef179e507fdcc9776eb8dc3d650339f8b84dd084642cf7314c5ca26745",
+ "zh:8a793d816d7ef57e71758fe95bf830cfca70d121df70778b65cc11065ad004fd",
+ "zh:8c7cda08adba01b5ae8cc4e5fbf16761451f0fab01327e5f44fc47b7248ba653",
+ "zh:96d855f1771342771855c0fb2d47ff6a731e8f2fa5d242b18037c751fd63e6c3",
"zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425",
- "zh:a5bbc84fd37d468c7b016009776b6d2a287bbb746af81aba786cdf8eb5fce4a1",
- "zh:d5322bcd4e11caddbbfaa1198893824d4b4d28f504517a3a87902cf86d75bd87",
- "zh:d766eb9f86a40060d63e12ef674d7c9c47ec4e47ade487f1f49af8c89b441711",
- "zh:df23f592b99f6617f09e449009bbb49068a69fc926b15ca29e30b068c9c67365",
- "zh:e7b0acee2d98549731547259b539f598e18db07c0c202d3a34b922beff711054",
- "zh:ec317f79fdcce934c39458ea312862e7f7ec48cafb8bcc9b5a00d9b78b629d81",
- "zh:f78ec7a771867d96dfee96bf74523341ba42feeb64ce2f108b5bf2e7ebef0fef",
+ "zh:b2a62669b72c2471820410b58d764102b11c24e326831ddcfae85c7d20795acf",
+ "zh:b4a6b251ac24c8f5522581f8d55238d249d0008d36f64475beefc3791f229e1d",
+ "zh:ca519fa7ee1cac30439c7e2d311a0ecea6a5dae2d175fe8440f30133688b6272",
+ "zh:fbcd54e7d65806b0038fc8a0fbdc717e1284298ff66e22aac39dcc5a22cc99e5",
]
}
diff --git a/.tflint.hcl b/.tflint.hcl
index 854fb92..c700b79 100644
--- a/.tflint.hcl
+++ b/.tflint.hcl
@@ -2,6 +2,12 @@ config {
module = true
}
+plugin "aws" {
+ enabled = true
+ version = "0.30.0"
+ source = "github.com/terraform-linters/tflint-ruleset-aws"
+}
+
rule "terraform_deprecated_interpolation" {
enabled = true
}
diff --git a/LICENSE b/LICENSE
index c026f1a..9f1b0ba 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2023 Rhythmic Technologies, Inc.
+Copyright (c) 2024 Rhythmic Technologies, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/README.md b/README.md
index a232bd5..f27bd21 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,12 @@
# terraform-aws-config
-[![](https://github.com/rhythmictech/terraform-aws-config/workflows/check/badge.svg)](https://github.com/rhythmictech/terraform-aws-config/actions)
+[![tflint](https://github.com/rhythmictech/terraform-aws-config/workflows/tflint/badge.svg?branch=master&event=push)](https://github.com/rhythmictech/terraform-aws-config/actions?query=workflow%3Atflint+event%3Apush+branch%3Amaster)
+[![trivy](https://github.com/rhythmictech/terraform-aws-config/workflows/trivy/badge.svg?branch=master&event=push)](https://github.com/rhythmictech/terraform-aws-config/actions?query=workflow%3Atrivy+event%3Apush+branch%3Amaster)
+[![yamllint](https://github.com/rhythmictech/terraform-aws-config/workflows/yamllint/badge.svg?branch=master&event=push)](https://github.com/rhythmictech/terraform-aws-config/actions?query=workflow%3Ayamllint+event%3Apush+branch%3Amaster)
+[![misspell](https://github.com/rhythmictech/terraform-aws-config/workflows/misspell/badge.svg?branch=master&event=push)](https://github.com/rhythmictech/terraform-aws-config/actions?query=workflow%3Amisspell+event%3Apush+branch%3Amaster)
+[![pre-commit-check](https://github.com/rhythmictech/terraform-aws-config/workflows/pre-commit-check/badge.svg?branch=master&event=push)](https://github.com/rhythmictech/terraform-aws-config/actions?query=workflow%3Apre-commit-check+event%3Apush+branch%3Amaster)
+
+
@@ -8,14 +14,14 @@
| Name | Version |
|------|---------|
-| [terraform](#requirement\_terraform) | >= 0.13.4 |
-| [aws](#requirement\_aws) | >= 3.8 |
+| [terraform](#requirement\_terraform) | >= 1.1 |
+| [aws](#requirement\_aws) | >= 5.0 |
## Providers
| Name | Version |
|------|---------|
-| [aws](#provider\_aws) | 4.56.0 |
+| [aws](#provider\_aws) | 5.66.0 |
## Modules
@@ -33,7 +39,11 @@ No modules.
| [aws_iam_role_policy_attachment.awsconfig_managed_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_iam_role_policy_attachment.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_s3_bucket.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket) | resource |
+| [aws_s3_bucket_logging.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_logging) | resource |
| [aws_s3_bucket_public_access_block.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_public_access_block) | resource |
+| [aws_s3_bucket_server_side_encryption_configuration.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_server_side_encryption_configuration) | resource |
+| [aws_s3_bucket_versioning.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_versioning) | resource |
+| [aws_sns_topic.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sns_topic) | resource |
| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source |
| [aws_iam_policy_document.assume](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
@@ -46,16 +56,35 @@ No modules.
|------|-------------|------|---------|:--------:|
| [bucket\_name](#input\_bucket\_name) | Name of the S3 bucket to record to (do not use with multi-region module) | `string` | `null` | no |
| [bucket\_suffix](#input\_bucket\_suffix) | Suffix to append to S3 bucket name | `string` | `"awsconfig"` | no |
+| [create\_sns\_topic](#input\_create\_sns\_topic) | Whether to create an SNS topic | `bool` | `false` | no |
| [delivery\_channel\_name](#input\_delivery\_channel\_name) | Name of the delivery channel | `string` | `"awsconfig-s3"` | no |
-| [enable\_global\_logging](#input\_enable\_global\_logging) | Enable recording of global events (E.g., IAM) | `bool` | `true` | no |
+| [grant\_s3\_kms\_access](#input\_grant\_s3\_kms\_access) | Whether to grant the IAM role access to the S3 bucket KMS key | `bool` | `true` | no |
+| [grant\_sns\_kms\_access](#input\_grant\_sns\_kms\_access) | Whether to grant the IAM role access to the SNS topic KMS key | `bool` | `true` | no |
| [logging\_bucket](#input\_logging\_bucket) | Optional target for S3 access logging | `string` | `null` | no |
| [logging\_prefix](#input\_logging\_prefix) | Optional target prefix for S3 access logging (only used if `s3_access_logging_bucket` is set) | `string` | `null` | no |
| [recorder\_name](#input\_recorder\_name) | Name of the config recorder | `string` | `"awsconfig"` | no |
-| [snapshot\_delivery\_frequency](#input\_snapshot\_delivery\_frequency) | Deliery frequency: One\_Hour, Three\_Hours, Six\_Hours, Twelve\_Hours, TwentyFour\_Hours | `string` | `"Six_Hours"` | no |
+| [recording\_group\_all\_supported](#input\_recording\_group\_all\_supported) | Specifies whether AWS Config records configuration changes for every supported type of regional resource. If set to 'false', you must specify resource types in 'recording\_group\_resource\_types'. | `bool` | `true` | no |
+| [recording\_group\_exclusion\_resource\_types](#input\_recording\_group\_exclusion\_resource\_types) | A list of resource types to exclude from recording. Only valid when 'recording\_group\_all\_supported' is true. | `list(string)` | `[]` | no |
+| [recording\_group\_include\_global\_resource\_types](#input\_recording\_group\_include\_global\_resource\_types) | Specifies whether AWS Config includes all supported types of global resources with the resources that it records. Only valid when 'recording\_group\_all\_supported' is true. | `bool` | `true` | no |
+| [recording\_group\_recording\_strategy\_use\_only](#input\_recording\_group\_recording\_strategy\_use\_only) | Specifies whether AWS Config limits recording to the resource types specified in 'recording\_group\_resource\_types'. Valid values: 'ALL\_SUPPORTED\_RESOURCE\_TYPES' or 'INCLUSION\_BY\_RESOURCE\_TYPES'. | `string` | `null` | no |
+| [recording\_group\_resource\_types](#input\_recording\_group\_resource\_types) | A list of valid AWS resource types to include in this recording group. Only used if 'recording\_group\_all\_supported' is false. | `list(string)` | `[]` | no |
+| [recording\_mode\_override\_description](#input\_recording\_mode\_override\_description) | A description for the recording mode override. | `string` | `null` | no |
+| [recording\_mode\_override\_enabled](#input\_recording\_mode\_override\_enabled) | Specifies whether to enable recording mode override. | `bool` | `false` | no |
+| [recording\_mode\_override\_recording\_frequency](#input\_recording\_mode\_override\_recording\_frequency) | The frequency for the recording mode override. Valid values: CONTINUOUS, PERIODIC\_1\_HOUR, PERIODIC\_3\_HOURS, PERIODIC\_6\_HOURS, PERIODIC\_12\_HOURS, PERIODIC\_24\_HOURS | `string` | `"CONTINUOUS"` | no |
+| [recording\_mode\_override\_resource\_types](#input\_recording\_mode\_override\_resource\_types) | A list of resource types to be recorded at the frequency specified in recording\_mode\_override\_recording\_frequency. | `list(string)` | `[]` | no |
+| [recording\_mode\_recording\_frequency](#input\_recording\_mode\_recording\_frequency) | The frequency with which AWS Config records configuration changes. Valid values: CONTINUOUS, PERIODIC\_1\_HOUR, PERIODIC\_3\_HOURS, PERIODIC\_6\_HOURS, PERIODIC\_12\_HOURS, PERIODIC\_24\_HOURS | `string` | `"CONTINUOUS"` | no |
+| [s3\_bucket\_kms\_key\_id](#input\_s3\_bucket\_kms\_key\_id) | The ARN of the KMS key to use for encrypting the S3 bucket. If not provided, AES256 encryption will be used. | `string` | `null` | no |
+| [s3\_key\_prefix](#input\_s3\_key\_prefix) | The prefix for the specified S3 bucket. | `string` | `null` | no |
+| [snapshot\_delivery\_frequency](#input\_snapshot\_delivery\_frequency) | Delivery frequency. Valid values: One\_Hour, Three\_Hours, Six\_Hours, Twelve\_Hours, TwentyFour\_Hours | `string` | `"Six_Hours"` | no |
| [sns\_topic\_arn](#input\_sns\_topic\_arn) | SNS topic to deliver config rule notifications to | `string` | `null` | no |
+| [sns\_topic\_kms\_key\_id](#input\_sns\_topic\_kms\_key\_id) | The ARN of the KMS key to use for encrypting the SNS topic. If not provided, the default AWS managed key for SNS will be used. | `string` | `null` | no |
| [tags](#input\_tags) | Tags to add to resources that support it | `map(string)` | `{}` | no |
## Outputs
No outputs.
+
+## Additional Information
+
+The SNS topic created by this module (when `sns_topic_arn` is not provided) will have a name prefix based on the `recorder_name` variable, followed by "-config-topic-". AWS will append a unique suffix to this prefix to ensure uniqueness.
diff --git a/bin/install-macos.sh b/bin/install-macos.sh
index 3800165..349bb9d 100755
--- a/bin/install-macos.sh
+++ b/bin/install-macos.sh
@@ -2,9 +2,8 @@
echo 'installing brew packages'
brew update
-brew tap liamg/tfsec
-brew install tfenv tflint terraform-docs pre-commit liamg/tfsec/tfsec coreutils
-brew upgrade tfenv tflint terraform-docs pre-commit liamg/tfsec/tfsec coreutils
+brew install tfenv tflint terraform-docs aquasecurity/trivy/trivy pre-commit coreutils
+brew upgrade tfenv tflint terraform-docs aquasecurity/trivy/trivy pre-commit coreutils
echo 'installing pre-commit hooks'
pre-commit install
diff --git a/bin/install-ubuntu.sh b/bin/install-ubuntu.sh
index 670d0b9..331e45b 100755
--- a/bin/install-ubuntu.sh
+++ b/bin/install-ubuntu.sh
@@ -7,7 +7,7 @@ pip3 install pre-commit
# terraform docs
mkdir tmp
cd tmp
-curl -Lo ./terraform-docs.tar.gz https://github.com/terraform-docs/terraform-docs/releases/download/v0.16.0/terraform-docs-v0.16.0-$(uname)-amd64.tar.gz
+curl -Lo ./terraform-docs.tar.gz https://github.com/terraform-docs/terraform-docs/releases/download/v0.18.0/terraform-docs-v0.18.0-$(uname)-amd64.tar.gz
tar -xzf terraform-docs.tar.gz
chmod +x terraform-docs
sudo mv terraform-docs /usr/bin/
@@ -30,3 +30,6 @@ pre-commit init-templatedir ~/.git-template
echo 'installing terraform with tfenv'
tfenv install
+
+wget https://github.com/aquasecurity/trivy/releases/download/v0.54.1/trivy_0.54.1_Linux-64bit.deb
+sudo dpkg -i trivy_0.54.1_Linux-64bit.deb
diff --git a/iam.tf b/iam.tf
index 0caf81f..c7c8a51 100644
--- a/iam.tf
+++ b/iam.tf
@@ -1,4 +1,3 @@
-
#tfsec:ignore:aws-iam-no-policy-wildcards
data "aws_iam_policy_document" "this" {
statement {
@@ -20,6 +19,36 @@ data "aws_iam_policy_document" "this" {
aws_s3_bucket.this.arn,
]
}
+
+ # Conditional SNS topic permissions
+ dynamic "statement" {
+ for_each = var.sns_topic_arn != null || var.create_sns_topic ? [1] : []
+ content {
+ effect = "Allow"
+ actions = ["sns:Publish"]
+ resources = [var.sns_topic_arn != null ? var.sns_topic_arn : aws_sns_topic.this[0].arn]
+ }
+ }
+
+ # Conditional KMS permissions for S3
+ dynamic "statement" {
+ for_each = var.grant_s3_kms_access && var.s3_bucket_kms_key_id != null ? [1] : []
+ content {
+ effect = "Allow"
+ actions = ["kms:Encrypt", "kms:Decrypt", "kms:ReEncrypt*", "kms:GenerateDataKey*", "kms:DescribeKey"]
+ resources = [var.s3_bucket_kms_key_id]
+ }
+ }
+
+ # Conditional KMS permissions for SNS
+ dynamic "statement" {
+ for_each = var.grant_sns_kms_access && var.sns_topic_kms_key_id != null ? [1] : []
+ content {
+ effect = "Allow"
+ actions = ["kms:Encrypt", "kms:Decrypt", "kms:ReEncrypt*", "kms:GenerateDataKey*", "kms:DescribeKey"]
+ resources = [var.sns_topic_kms_key_id]
+ }
+ }
}
resource "aws_iam_policy" "this" {
diff --git a/main.tf b/main.tf
index b2e6e61..1c59dac 100644
--- a/main.tf
+++ b/main.tf
@@ -12,40 +12,37 @@ locals {
bucket_name = var.bucket_name == null ? "${local.account_id}-${local.region}-${var.bucket_suffix}" : var.bucket_name
partition = data.aws_partition.current.partition
region = data.aws_region.current.name
-
- logging = var.logging_bucket == null ? [] : [{
- bucket = var.logging_bucket
- prefix = var.logging_prefix == null ? local.bucket_name : var.logging_prefix
- }]
}
-#tfsec:ignore:aws-s3-encryption-customer-key tfsec:ignore:aws-s3-enable-bucket-logging
+#trivy:ignore:AVD-AWS-0089
resource "aws_s3_bucket" "this" {
bucket = local.bucket_name
- acl = "private"
- tags = merge(var.tags, {
+ tags = merge(var.tags, {
"Name" = local.bucket_name
})
+}
- versioning {
- enabled = true
+resource "aws_s3_bucket_versioning" "this" {
+ bucket = aws_s3_bucket.this.id
+ versioning_configuration {
+ status = "Enabled"
}
+}
- dynamic "logging" {
- iterator = log
- for_each = local.logging
+resource "aws_s3_bucket_logging" "this" {
+ count = var.logging_bucket != null ? 1 : 0
+ bucket = aws_s3_bucket.this.id
+ target_bucket = var.logging_bucket
+ target_prefix = var.logging_prefix == null ? local.bucket_name : var.logging_prefix
+}
- content {
- target_bucket = log.value.bucket
- target_prefix = lookup(log.value, "prefix", null)
- }
- }
+resource "aws_s3_bucket_server_side_encryption_configuration" "this" {
+ bucket = aws_s3_bucket.this.id
- server_side_encryption_configuration {
- rule {
- apply_server_side_encryption_by_default {
- sse_algorithm = "aws:kms"
- }
+ rule {
+ apply_server_side_encryption_by_default {
+ sse_algorithm = var.s3_bucket_kms_key_id != null ? "aws:kms" : "AES256"
+ kms_master_key_id = var.s3_bucket_kms_key_id
}
}
}
@@ -63,20 +60,50 @@ resource "aws_config_configuration_recorder" "this" {
role_arn = aws_iam_role.this.arn
recording_group {
- all_supported = true
- include_global_resource_types = var.enable_global_logging
+ all_supported = var.recording_group_all_supported
+ include_global_resource_types = var.recording_group_include_global_resource_types
+ resource_types = var.recording_group_resource_types
+ exclusion_by_resource_types {
+ resource_types = var.recording_group_exclusion_resource_types
+ }
+ recording_strategy {
+ use_only = var.recording_group_recording_strategy_use_only
+ }
+ }
+
+ recording_mode {
+ recording_frequency = var.recording_mode_recording_frequency
+
+ dynamic "recording_mode_override" {
+ for_each = var.recording_mode_override_enabled ? [1] : []
+ content {
+ description = var.recording_mode_override_description
+ resource_types = var.recording_mode_override_resource_types
+ recording_frequency = var.recording_mode_override_recording_frequency
+ }
+ }
}
}
+resource "aws_sns_topic" "this" {
+ count = var.create_sns_topic ? 1 : 0
+ name_prefix = "${var.recorder_name}-config-topic-"
+
+ kms_master_key_id = var.sns_topic_kms_key_id
+}
+
resource "aws_config_delivery_channel" "this" {
name = var.delivery_channel_name
s3_bucket_name = aws_s3_bucket.this.bucket
- sns_topic_arn = var.sns_topic_arn
+ s3_key_prefix = var.s3_key_prefix
+ sns_topic_arn = var.create_sns_topic ? aws_sns_topic.this[0].arn : var.sns_topic_arn
snapshot_delivery_properties {
delivery_frequency = var.snapshot_delivery_frequency
}
+ s3_kms_key_arn = var.s3_bucket_kms_key_id
+
depends_on = [aws_config_configuration_recorder.this]
}
diff --git a/variables.tf b/variables.tf
index b3df5f2..612d353 100644
--- a/variables.tf
+++ b/variables.tf
@@ -20,12 +20,6 @@ variable "delivery_channel_name" {
type = string
}
-variable "enable_global_logging" {
- default = true
- description = "Enable recording of global events (E.g., IAM)"
- type = bool
-}
-
variable "logging_bucket" {
default = null
description = "Optional target for S3 access logging"
@@ -45,9 +39,9 @@ variable "recorder_name" {
}
variable "snapshot_delivery_frequency" {
- default = "Six_Hours"
- description = "Deliery frequency: One_Hour, Three_Hours, Six_Hours, Twelve_Hours, TwentyFour_Hours"
+ description = "Delivery frequency. Valid values: One_Hour, Three_Hours, Six_Hours, Twelve_Hours, TwentyFour_Hours"
type = string
+ default = "Six_Hours"
}
variable "sns_topic_arn" {
@@ -61,3 +55,99 @@ variable "tags" {
description = "Tags to add to resources that support it"
type = map(string)
}
+
+variable "s3_bucket_kms_key_id" {
+ description = "The ARN of the KMS key to use for encrypting the S3 bucket. If not provided, AES256 encryption will be used."
+ type = string
+ default = null
+}
+
+variable "sns_topic_kms_key_id" {
+ description = "The ARN of the KMS key to use for encrypting the SNS topic. If not provided, the default AWS managed key for SNS will be used."
+ type = string
+ default = null
+}
+
+variable "recording_group_all_supported" {
+ description = "Specifies whether AWS Config records configuration changes for every supported type of regional resource. If set to 'false', you must specify resource types in 'recording_group_resource_types'."
+ type = bool
+ default = true
+}
+
+variable "recording_group_include_global_resource_types" {
+ description = "Specifies whether AWS Config includes all supported types of global resources with the resources that it records. Only valid when 'recording_group_all_supported' is true."
+ type = bool
+ default = true
+}
+
+variable "recording_group_resource_types" {
+ description = "A list of valid AWS resource types to include in this recording group. Only used if 'recording_group_all_supported' is false."
+ type = list(string)
+ default = []
+}
+
+variable "recording_group_exclusion_resource_types" {
+ description = "A list of resource types to exclude from recording. Only valid when 'recording_group_all_supported' is true."
+ type = list(string)
+ default = []
+}
+
+variable "recording_group_recording_strategy_use_only" {
+ description = "Specifies whether AWS Config limits recording to the resource types specified in 'recording_group_resource_types'. Valid values: 'ALL_SUPPORTED_RESOURCE_TYPES' or 'INCLUSION_BY_RESOURCE_TYPES'."
+ type = string
+ default = null
+}
+
+variable "recording_mode_recording_frequency" {
+ description = "The frequency with which AWS Config records configuration changes. Valid values: CONTINUOUS, PERIODIC_1_HOUR, PERIODIC_3_HOURS, PERIODIC_6_HOURS, PERIODIC_12_HOURS, PERIODIC_24_HOURS"
+ type = string
+ default = "CONTINUOUS"
+}
+
+variable "recording_mode_override_enabled" {
+ description = "Specifies whether to enable recording mode override."
+ type = bool
+ default = false
+}
+
+variable "recording_mode_override_description" {
+ description = "A description for the recording mode override."
+ type = string
+ default = null
+}
+
+variable "recording_mode_override_resource_types" {
+ description = "A list of resource types to be recorded at the frequency specified in recording_mode_override_recording_frequency."
+ type = list(string)
+ default = []
+}
+
+variable "recording_mode_override_recording_frequency" {
+ description = "The frequency for the recording mode override. Valid values: CONTINUOUS, PERIODIC_1_HOUR, PERIODIC_3_HOURS, PERIODIC_6_HOURS, PERIODIC_12_HOURS, PERIODIC_24_HOURS"
+ type = string
+ default = "CONTINUOUS"
+}
+
+variable "s3_key_prefix" {
+ description = "The prefix for the specified S3 bucket."
+ type = string
+ default = null
+}
+
+variable "grant_s3_kms_access" {
+ description = "Whether to grant the IAM role access to the S3 bucket KMS key"
+ type = bool
+ default = true
+}
+
+variable "grant_sns_kms_access" {
+ description = "Whether to grant the IAM role access to the SNS topic KMS key"
+ type = bool
+ default = true
+}
+
+variable "create_sns_topic" {
+ description = "Whether to create an SNS topic"
+ type = bool
+ default = false
+}
diff --git a/versions.tf b/versions.tf
index 6b4dc4e..5c7c4d1 100644
--- a/versions.tf
+++ b/versions.tf
@@ -1,10 +1,10 @@
terraform {
- required_version = ">= 0.13.4"
+ required_version = ">= 1.1"
required_providers {
aws = {
source = "hashicorp/aws"
- version = ">= 3.8"
+ version = ">= 5.0"
}
}
}