Skip to content
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,12 @@ module "cloudformation_stack" {
namespace = "eg"
stage = "prod"
name = "app"

# Option 1: Use template_url (for templates stored in S3)
template_url = "https://aws-quickstart.s3.amazonaws.com/quickstart-compliance-cis-benchmark/templates/main.template"

# Option 2: Use template_body (for inline templates or local files)
# template_body = file("${path.module}/template.yaml")

parameters = {
NotificationEmailAddressForCloudWatchAlarms = "notify-me@example.com"
Expand Down Expand Up @@ -124,6 +129,7 @@ module "cloudformation_stack" {
| <a name="input_additional_tag_map"></a> [additional\_tag\_map](#input\_additional\_tag\_map) | Additional key-value pairs to add to each map in `tags_as_list_of_maps`. Not added to `tags` or `id`.<br/>This is for some rare cases where resources want additional configuration of tags<br/>and therefore take a list of maps with tag key, value, and additional configuration. | `map(string)` | `{}` | no |
| <a name="input_attributes"></a> [attributes](#input\_attributes) | ID element. Additional attributes (e.g. `workers` or `cluster`) to add to `id`,<br/>in the order they appear in the list. New attributes are appended to the<br/>end of the list. The elements of the list are joined by the `delimiter`<br/>and treated as a single ID element. | `list(string)` | `[]` | no |
| <a name="input_capabilities"></a> [capabilities](#input\_capabilities) | A list of capabilities. Valid values: CAPABILITY\_IAM, CAPABILITY\_NAMED\_IAM, CAPABILITY\_AUTO\_EXPAND | `list(string)` | `[]` | no |
| <a name="input_disable_rollback"></a> [disable\_rollback](#input\_disable\_rollback) | Set to true to disable rollback of the stack if stack creation failed. You can specify either on\_failure or disable\_rollback, but not both. | `bool` | `false` | no |
| <a name="input_context"></a> [context](#input\_context) | Single object for setting entire context at once.<br/>See description of individual variables for details.<br/>Leave string and numeric variables as `null` to use default value.<br/>Individual variable settings (non-null) override settings in context object,<br/>except for attributes, tags, and additional\_tag\_map, which are merged. | `any` | <pre>{<br/> "additional_tag_map": {},<br/> "attributes": [],<br/> "delimiter": null,<br/> "descriptor_formats": {},<br/> "enabled": true,<br/> "environment": null,<br/> "id_length_limit": null,<br/> "label_key_case": null,<br/> "label_order": [],<br/> "label_value_case": null,<br/> "labels_as_tags": [<br/> "unset"<br/> ],<br/> "name": null,<br/> "namespace": null,<br/> "regex_replace_chars": null,<br/> "stage": null,<br/> "tags": {},<br/> "tenant": null<br/>}</pre> | no |
| <a name="input_delimiter"></a> [delimiter](#input\_delimiter) | Delimiter to be used between ID elements.<br/>Defaults to `-` (hyphen). Set to `""` to use no delimiter at all. | `string` | `null` | no |
| <a name="input_descriptor_formats"></a> [descriptor\_formats](#input\_descriptor\_formats) | Describe additional descriptors to be output in the `descriptors` output map.<br/>Map of maps. Keys are names of descriptors. Values are maps of the form<br/>`{<br/> format = string<br/> labels = list(string)<br/>}`<br/>(Type is `any` so the map values can later be enhanced to provide additional options.)<br/>`format` is a Terraform format string to be passed to the `format()` function.<br/>`labels` is a list of labels, in order, to pass to `format()` function.<br/>Label values will be normalized before being passed to `format()` so they will be<br/>identical to how they appear in `id`.<br/>Default is `{}` (`descriptors` output will be empty). | `any` | `{}` | no |
Expand All @@ -142,7 +148,8 @@ module "cloudformation_stack" {
| <a name="input_regex_replace_chars"></a> [regex\_replace\_chars](#input\_regex\_replace\_chars) | Terraform regular expression (regex) string.<br/>Characters matching the regex will be removed from the ID elements.<br/>If not set, `"/[^a-zA-Z0-9-]/"` is used to remove all characters other than hyphens, letters and digits. | `string` | `null` | no |
| <a name="input_stage"></a> [stage](#input\_stage) | ID element. Usually used to indicate role, e.g. 'prod', 'staging', 'source', 'build', 'test', 'deploy', 'release' | `string` | `null` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | Additional tags (e.g. `{'BusinessUnit': 'XYZ'}`).<br/>Neither the tag keys nor the tag values will be modified by this module. | `map(string)` | `{}` | no |
| <a name="input_template_url"></a> [template\_url](#input\_template\_url) | Amazon S3 bucket URL location of a file containing the CloudFormation template body. Maximum file size: 460,800 bytes | `string` | n/a | yes |
| <a name="input_template_body"></a> [template\_body](#input\_template\_body) | Structure containing the CloudFormation template body. Maximum size: 51,200 bytes | `string` | `null` | no |
| <a name="input_template_url"></a> [template\_url](#input\_template\_url) | Amazon S3 bucket URL location of a file containing the CloudFormation template body. Maximum file size: 460,800 bytes | `string` | `null` | no |
| <a name="input_tenant"></a> [tenant](#input\_tenant) | ID element \_(Rarely used, not included by default)\_. A customer identifier, indicating who this instance of a resource is for | `string` | `null` | no |
| <a name="input_timeout_in_minutes"></a> [timeout\_in\_minutes](#input\_timeout\_in\_minutes) | The amount of time that can pass before the stack status becomes `CREATE_FAILED` | `number` | `30` | no |

Expand Down
29 changes: 29 additions & 0 deletions examples/complete/example.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
AWSTemplateFormatVersion: '2010-09-09'
Description: 'Basic test template for CloudFormation stack module'

Parameters:
StackSuffix:
Type: String
Description: 'Unique suffix for the stack and bucket names'
Default: 'test'

Resources:
TestBucket:
Type: AWS::S3::Bucket
DeletionPolicy: Delete
Properties:
BucketName: !Sub '${StackSuffix}-${AWS::AccountId}'
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
VersioningConfiguration:
Status: Suspended

Outputs:
BucketName:
Description: 'Name of the created S3 bucket'
Value: !Ref TestBucket
Export:
Name: !Sub '${AWS::StackName}-BucketName'
13 changes: 2 additions & 11 deletions examples/complete/fixtures.us-east-2.tfvars
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,6 @@ stage = "test"

name = "cloudformation-stack"

template_url = "https://aws-quickstart.s3.amazonaws.com/quickstart-compliance-cis-benchmark/templates/main.template"
parameters = {}

parameters = {
NotificationEmailAddressForCloudWatchAlarms = "notify-me@example.com"
ConfigureCloudtrail = "Yes"
ConfigureConfig = "Yes"
ProfileLevel = "Level 2"
QSS3BucketName = "aws-quickstart"
QSS3KeyPrefix = "quickstart-compliance-cis-benchmark/"
}

capabilities = ["CAPABILITY_IAM"]
capabilities = []
18 changes: 14 additions & 4 deletions examples/complete/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,21 @@ provider "aws" {
region = var.region
}

resource "random_string" "suffix" {
length = 8
special = false
upper = false
}

module "cloudformation_stack" {
source = "../../"
template_url = var.template_url
parameters = var.parameters
source = "../../"
template_body = file("${path.module}/example.template")
parameters = merge(var.parameters, {
StackSuffix = "t${formatdate("MMDDhh", timestamp())}${random_string.suffix.result}"
})
capabilities = var.capabilities

context = module.this.context
context = merge(module.this.context, {
name = "${module.this.name}-${random_string.suffix.result}"
})
}
25 changes: 1 addition & 24 deletions examples/complete/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,6 @@ variable "region" {
description = "AWS Region"
}

variable "template_url" {
type = string
description = "Amazon S3 bucket URL location of a file containing the CloudFormation template body. Maximum file size: 460,800 bytes"
}

variable "parameters" {
type = map(string)
description = "Key-value map of input parameters for the Stack Set template. (_e.g._ map(\"BusinessUnit\",\"ABC\")"
Expand All @@ -18,22 +13,4 @@ variable "capabilities" {
type = list(string)
description = "A list of capabilities. Valid values: CAPABILITY_IAM, CAPABILITY_NAMED_IAM, CAPABILITY_AUTO_EXPAND"
default = []
}

variable "on_failure" {
type = string
default = "ROLLBACK"
description = "Action to be taken if stack creation fails. This must be one of: `DO_NOTHING`, `ROLLBACK`, or `DELETE`"
}

variable "timeout_in_minutes" {
type = number
default = 30
description = "The amount of time that can pass before the stack status becomes `CREATE_FAILED`"
}

variable "policy_body" {
type = string
default = ""
description = "Structure containing the stack policy body"
}
}
4 changes: 4 additions & 0 deletions examples/complete/versions.tf
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,9 @@ terraform {
source = "hashicorp/aws"
version = ">= 2.0"
}
random = {
source = "hashicorp/random"
version = ">= 3.0"
}
}
}
11 changes: 8 additions & 3 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,15 @@ resource "aws_cloudformation_stack" "default" {
tags = module.this.tags

template_url = var.template_url
parameters = var.parameters
capabilities = var.capabilities
# template_url and template_body are mutually exclusive
template_body = var.template_url == null ? var.template_body : null
parameters = var.parameters
capabilities = var.capabilities

on_failure = var.on_failure
# When disable_rollback is true, on_failure should not be set (or set to null)
# When disable_rollback is false, use the value of var.on_failure
on_failure = var.disable_rollback ? null : var.on_failure
disable_rollback = var.disable_rollback
timeout_in_minutes = var.timeout_in_minutes

policy_body = var.policy_body
Expand Down
4 changes: 2 additions & 2 deletions output.tf
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
output "name" {
value = join("", aws_cloudformation_stack.default.*.name)
value = join("", aws_cloudformation_stack.default[*].name)
description = "Name of the CloudFormation Stack"
}

output "id" {
value = join("", aws_cloudformation_stack.default.*.id)
value = join("", aws_cloudformation_stack.default[*].id)
description = "ID of the CloudFormation Stack"
}

Expand Down
9 changes: 5 additions & 4 deletions test/src/examples_complete_test.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package test

import (
"testing"

"github.com/gruntwork-io/terratest/modules/terraform"
"github.com/stretchr/testify/assert"
"testing"
)

func int32Ptr(i int32) *int32 { return &i }
Expand All @@ -28,11 +29,11 @@ func TestExamplesComplete(t *testing.T) {

// Run `terraform output` to get the value of an output variable
name := terraform.Output(t, terraformOptions, "name")
// Verify we're getting back the outputs we expect
assert.Equal(t, "eg-test-cloudformation-stack", name)
// Verify we're getting back the outputs we expect (check prefix and any suffix)
assert.Contains(t, name, "eg-test-cloudformation-stack")

// Run `terraform output` to get the value of an output variable
id := terraform.Output(t, terraformOptions, "id")
// Verify we're getting back the outputs we expect
// Verify we're getting back the outputs we expect (check prefix and any suffix)
assert.Contains(t, id, "stack/eg-test-cloudformation-stack")
}
13 changes: 13 additions & 0 deletions variables.tf
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
variable "template_url" {
type = string
default = null
description = "Amazon S3 bucket URL location of a file containing the CloudFormation template body. Maximum file size: 460,800 bytes"
}

variable "template_body" {
type = string
default = null
description = "Structure containing the CloudFormation template body. Maximum size: 51,200 bytes"
}

variable "parameters" {
type = map(string)
description = "Key-value map of input parameters for the Stack Set template. (_e.g._ map(\"BusinessUnit\",\"ABC\")"
Expand Down Expand Up @@ -33,3 +40,9 @@ variable "policy_body" {
description = "Structure containing the stack policy body"
}

variable "disable_rollback" {
type = bool
default = false
description = "Set to true to disable rollback of the stack if stack creation failed. You can specify either on_failure or disable_rollback, but not both."
}