github.com/erriapo/terraform@v0.6.12-0.20160203182612-0340ea72354f/builtin/providers/aws/resource_aws_cloudformation_stack_test.go (about)

     1  package aws
     2  
     3  import (
     4  	"fmt"
     5  	"math/rand"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/aws/aws-sdk-go/aws"
    10  	"github.com/aws/aws-sdk-go/service/cloudformation"
    11  	"github.com/hashicorp/terraform/helper/resource"
    12  	"github.com/hashicorp/terraform/terraform"
    13  )
    14  
    15  func TestAccAWSCloudFormation_basic(t *testing.T) {
    16  	var stack cloudformation.Stack
    17  
    18  	resource.Test(t, resource.TestCase{
    19  		PreCheck:     func() { testAccPreCheck(t) },
    20  		Providers:    testAccProviders,
    21  		CheckDestroy: testAccCheckAWSCloudFormationDestroy,
    22  		Steps: []resource.TestStep{
    23  			resource.TestStep{
    24  				Config: testAccAWSCloudFormationConfig,
    25  				Check: resource.ComposeTestCheckFunc(
    26  					testAccCheckCloudFormationStackExists("aws_cloudformation_stack.network", &stack),
    27  				),
    28  			},
    29  		},
    30  	})
    31  }
    32  
    33  func TestAccAWSCloudFormation_defaultParams(t *testing.T) {
    34  	var stack cloudformation.Stack
    35  
    36  	resource.Test(t, resource.TestCase{
    37  		PreCheck:     func() { testAccPreCheck(t) },
    38  		Providers:    testAccProviders,
    39  		CheckDestroy: testAccCheckAWSCloudFormationDestroy,
    40  		Steps: []resource.TestStep{
    41  			resource.TestStep{
    42  				Config: testAccAWSCloudFormationConfig_defaultParams,
    43  				Check: resource.ComposeTestCheckFunc(
    44  					testAccCheckCloudFormationStackExists("aws_cloudformation_stack.asg-demo", &stack),
    45  				),
    46  			},
    47  		},
    48  	})
    49  }
    50  
    51  func TestAccAWSCloudFormation_allAttributes(t *testing.T) {
    52  	var stack cloudformation.Stack
    53  
    54  	resource.Test(t, resource.TestCase{
    55  		PreCheck:     func() { testAccPreCheck(t) },
    56  		Providers:    testAccProviders,
    57  		CheckDestroy: testAccCheckAWSCloudFormationDestroy,
    58  		Steps: []resource.TestStep{
    59  			resource.TestStep{
    60  				Config: testAccAWSCloudFormationConfig_allAttributes,
    61  				Check: resource.ComposeTestCheckFunc(
    62  					testAccCheckCloudFormationStackExists("aws_cloudformation_stack.full", &stack),
    63  				),
    64  			},
    65  		},
    66  	})
    67  }
    68  
    69  // Regression for https://github.com/hashicorp/terraform/issues/4332
    70  func TestAccAWSCloudFormation_withParams(t *testing.T) {
    71  	var stack cloudformation.Stack
    72  
    73  	resource.Test(t, resource.TestCase{
    74  		PreCheck:     func() { testAccPreCheck(t) },
    75  		Providers:    testAccProviders,
    76  		CheckDestroy: testAccCheckAWSCloudFormationDestroy,
    77  		Steps: []resource.TestStep{
    78  			resource.TestStep{
    79  				Config: testAccAWSCloudFormationConfig_withParams,
    80  				Check: resource.ComposeTestCheckFunc(
    81  					testAccCheckCloudFormationStackExists("aws_cloudformation_stack.with_params", &stack),
    82  				),
    83  			},
    84  			resource.TestStep{
    85  				Config: testAccAWSCloudFormationConfig_withParams_modified,
    86  				Check: resource.ComposeTestCheckFunc(
    87  					testAccCheckCloudFormationStackExists("aws_cloudformation_stack.with_params", &stack),
    88  				),
    89  			},
    90  		},
    91  	})
    92  }
    93  
    94  // Regression for https://github.com/hashicorp/terraform/issues/4534
    95  func TestAccAWSCloudFormation_withUrl_withParams(t *testing.T) {
    96  	var stack cloudformation.Stack
    97  
    98  	resource.Test(t, resource.TestCase{
    99  		PreCheck:     func() { testAccPreCheck(t) },
   100  		Providers:    testAccProviders,
   101  		CheckDestroy: testAccCheckAWSCloudFormationDestroy,
   102  		Steps: []resource.TestStep{
   103  			resource.TestStep{
   104  				Config: testAccAWSCloudFormationConfig_templateUrl_withParams,
   105  				Check: resource.ComposeTestCheckFunc(
   106  					testAccCheckCloudFormationStackExists("aws_cloudformation_stack.with-url-and-params", &stack),
   107  				),
   108  			},
   109  			resource.TestStep{
   110  				Config: testAccAWSCloudFormationConfig_templateUrl_withParams_modified,
   111  				Check: resource.ComposeTestCheckFunc(
   112  					testAccCheckCloudFormationStackExists("aws_cloudformation_stack.with-url-and-params", &stack),
   113  				),
   114  			},
   115  		},
   116  	})
   117  }
   118  
   119  func testAccCheckCloudFormationStackExists(n string, stack *cloudformation.Stack) resource.TestCheckFunc {
   120  	return func(s *terraform.State) error {
   121  		rs, ok := s.RootModule().Resources[n]
   122  		if !ok {
   123  			return fmt.Errorf("Not found: %s", n)
   124  		}
   125  
   126  		conn := testAccProvider.Meta().(*AWSClient).cfconn
   127  		params := &cloudformation.DescribeStacksInput{
   128  			StackName: aws.String(rs.Primary.ID),
   129  		}
   130  		resp, err := conn.DescribeStacks(params)
   131  		if err != nil {
   132  			return err
   133  		}
   134  		if len(resp.Stacks) == 0 {
   135  			return fmt.Errorf("CloudFormation stack not found")
   136  		}
   137  
   138  		return nil
   139  	}
   140  }
   141  
   142  func testAccCheckAWSCloudFormationDestroy(s *terraform.State) error {
   143  	conn := testAccProvider.Meta().(*AWSClient).cfconn
   144  
   145  	for _, rs := range s.RootModule().Resources {
   146  		if rs.Type != "aws_cloudformation_stack" {
   147  			continue
   148  		}
   149  
   150  		params := cloudformation.DescribeStacksInput{
   151  			StackName: aws.String(rs.Primary.ID),
   152  		}
   153  
   154  		resp, err := conn.DescribeStacks(&params)
   155  
   156  		if err != nil {
   157  			return err
   158  		}
   159  
   160  		for _, s := range resp.Stacks {
   161  			if *s.StackId == rs.Primary.ID && *s.StackStatus != "DELETE_COMPLETE" {
   162  				return fmt.Errorf("CloudFormation stack still exists: %q", rs.Primary.ID)
   163  			}
   164  		}
   165  	}
   166  
   167  	return nil
   168  }
   169  
   170  var testAccAWSCloudFormationConfig = `
   171  resource "aws_cloudformation_stack" "network" {
   172    name = "tf-networking-stack"
   173    template_body = <<STACK
   174  {
   175    "Resources" : {
   176      "MyVPC": {
   177        "Type" : "AWS::EC2::VPC",
   178        "Properties" : {
   179          "CidrBlock" : "10.0.0.0/16",
   180          "Tags" : [
   181            {"Key": "Name", "Value": "Primary_CF_VPC"}
   182          ]
   183        }
   184      }
   185    },
   186    "Outputs" : {
   187      "DefaultSgId" : {
   188        "Description": "The ID of default security group",
   189        "Value" : { "Fn::GetAtt" : [ "MyVPC", "DefaultSecurityGroup" ]}
   190      },
   191      "VpcID" : {
   192        "Description": "The VPC ID",
   193        "Value" : { "Ref" : "MyVPC" }
   194      }
   195    }
   196  }
   197  STACK
   198  }`
   199  
   200  var testAccAWSCloudFormationConfig_defaultParams = `
   201  resource "aws_cloudformation_stack" "asg-demo" {
   202    name = "tf-asg-demo-stack"
   203    template_body = <<BODY
   204  {
   205      "Parameters": {
   206          "TopicName": {
   207              "Type": "String"
   208          },
   209          "VPCCIDR": {
   210              "Type": "String",
   211              "Default": "10.10.0.0/16"
   212          }
   213      },
   214      "Resources": {
   215          "NotificationTopic": {
   216              "Type": "AWS::SNS::Topic",
   217              "Properties": {
   218                  "TopicName": {
   219                      "Ref": "TopicName"
   220                  }
   221              }
   222          },
   223          "MyVPC": {
   224              "Type": "AWS::EC2::VPC",
   225              "Properties": {
   226                  "CidrBlock": {
   227                      "Ref": "VPCCIDR"
   228                  },
   229                  "Tags": [
   230                      {
   231                          "Key": "Name",
   232                          "Value": "Primary_CF_VPC"
   233                      }
   234                  ]
   235              }
   236          }
   237      },
   238      "Outputs": {
   239          "VPCCIDR": {
   240              "Value": {
   241                  "Ref": "VPCCIDR"
   242              }
   243          }
   244      }
   245  }
   246  BODY
   247  
   248    parameters {
   249      TopicName = "ExampleTopic"
   250    }
   251  }
   252  `
   253  
   254  var testAccAWSCloudFormationConfig_allAttributes = `
   255  resource "aws_cloudformation_stack" "full" {
   256    name = "tf-full-stack"
   257    template_body = <<STACK
   258  {
   259    "Resources" : {
   260      "MyVPC": {
   261        "Type" : "AWS::EC2::VPC",
   262        "Properties" : {
   263          "CidrBlock" : "10.0.0.0/16",
   264          "Tags" : [
   265            {"Key": "Name", "Value": "Primary_CF_VPC"}
   266          ]
   267        }
   268      }
   269    }
   270  }
   271  STACK
   272  
   273    capabilities = ["CAPABILITY_IAM"]
   274    notification_arns = ["${aws_sns_topic.cf-updates.arn}"]
   275    on_failure = "DELETE"
   276    timeout_in_minutes = 1
   277  }
   278  
   279  resource "aws_sns_topic" "cf-updates" {
   280    name = "tf-cf-notifications"
   281  }
   282  `
   283  
   284  var tpl_testAccAWSCloudFormationConfig_withParams = `
   285  resource "aws_cloudformation_stack" "with_params" {
   286    name = "tf-stack-with-params"
   287    parameters {
   288      VpcCIDR = "%s"
   289    }
   290    template_body = <<STACK
   291  {
   292    "Parameters" : {
   293      "VpcCIDR" : {
   294        "Description" : "CIDR to be used for the VPC",
   295        "Type" : "String"
   296      }
   297    },
   298    "Resources" : {
   299      "MyVPC": {
   300        "Type" : "AWS::EC2::VPC",
   301        "Properties" : {
   302          "CidrBlock" : {"Ref": "VpcCIDR"},
   303          "Tags" : [
   304            {"Key": "Name", "Value": "Primary_CF_VPC"}
   305          ]
   306        }
   307      }
   308    }
   309  }
   310  STACK
   311  
   312    on_failure = "DELETE"
   313    timeout_in_minutes = 1
   314  }
   315  `
   316  
   317  var testAccAWSCloudFormationConfig_withParams = fmt.Sprintf(
   318  	tpl_testAccAWSCloudFormationConfig_withParams,
   319  	"10.0.0.0/16")
   320  var testAccAWSCloudFormationConfig_withParams_modified = fmt.Sprintf(
   321  	tpl_testAccAWSCloudFormationConfig_withParams,
   322  	"12.0.0.0/16")
   323  
   324  var tpl_testAccAWSCloudFormationConfig_templateUrl_withParams = `
   325  resource "aws_s3_bucket" "b" {
   326    bucket = "%s"
   327    acl = "public-read"
   328    policy = <<POLICY
   329  {
   330    "Version":"2008-10-17",
   331    "Statement": [
   332      {
   333        "Sid":"AllowPublicRead",
   334        "Effect":"Allow",
   335        "Principal": {
   336          "AWS": "*"
   337        },
   338        "Action": "s3:GetObject",
   339        "Resource": "arn:aws:s3:::%s/*"
   340      }
   341    ]
   342  }
   343  POLICY
   344  
   345    website {
   346        index_document = "index.html"
   347        error_document = "error.html"
   348    }
   349  }
   350  
   351  resource "aws_s3_bucket_object" "object" {
   352    bucket = "${aws_s3_bucket.b.id}"
   353    key = "tf-cf-stack.json"
   354    source = "test-fixtures/cloudformation-template.json"
   355  }
   356  
   357  resource "aws_cloudformation_stack" "with-url-and-params" {
   358    name = "tf-stack-template-url-with-params"
   359    parameters {
   360      VpcCIDR = "%s"
   361    }
   362    template_url = "https://${aws_s3_bucket.b.id}.s3-us-west-2.amazonaws.com/${aws_s3_bucket_object.object.key}"
   363    on_failure = "DELETE"
   364    timeout_in_minutes = 1
   365  }
   366  `
   367  
   368  var cfRandInt = rand.New(rand.NewSource(time.Now().UnixNano())).Int()
   369  var cfBucketName = "tf-stack-with-url-and-params-" + fmt.Sprintf("%d", cfRandInt)
   370  
   371  var testAccAWSCloudFormationConfig_templateUrl_withParams = fmt.Sprintf(
   372  	tpl_testAccAWSCloudFormationConfig_templateUrl_withParams,
   373  	cfBucketName, cfBucketName, "11.0.0.0/16")
   374  var testAccAWSCloudFormationConfig_templateUrl_withParams_modified = fmt.Sprintf(
   375  	tpl_testAccAWSCloudFormationConfig_templateUrl_withParams,
   376  	cfBucketName, cfBucketName, "13.0.0.0/16")