Skip to content

Commit

Permalink
Fix: Adhere module.this.enabled (#66)
Browse files Browse the repository at this point in the history
* Ensure module can be disabled
* Add tests to test module when it is disabled.
  • Loading branch information
korenyoni authored Jul 2, 2021
1 parent 972da8c commit 6c6ad0f
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 26 deletions.
37 changes: 23 additions & 14 deletions main.tf
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
locals {
enabled = module.this.enabled
website_config = {
redirect_all = [
{
Expand All @@ -19,7 +20,7 @@ module "logs" {
source = "cloudposse/s3-log-storage/aws"
version = "0.20.0"
attributes = ["logs"]
enabled = var.logs_enabled
enabled = local.enabled && var.logs_enabled
standard_transition_days = var.logs_standard_transition_days
glacier_transition_days = var.logs_glacier_transition_days
expiration_days = var.logs_expiration_days
Expand All @@ -36,6 +37,8 @@ module "default_label" {
}

resource "aws_s3_bucket" "default" {
count = local.enabled ? 1 : 0

#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)
#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).
#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).
Expand Down Expand Up @@ -106,15 +109,19 @@ resource "aws_s3_bucket" "default" {
# AWS only supports a single bucket policy on a bucket. You can combine multiple Statements into a single policy, but not attach multiple policies.
# https://github.com/hashicorp/terraform/issues/10543
resource "aws_s3_bucket_policy" "default" {
bucket = aws_s3_bucket.default.id
policy = data.aws_iam_policy_document.default.json
count = local.enabled ? 1 : 0

bucket = aws_s3_bucket.default[0].id
policy = data.aws_iam_policy_document.default[0].json
}

data "aws_iam_policy_document" "default" {
count = local.enabled ? 1 : 0

statement {
actions = ["s3:GetObject"]

resources = ["${aws_s3_bucket.default.arn}/*"]
resources = ["${aws_s3_bucket.default[0].arn}/*"]

principals {
type = "AWS"
Expand Down Expand Up @@ -200,7 +207,7 @@ data "aws_iam_policy_document" "default" {
}

data "aws_iam_policy_document" "replication" {
count = signum(length(var.replication_source_principal_arns))
count = local.enabled ? signum(length(var.replication_source_principal_arns)) : 0

statement {
principals {
Expand All @@ -216,25 +223,25 @@ data "aws_iam_policy_document" "replication" {
]

resources = [
aws_s3_bucket.default.arn,
"${aws_s3_bucket.default.arn}/*"
aws_s3_bucket.default[0].arn,
"${aws_s3_bucket.default[0].arn}/*"
]
}
}

data "aws_iam_policy_document" "deployment" {
count = length(keys(var.deployment_arns))
count = local.enabled ? length(keys(var.deployment_arns)) : 0

statement {
actions = var.deployment_actions

resources = flatten([
formatlist(
"${aws_s3_bucket.default.arn}%s",
"${aws_s3_bucket.default[0].arn}%s",
var.deployment_arns[keys(var.deployment_arns)[count.index]]
),
formatlist(
"${aws_s3_bucket.default.arn}%s/*",
"${aws_s3_bucket.default[0].arn}%s/*",
var.deployment_arns[keys(var.deployment_arns)[count.index]]
)
])
Expand All @@ -247,13 +254,15 @@ data "aws_iam_policy_document" "deployment" {
}

module "dns" {
source = "cloudposse/route53-alias/aws"
version = "0.12.0"
source = "cloudposse/route53-alias/aws"
version = "0.12.0"

enabled = local.enabled
aliases = compact([signum(length(var.parent_zone_id)) == 1 || signum(length(var.parent_zone_name)) == 1 ? var.hostname : ""])
parent_zone_id = var.parent_zone_id
parent_zone_name = var.parent_zone_name
target_dns_name = aws_s3_bucket.default.website_domain
target_zone_id = aws_s3_bucket.default.hosted_zone_id
target_dns_name = join("", aws_s3_bucket.default.*.website_domain)
target_zone_id = join("", aws_s3_bucket.default.*.hosted_zone_id)

context = module.this.context
}
12 changes: 6 additions & 6 deletions outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,31 @@ output "hostname" {
}

output "s3_bucket_name" {
value = aws_s3_bucket.default.id
value = join("", aws_s3_bucket.default.*.id)
description = "DNS record of the website bucket"
}

output "s3_bucket_domain_name" {
value = aws_s3_bucket.default.bucket_domain_name
value = join("", aws_s3_bucket.default.*.bucket_domain_name)
description = "Name of the website bucket"
}

output "s3_bucket_arn" {
value = aws_s3_bucket.default.arn
value = join("", aws_s3_bucket.default.*.arn)
description = "ARN identifier of the website bucket"
}

output "s3_bucket_website_endpoint" {
value = aws_s3_bucket.default.website_endpoint
value = join("", aws_s3_bucket.default.*.website_endpoint)
description = "The website endpoint URL"
}

output "s3_bucket_website_domain" {
value = aws_s3_bucket.default.website_domain
value = join("", aws_s3_bucket.default.*.website_domain)
description = "The domain of the website endpoint"
}

output "s3_bucket_hosted_zone_id" {
value = aws_s3_bucket.default.hosted_zone_id
value = join("", aws_s3_bucket.default.*.hosted_zone_id)
description = "The Route 53 Hosted Zone ID for this bucket's region"
}
61 changes: 55 additions & 6 deletions test/src/examples_complete_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,29 +20,44 @@ func RandStringRunes(n int) string {
return string(b)
}

// Test the Terraform module in examples/complete using Terratest.
func TestExamplesComplete(t *testing.T) {
terraformOptions := &terraform.Options{
// The path to where our Terraform code is located
TerraformDir: "../../examples/complete",
Upgrade: true,
// Variables to pass to our Terraform code using -var-file options
VarFiles: []string{"fixtures.us-west-1.tfvars"},
}

terraform.Init(t, terraformOptions)
// Run tests in parallel
t.Run("Enabled", testExamplesCompleteEnabled)
t.Run("Disabled", testExamplesCompleteDisabled)
}

// Test the Terraform module in examples/complete using Terratest.
func testExamplesCompleteEnabled(t *testing.T) {
t.Parallel()

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

terraformOptions := &terraform.Options{
// The path to where our Terraform code is located
TerraformDir: "../../examples/complete",
Upgrade: true,
// Variables to pass to our Terraform code using -var-file options
VarFiles: []string{"fixtures.us-west-1.tfvars"},
Vars: map[string]interface{} {
"name": testName,
"hostname": testName+".testing.cloudposse.co",
Vars: map[string]interface{}{
"name": testName,
"hostname": testName + ".testing.cloudposse.co",
},
}

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

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

// Run `terraform output` to get the value of an output variable
hostname := terraform.Output(t, terraformOptions, "hostname")
Expand All @@ -59,3 +74,37 @@ func TestExamplesComplete(t *testing.T) {
// Verify we're getting back the outputs we expect
assert.Equal(t, testName+".testing.cloudposse.co.s3.amazonaws.com", s3BucketDomainName)
}

// Test the Terraform module in examples/complete using Terratest, but with the root module disabled.
func testExamplesCompleteDisabled(t *testing.T) {
t.Parallel()

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

terraformOptions := &terraform.Options{
// The path to where our Terraform code is located
TerraformDir: "../../examples/complete",
Upgrade: true,
EnvVars: map[string]string{
"TF_CLI_ARGS": "-state=terraform-disabled-test.tfstate",
},
// Variables to pass to our Terraform code using -var-file options
VarFiles: []string{"fixtures.us-west-1.tfvars"},
Vars: map[string]interface{}{
"enabled": "false",
"name": testName,
"hostname": testName + ".testing.cloudposse.co",
},
}

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

// This will run `terraform init` and `terraform apply` and fail the test if there are any errors
terraform.Apply(t, terraformOptions)

// Run `terraform output` to get the value of an output variable
s3BucketDomainName := terraform.Output(t, terraformOptions, "s3_bucket_domain_name")
// Verify we're getting back the outputs we expect
assert.Empty(t, s3BucketDomainName)
}

0 comments on commit 6c6ad0f

Please sign in to comment.