Skip to content

Commit 6c6ad0f

Browse files
authored
Fix: Adhere module.this.enabled (#66)
* Ensure module can be disabled * Add tests to test module when it is disabled.
1 parent 972da8c commit 6c6ad0f

File tree

3 files changed

+84
-26
lines changed

3 files changed

+84
-26
lines changed

main.tf

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
locals {
2+
enabled = module.this.enabled
23
website_config = {
34
redirect_all = [
45
{
@@ -19,7 +20,7 @@ module "logs" {
1920
source = "cloudposse/s3-log-storage/aws"
2021
version = "0.20.0"
2122
attributes = ["logs"]
22-
enabled = var.logs_enabled
23+
enabled = local.enabled && var.logs_enabled
2324
standard_transition_days = var.logs_standard_transition_days
2425
glacier_transition_days = var.logs_glacier_transition_days
2526
expiration_days = var.logs_expiration_days
@@ -36,6 +37,8 @@ module "default_label" {
3637
}
3738

3839
resource "aws_s3_bucket" "default" {
40+
count = local.enabled ? 1 : 0
41+
3942
#bridgecrew:skip=BC_AWS_S3_1:The bucket used for a public static website. (https://docs.bridgecrew.io/docs/s3_1-acl-read-permissions-everyone)
4043
#bridgecrew:skip=BC_AWS_S3_14:Skipping `Ensure all data stored in the S3 bucket is securely encrypted at rest` check until bridgecrew will support dynamic blocks (https://github.com/bridgecrewio/checkov/issues/776).
4144
#bridgecrew:skip=CKV_AWS_52:Skipping `Ensure S3 bucket has MFA delete enabled` due to issue using `mfa_delete` by terraform (https://github.com/hashicorp/terraform-provider-aws/issues/629).
@@ -106,15 +109,19 @@ resource "aws_s3_bucket" "default" {
106109
# AWS only supports a single bucket policy on a bucket. You can combine multiple Statements into a single policy, but not attach multiple policies.
107110
# https://github.com/hashicorp/terraform/issues/10543
108111
resource "aws_s3_bucket_policy" "default" {
109-
bucket = aws_s3_bucket.default.id
110-
policy = data.aws_iam_policy_document.default.json
112+
count = local.enabled ? 1 : 0
113+
114+
bucket = aws_s3_bucket.default[0].id
115+
policy = data.aws_iam_policy_document.default[0].json
111116
}
112117

113118
data "aws_iam_policy_document" "default" {
119+
count = local.enabled ? 1 : 0
120+
114121
statement {
115122
actions = ["s3:GetObject"]
116123

117-
resources = ["${aws_s3_bucket.default.arn}/*"]
124+
resources = ["${aws_s3_bucket.default[0].arn}/*"]
118125

119126
principals {
120127
type = "AWS"
@@ -200,7 +207,7 @@ data "aws_iam_policy_document" "default" {
200207
}
201208

202209
data "aws_iam_policy_document" "replication" {
203-
count = signum(length(var.replication_source_principal_arns))
210+
count = local.enabled ? signum(length(var.replication_source_principal_arns)) : 0
204211

205212
statement {
206213
principals {
@@ -216,25 +223,25 @@ data "aws_iam_policy_document" "replication" {
216223
]
217224

218225
resources = [
219-
aws_s3_bucket.default.arn,
220-
"${aws_s3_bucket.default.arn}/*"
226+
aws_s3_bucket.default[0].arn,
227+
"${aws_s3_bucket.default[0].arn}/*"
221228
]
222229
}
223230
}
224231

225232
data "aws_iam_policy_document" "deployment" {
226-
count = length(keys(var.deployment_arns))
233+
count = local.enabled ? length(keys(var.deployment_arns)) : 0
227234

228235
statement {
229236
actions = var.deployment_actions
230237

231238
resources = flatten([
232239
formatlist(
233-
"${aws_s3_bucket.default.arn}%s",
240+
"${aws_s3_bucket.default[0].arn}%s",
234241
var.deployment_arns[keys(var.deployment_arns)[count.index]]
235242
),
236243
formatlist(
237-
"${aws_s3_bucket.default.arn}%s/*",
244+
"${aws_s3_bucket.default[0].arn}%s/*",
238245
var.deployment_arns[keys(var.deployment_arns)[count.index]]
239246
)
240247
])
@@ -247,13 +254,15 @@ data "aws_iam_policy_document" "deployment" {
247254
}
248255

249256
module "dns" {
250-
source = "cloudposse/route53-alias/aws"
251-
version = "0.12.0"
257+
source = "cloudposse/route53-alias/aws"
258+
version = "0.12.0"
259+
260+
enabled = local.enabled
252261
aliases = compact([signum(length(var.parent_zone_id)) == 1 || signum(length(var.parent_zone_name)) == 1 ? var.hostname : ""])
253262
parent_zone_id = var.parent_zone_id
254263
parent_zone_name = var.parent_zone_name
255-
target_dns_name = aws_s3_bucket.default.website_domain
256-
target_zone_id = aws_s3_bucket.default.hosted_zone_id
264+
target_dns_name = join("", aws_s3_bucket.default.*.website_domain)
265+
target_zone_id = join("", aws_s3_bucket.default.*.hosted_zone_id)
257266

258267
context = module.this.context
259268
}

outputs.tf

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,31 +4,31 @@ output "hostname" {
44
}
55

66
output "s3_bucket_name" {
7-
value = aws_s3_bucket.default.id
7+
value = join("", aws_s3_bucket.default.*.id)
88
description = "DNS record of the website bucket"
99
}
1010

1111
output "s3_bucket_domain_name" {
12-
value = aws_s3_bucket.default.bucket_domain_name
12+
value = join("", aws_s3_bucket.default.*.bucket_domain_name)
1313
description = "Name of the website bucket"
1414
}
1515

1616
output "s3_bucket_arn" {
17-
value = aws_s3_bucket.default.arn
17+
value = join("", aws_s3_bucket.default.*.arn)
1818
description = "ARN identifier of the website bucket"
1919
}
2020

2121
output "s3_bucket_website_endpoint" {
22-
value = aws_s3_bucket.default.website_endpoint
22+
value = join("", aws_s3_bucket.default.*.website_endpoint)
2323
description = "The website endpoint URL"
2424
}
2525

2626
output "s3_bucket_website_domain" {
27-
value = aws_s3_bucket.default.website_domain
27+
value = join("", aws_s3_bucket.default.*.website_domain)
2828
description = "The domain of the website endpoint"
2929
}
3030

3131
output "s3_bucket_hosted_zone_id" {
32-
value = aws_s3_bucket.default.hosted_zone_id
32+
value = join("", aws_s3_bucket.default.*.hosted_zone_id)
3333
description = "The Route 53 Hosted Zone ID for this bucket's region"
3434
}

test/src/examples_complete_test.go

Lines changed: 55 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,29 +20,44 @@ func RandStringRunes(n int) string {
2020
return string(b)
2121
}
2222

23-
// Test the Terraform module in examples/complete using Terratest.
2423
func TestExamplesComplete(t *testing.T) {
24+
terraformOptions := &terraform.Options{
25+
// The path to where our Terraform code is located
26+
TerraformDir: "../../examples/complete",
27+
Upgrade: true,
28+
// Variables to pass to our Terraform code using -var-file options
29+
VarFiles: []string{"fixtures.us-west-1.tfvars"},
30+
}
31+
32+
terraform.Init(t, terraformOptions)
33+
// Run tests in parallel
34+
t.Run("Enabled", testExamplesCompleteEnabled)
35+
t.Run("Disabled", testExamplesCompleteDisabled)
36+
}
37+
38+
// Test the Terraform module in examples/complete using Terratest.
39+
func testExamplesCompleteEnabled(t *testing.T) {
2540
t.Parallel()
2641

27-
testName := "s3-website-test-"+RandStringRunes(10)
42+
testName := "s3-website-test-" + RandStringRunes(10)
2843

2944
terraformOptions := &terraform.Options{
3045
// The path to where our Terraform code is located
3146
TerraformDir: "../../examples/complete",
3247
Upgrade: true,
3348
// Variables to pass to our Terraform code using -var-file options
3449
VarFiles: []string{"fixtures.us-west-1.tfvars"},
35-
Vars: map[string]interface{} {
36-
"name": testName,
37-
"hostname": testName+".testing.cloudposse.co",
50+
Vars: map[string]interface{}{
51+
"name": testName,
52+
"hostname": testName + ".testing.cloudposse.co",
3853
},
3954
}
4055

4156
// At the end of the test, run `terraform destroy` to clean up any resources that were created
4257
defer terraform.Destroy(t, terraformOptions)
4358

4459
// This will run `terraform init` and `terraform apply` and fail the test if there are any errors
45-
terraform.InitAndApply(t, terraformOptions)
60+
terraform.Apply(t, terraformOptions)
4661

4762
// Run `terraform output` to get the value of an output variable
4863
hostname := terraform.Output(t, terraformOptions, "hostname")
@@ -59,3 +74,37 @@ func TestExamplesComplete(t *testing.T) {
5974
// Verify we're getting back the outputs we expect
6075
assert.Equal(t, testName+".testing.cloudposse.co.s3.amazonaws.com", s3BucketDomainName)
6176
}
77+
78+
// Test the Terraform module in examples/complete using Terratest, but with the root module disabled.
79+
func testExamplesCompleteDisabled(t *testing.T) {
80+
t.Parallel()
81+
82+
testName := "s3-website-test-" + RandStringRunes(10)
83+
84+
terraformOptions := &terraform.Options{
85+
// The path to where our Terraform code is located
86+
TerraformDir: "../../examples/complete",
87+
Upgrade: true,
88+
EnvVars: map[string]string{
89+
"TF_CLI_ARGS": "-state=terraform-disabled-test.tfstate",
90+
},
91+
// Variables to pass to our Terraform code using -var-file options
92+
VarFiles: []string{"fixtures.us-west-1.tfvars"},
93+
Vars: map[string]interface{}{
94+
"enabled": "false",
95+
"name": testName,
96+
"hostname": testName + ".testing.cloudposse.co",
97+
},
98+
}
99+
100+
// At the end of the test, run `terraform destroy` to clean up any resources that were created
101+
defer terraform.Destroy(t, terraformOptions)
102+
103+
// This will run `terraform init` and `terraform apply` and fail the test if there are any errors
104+
terraform.Apply(t, terraformOptions)
105+
106+
// Run `terraform output` to get the value of an output variable
107+
s3BucketDomainName := terraform.Output(t, terraformOptions, "s3_bucket_domain_name")
108+
// Verify we're getting back the outputs we expect
109+
assert.Empty(t, s3BucketDomainName)
110+
}

0 commit comments

Comments
 (0)