Merge pull request #8640 from TimeIncOSS/f-aws-cloudformation-data-source
provider/aws: Add cloudformation_stack data source
This commit is contained in:
commit
54784864fc
|
@ -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
|
||||||
|
}
|
|
@ -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 = <<STACK
|
||||||
|
{
|
||||||
|
"Parameters": {
|
||||||
|
"CIDR": {
|
||||||
|
"Type": "String"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Resources" : {
|
||||||
|
"myvpc": {
|
||||||
|
"Type" : "AWS::EC2::VPC",
|
||||||
|
"Properties" : {
|
||||||
|
"CidrBlock" : { "Ref" : "CIDR" },
|
||||||
|
"Tags" : [
|
||||||
|
{"Key": "Name", "Value": "Primary_CF_VPC"}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Outputs" : {
|
||||||
|
"VPCId" : {
|
||||||
|
"Value" : { "Ref" : "myvpc" },
|
||||||
|
"Description" : "VPC ID"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
STACK
|
||||||
|
tags {
|
||||||
|
Name = "Form the Cloud"
|
||||||
|
Second = "meh"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data "aws_cloudformation_stack" "network" {
|
||||||
|
name = "${aws_cloudformation_stack.cfs.name}"
|
||||||
|
}
|
||||||
|
`
|
|
@ -146,6 +146,7 @@ func Provider() terraform.ResourceProvider {
|
||||||
"aws_ami": dataSourceAwsAmi(),
|
"aws_ami": dataSourceAwsAmi(),
|
||||||
"aws_availability_zones": dataSourceAwsAvailabilityZones(),
|
"aws_availability_zones": dataSourceAwsAvailabilityZones(),
|
||||||
"aws_caller_identity": dataSourceAwsCallerIdentity(),
|
"aws_caller_identity": dataSourceAwsCallerIdentity(),
|
||||||
|
"aws_cloudformation_stack": dataSourceAwsCloudFormationStack(),
|
||||||
"aws_ecs_container_definition": dataSourceAwsEcsContainerDefinition(),
|
"aws_ecs_container_definition": dataSourceAwsEcsContainerDefinition(),
|
||||||
"aws_elb_service_account": dataSourceAwsElbServiceAccount(),
|
"aws_elb_service_account": dataSourceAwsElbServiceAccount(),
|
||||||
"aws_iam_policy_document": dataSourceAwsIamPolicyDocument(),
|
"aws_iam_policy_document": dataSourceAwsIamPolicyDocument(),
|
||||||
|
|
|
@ -991,6 +991,14 @@ func flattenCloudFormationParameters(cfParams []*cloudformation.Parameter,
|
||||||
return params
|
return params
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func flattenAllCloudFormationParameters(cfParams []*cloudformation.Parameter) map[string]interface{} {
|
||||||
|
params := make(map[string]interface{}, len(cfParams))
|
||||||
|
for _, p := range cfParams {
|
||||||
|
params[*p.ParameterKey] = *p.ParameterValue
|
||||||
|
}
|
||||||
|
return params
|
||||||
|
}
|
||||||
|
|
||||||
func expandCloudFormationTags(tags map[string]interface{}) []*cloudformation.Tag {
|
func expandCloudFormationTags(tags map[string]interface{}) []*cloudformation.Tag {
|
||||||
var cfTags []*cloudformation.Tag
|
var cfTags []*cloudformation.Tag
|
||||||
for k, v := range tags {
|
for k, v := range tags {
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
---
|
||||||
|
layout: "aws"
|
||||||
|
page_title: "AWS: aws_cloudformation_stack"
|
||||||
|
sidebar_current: "docs-aws-datasource-cloudformation-stack"
|
||||||
|
description: |-
|
||||||
|
Provides metadata of a CloudFormation stack (e.g. outputs)
|
||||||
|
---
|
||||||
|
|
||||||
|
# aws\_cloudformation\_stack
|
||||||
|
|
||||||
|
The CloudFormation Stack data source allows access to stack
|
||||||
|
outputs and other useful data including the template body.
|
||||||
|
|
||||||
|
## Example Usage
|
||||||
|
|
||||||
|
```
|
||||||
|
data "aws_cloudformation_stack" "network" {
|
||||||
|
name = "my-network-stack"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_instance" "web" {
|
||||||
|
ami = "ami-abb07bcb"
|
||||||
|
instance_type = "t1.micro"
|
||||||
|
subnet_id = "${data.aws_cloudformation_stack.network.outputs["SubnetId"]}"
|
||||||
|
tags {
|
||||||
|
Name = "HelloWorld"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Argument Reference
|
||||||
|
|
||||||
|
The following arguments are supported:
|
||||||
|
|
||||||
|
* `name` - (Required) The name of the stack
|
||||||
|
|
||||||
|
## Attributes Reference
|
||||||
|
|
||||||
|
The following attributes are exported:
|
||||||
|
|
||||||
|
* `capabilities` - A list of capabilities
|
||||||
|
* `description` - Description of the stack
|
||||||
|
* `disable_rollback` - Whether the rollback of the stack is disabled when stack creation fails
|
||||||
|
* `notification_arns` - A list of SNS topic ARNs to publish stack related events
|
||||||
|
* `outputs` - A map of outputs from the stack.
|
||||||
|
* `parameters` - A map of parameters that specify input parameters for the stack.
|
||||||
|
* `tags` - A map of tags associated with this stack.
|
||||||
|
* `template_body` - Structure containing the template body.
|
||||||
|
* `timeout_in_minutes` - The amount of time that can pass before the stack status becomes `CREATE_FAILED`
|
|
@ -23,6 +23,9 @@
|
||||||
<li<%= sidebar_current("docs-aws-datasource-caller-identity") %>>
|
<li<%= sidebar_current("docs-aws-datasource-caller-identity") %>>
|
||||||
<a href="/docs/providers/aws/d/caller_identity.html">aws_caller_identity</a>
|
<a href="/docs/providers/aws/d/caller_identity.html">aws_caller_identity</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li<%= sidebar_current("docs-aws-datasource-cloudformation-stack") %>>
|
||||||
|
<a href="/docs/providers/aws/d/cloudformation_stack.html">aws_cloudformation_stack</a>
|
||||||
|
</li>
|
||||||
<li<%= sidebar_current("docs-aws-datasource-ecs-container-definition") %>>
|
<li<%= sidebar_current("docs-aws-datasource-ecs-container-definition") %>>
|
||||||
<a href="/docs/providers/aws/d/ecs_container_definition.html">aws_ecs_container_definition</a>
|
<a href="/docs/providers/aws/d/ecs_container_definition.html">aws_ecs_container_definition</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
Loading…
Reference in New Issue