diff --git a/builtin/providers/aws/data_source_aws_cloudformation_stack.go b/builtin/providers/aws/data_source_aws_cloudformation_stack.go new file mode 100644 index 000000000..0e2175938 --- /dev/null +++ b/builtin/providers/aws/data_source_aws_cloudformation_stack.go @@ -0,0 +1,109 @@ +package aws + +import ( + "fmt" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/cloudformation" + "github.com/hashicorp/terraform/helper/schema" +) + +func dataSourceAwsCloudFormationStack() *schema.Resource { + return &schema.Resource{ + Read: dataSourceAwsCloudFormationStackRead, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + }, + "template_body": { + Type: schema.TypeString, + Computed: true, + StateFunc: normalizeJson, + }, + "capabilities": { + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Set: schema.HashString, + }, + "description": { + Type: schema.TypeString, + Computed: true, + }, + "disable_rollback": { + Type: schema.TypeBool, + Computed: true, + }, + "notification_arns": { + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Set: schema.HashString, + }, + "parameters": { + Type: schema.TypeMap, + Computed: true, + }, + "outputs": { + Type: schema.TypeMap, + Computed: true, + }, + "timeout_in_minutes": { + Type: schema.TypeInt, + Computed: true, + }, + "tags": { + Type: schema.TypeMap, + Computed: true, + }, + }, + } +} + +func dataSourceAwsCloudFormationStackRead(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).cfconn + name := d.Get("name").(string) + input := cloudformation.DescribeStacksInput{ + StackName: aws.String(name), + } + + out, err := conn.DescribeStacks(&input) + if err != nil { + return fmt.Errorf("Failed describing CloudFormation stack (%s): %s", name, err) + } + if l := len(out.Stacks); l != 1 { + return fmt.Errorf("Expected 1 CloudFormation stack (%s), found %d", name, l) + } + stack := out.Stacks[0] + d.SetId(*stack.StackId) + + d.Set("description", stack.Description) + d.Set("disable_rollback", stack.DisableRollback) + d.Set("timeout_in_minutes", stack.TimeoutInMinutes) + + if len(stack.NotificationARNs) > 0 { + d.Set("notification_arns", schema.NewSet(schema.HashString, flattenStringList(stack.NotificationARNs))) + } + + d.Set("parameters", flattenAllCloudFormationParameters(stack.Parameters)) + d.Set("tags", flattenCloudFormationTags(stack.Tags)) + d.Set("outputs", flattenCloudFormationOutputs(stack.Outputs)) + + if len(stack.Capabilities) > 0 { + d.Set("capabilities", schema.NewSet(schema.HashString, flattenStringList(stack.Capabilities))) + } + + tInput := cloudformation.GetTemplateInput{ + StackName: aws.String(name), + } + tOut, err := conn.GetTemplate(&tInput) + if err != nil { + return err + } + + d.Set("template_body", normalizeJson(*tOut.TemplateBody)) + + return nil +} diff --git a/builtin/providers/aws/data_source_aws_cloudformation_stack_test.go b/builtin/providers/aws/data_source_aws_cloudformation_stack_test.go new file mode 100644 index 000000000..7c3600425 --- /dev/null +++ b/builtin/providers/aws/data_source_aws_cloudformation_stack_test.go @@ -0,0 +1,78 @@ +package aws + +import ( + "regexp" + "testing" + + "github.com/hashicorp/terraform/helper/resource" +) + +func TestAccAWSCloudFormationStack_dataSource_basic(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccCheckAwsCloudFormationStackDataSourceConfig_basic, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("data.aws_cloudformation_stack.network", "outputs.%", "1"), + resource.TestMatchResourceAttr("data.aws_cloudformation_stack.network", "outputs.VPCId", + regexp.MustCompile("^vpc-[a-z0-9]{8}$")), + resource.TestCheckResourceAttr("data.aws_cloudformation_stack.network", "capabilities.#", "0"), + resource.TestCheckResourceAttr("data.aws_cloudformation_stack.network", "disable_rollback", "false"), + resource.TestCheckResourceAttr("data.aws_cloudformation_stack.network", "notification_arns.#", "0"), + resource.TestCheckResourceAttr("data.aws_cloudformation_stack.network", "parameters.%", "1"), + resource.TestCheckResourceAttr("data.aws_cloudformation_stack.network", "parameters.CIDR", "10.10.10.0/24"), + resource.TestCheckResourceAttr("data.aws_cloudformation_stack.network", "timeout_in_minutes", "6"), + resource.TestCheckResourceAttr("data.aws_cloudformation_stack.network", "tags.%", "2"), + resource.TestCheckResourceAttr("data.aws_cloudformation_stack.network", "tags.Name", "Form the Cloud"), + resource.TestCheckResourceAttr("data.aws_cloudformation_stack.network", "tags.Second", "meh"), + ), + }, + }, + }) +} + +const testAccCheckAwsCloudFormationStackDataSourceConfig_basic = ` +resource "aws_cloudformation_stack" "cfs" { + name = "tf-acc-ds-networking-stack" + parameters { + CIDR = "10.10.10.0/24" + } + timeout_in_minutes = 6 + template_body = <> aws_caller_identity + > + aws_cloudformation_stack + > aws_ecs_container_definition