diff --git a/README.md b/README.md
index d373e0b..6051c5a 100644
--- a/README.md
+++ b/README.md
@@ -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"
@@ -124,6 +129,7 @@ module "cloudformation_stack" {
| [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`.
This is for some rare cases where resources want additional configuration of tags
and therefore take a list of maps with tag key, value, and additional configuration. | `map(string)` | `{}` | no |
| [attributes](#input\_attributes) | ID element. Additional attributes (e.g. `workers` or `cluster`) to add to `id`,
in the order they appear in the list. New attributes are appended to the
end of the list. The elements of the list are joined by the `delimiter`
and treated as a single ID element. | `list(string)` | `[]` | no |
| [capabilities](#input\_capabilities) | A list of capabilities. Valid values: CAPABILITY\_IAM, CAPABILITY\_NAMED\_IAM, CAPABILITY\_AUTO\_EXPAND | `list(string)` | `[]` | no |
+| [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 |
| [context](#input\_context) | Single object for setting entire context at once.
See description of individual variables for details.
Leave string and numeric variables as `null` to use default value.
Individual variable settings (non-null) override settings in context object,
except for attributes, tags, and additional\_tag\_map, which are merged. | `any` |
{
"additional_tag_map": {},
"attributes": [],
"delimiter": null,
"descriptor_formats": {},
"enabled": true,
"environment": null,
"id_length_limit": null,
"label_key_case": null,
"label_order": [],
"label_value_case": null,
"labels_as_tags": [
"unset"
],
"name": null,
"namespace": null,
"regex_replace_chars": null,
"stage": null,
"tags": {},
"tenant": null
} | no |
| [delimiter](#input\_delimiter) | Delimiter to be used between ID elements.
Defaults to `-` (hyphen). Set to `""` to use no delimiter at all. | `string` | `null` | no |
| [descriptor\_formats](#input\_descriptor\_formats) | Describe additional descriptors to be output in the `descriptors` output map.
Map of maps. Keys are names of descriptors. Values are maps of the form
`{
format = string
labels = list(string)
}`
(Type is `any` so the map values can later be enhanced to provide additional options.)
`format` is a Terraform format string to be passed to the `format()` function.
`labels` is a list of labels, in order, to pass to `format()` function.
Label values will be normalized before being passed to `format()` so they will be
identical to how they appear in `id`.
Default is `{}` (`descriptors` output will be empty). | `any` | `{}` | no |
@@ -142,7 +148,8 @@ module "cloudformation_stack" {
| [regex\_replace\_chars](#input\_regex\_replace\_chars) | Terraform regular expression (regex) string.
Characters matching the regex will be removed from the ID elements.
If not set, `"/[^a-zA-Z0-9-]/"` is used to remove all characters other than hyphens, letters and digits. | `string` | `null` | no |
| [stage](#input\_stage) | ID element. Usually used to indicate role, e.g. 'prod', 'staging', 'source', 'build', 'test', 'deploy', 'release' | `string` | `null` | no |
| [tags](#input\_tags) | Additional tags (e.g. `{'BusinessUnit': 'XYZ'}`).
Neither the tag keys nor the tag values will be modified by this module. | `map(string)` | `{}` | no |
-| [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 |
+| [template\_body](#input\_template\_body) | Structure containing the CloudFormation template body. Maximum size: 51,200 bytes | `string` | `null` | no |
+| [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 |
| [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 |
| [timeout\_in\_minutes](#input\_timeout\_in\_minutes) | The amount of time that can pass before the stack status becomes `CREATE_FAILED` | `number` | `30` | no |
diff --git a/examples/complete/example.template b/examples/complete/example.template
new file mode 100644
index 0000000..9bb166b
--- /dev/null
+++ b/examples/complete/example.template
@@ -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'
diff --git a/examples/complete/fixtures.us-east-2.tfvars b/examples/complete/fixtures.us-east-2.tfvars
index 9c4af48..e85383f 100644
--- a/examples/complete/fixtures.us-east-2.tfvars
+++ b/examples/complete/fixtures.us-east-2.tfvars
@@ -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 = []
diff --git a/examples/complete/main.tf b/examples/complete/main.tf
index 7e53100..d401fc3 100644
--- a/examples/complete/main.tf
+++ b/examples/complete/main.tf
@@ -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}"
+ })
}
diff --git a/examples/complete/variables.tf b/examples/complete/variables.tf
index b17f520..28061fb 100644
--- a/examples/complete/variables.tf
+++ b/examples/complete/variables.tf
@@ -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\")"
@@ -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"
-}
+}
\ No newline at end of file
diff --git a/examples/complete/versions.tf b/examples/complete/versions.tf
index 5b2c49b..3b49b80 100644
--- a/examples/complete/versions.tf
+++ b/examples/complete/versions.tf
@@ -6,5 +6,9 @@ terraform {
source = "hashicorp/aws"
version = ">= 2.0"
}
+ random = {
+ source = "hashicorp/random"
+ version = ">= 3.0"
+ }
}
}
diff --git a/main.tf b/main.tf
index 4c69e02..8936770 100644
--- a/main.tf
+++ b/main.tf
@@ -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
diff --git a/output.tf b/output.tf
index d357605..0a95f59 100644
--- a/output.tf
+++ b/output.tf
@@ -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"
}
diff --git a/test/src/examples_complete_test.go b/test/src/examples_complete_test.go
index 8b1bed0..168bfca 100644
--- a/test/src/examples_complete_test.go
+++ b/test/src/examples_complete_test.go
@@ -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 }
@@ -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")
}
diff --git a/variables.tf b/variables.tf
index 8fe9897..da970cb 100644
--- a/variables.tf
+++ b/variables.tf
@@ -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\")"
@@ -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."
+}
+