github.com/recobe182/terraform@v0.8.5-0.20170117231232-49ab22a935b7/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  	expectedPolicyBody := "{\"Statement\":[{\"Action\":\"Update:*\",\"Effect\":\"Deny\",\"Principal\":\"*\",\"Resource\":\"LogicalResourceId/StaticVPC\"},{\"Action\":\"Update:*\",\"Effect\":\"Allow\",\"Principal\":\"*\",\"Resource\":\"*\"}]}"
    55  	resource.Test(t, resource.TestCase{
    56  		PreCheck:     func() { testAccPreCheck(t) },
    57  		Providers:    testAccProviders,
    58  		CheckDestroy: testAccCheckAWSCloudFormationDestroy,
    59  		Steps: []resource.TestStep{
    60  			resource.TestStep{
    61  				Config: testAccAWSCloudFormationConfig_allAttributesWithBodies,
    62  				Check: resource.ComposeTestCheckFunc(
    63  					testAccCheckCloudFormationStackExists("aws_cloudformation_stack.full", &stack),
    64  					resource.TestCheckResourceAttr("aws_cloudformation_stack.full", "name", "tf-full-stack"),
    65  					resource.TestCheckResourceAttr("aws_cloudformation_stack.full", "capabilities.#", "1"),
    66  					resource.TestCheckResourceAttr("aws_cloudformation_stack.full", "capabilities.1328347040", "CAPABILITY_IAM"),
    67  					resource.TestCheckResourceAttr("aws_cloudformation_stack.full", "disable_rollback", "false"),
    68  					resource.TestCheckResourceAttr("aws_cloudformation_stack.full", "notification_arns.#", "1"),
    69  					resource.TestCheckResourceAttr("aws_cloudformation_stack.full", "parameters.%", "1"),
    70  					resource.TestCheckResourceAttr("aws_cloudformation_stack.full", "parameters.VpcCIDR", "10.0.0.0/16"),
    71  					resource.TestCheckResourceAttr("aws_cloudformation_stack.full", "policy_body", expectedPolicyBody),
    72  					resource.TestCheckResourceAttr("aws_cloudformation_stack.full", "tags.%", "2"),
    73  					resource.TestCheckResourceAttr("aws_cloudformation_stack.full", "tags.First", "Mickey"),
    74  					resource.TestCheckResourceAttr("aws_cloudformation_stack.full", "tags.Second", "Mouse"),
    75  					resource.TestCheckResourceAttr("aws_cloudformation_stack.full", "timeout_in_minutes", "10"),
    76  				),
    77  			},
    78  			resource.TestStep{
    79  				Config: testAccAWSCloudFormationConfig_allAttributesWithBodies_modified,
    80  				Check: resource.ComposeTestCheckFunc(
    81  					testAccCheckCloudFormationStackExists("aws_cloudformation_stack.full", &stack),
    82  					resource.TestCheckResourceAttr("aws_cloudformation_stack.full", "name", "tf-full-stack"),
    83  					resource.TestCheckResourceAttr("aws_cloudformation_stack.full", "capabilities.#", "1"),
    84  					resource.TestCheckResourceAttr("aws_cloudformation_stack.full", "capabilities.1328347040", "CAPABILITY_IAM"),
    85  					resource.TestCheckResourceAttr("aws_cloudformation_stack.full", "disable_rollback", "false"),
    86  					resource.TestCheckResourceAttr("aws_cloudformation_stack.full", "notification_arns.#", "1"),
    87  					resource.TestCheckResourceAttr("aws_cloudformation_stack.full", "parameters.%", "1"),
    88  					resource.TestCheckResourceAttr("aws_cloudformation_stack.full", "parameters.VpcCIDR", "10.0.0.0/16"),
    89  					resource.TestCheckResourceAttr("aws_cloudformation_stack.full", "policy_body", expectedPolicyBody),
    90  					resource.TestCheckResourceAttr("aws_cloudformation_stack.full", "tags.%", "2"),
    91  					resource.TestCheckResourceAttr("aws_cloudformation_stack.full", "tags.First", "Mickey"),
    92  					resource.TestCheckResourceAttr("aws_cloudformation_stack.full", "tags.Second", "Mouse"),
    93  					resource.TestCheckResourceAttr("aws_cloudformation_stack.full", "timeout_in_minutes", "10"),
    94  				),
    95  			},
    96  		},
    97  	})
    98  }
    99  
   100  // Regression for https://github.com/hashicorp/terraform/issues/4332
   101  func TestAccAWSCloudFormation_withParams(t *testing.T) {
   102  	var stack cloudformation.Stack
   103  
   104  	resource.Test(t, resource.TestCase{
   105  		PreCheck:     func() { testAccPreCheck(t) },
   106  		Providers:    testAccProviders,
   107  		CheckDestroy: testAccCheckAWSCloudFormationDestroy,
   108  		Steps: []resource.TestStep{
   109  			resource.TestStep{
   110  				Config: testAccAWSCloudFormationConfig_withParams,
   111  				Check: resource.ComposeTestCheckFunc(
   112  					testAccCheckCloudFormationStackExists("aws_cloudformation_stack.with_params", &stack),
   113  				),
   114  			},
   115  			resource.TestStep{
   116  				Config: testAccAWSCloudFormationConfig_withParams_modified,
   117  				Check: resource.ComposeTestCheckFunc(
   118  					testAccCheckCloudFormationStackExists("aws_cloudformation_stack.with_params", &stack),
   119  				),
   120  			},
   121  		},
   122  	})
   123  }
   124  
   125  // Regression for https://github.com/hashicorp/terraform/issues/4534
   126  func TestAccAWSCloudFormation_withUrl_withParams(t *testing.T) {
   127  	var stack cloudformation.Stack
   128  
   129  	resource.Test(t, resource.TestCase{
   130  		PreCheck:     func() { testAccPreCheck(t) },
   131  		Providers:    testAccProviders,
   132  		CheckDestroy: testAccCheckAWSCloudFormationDestroy,
   133  		Steps: []resource.TestStep{
   134  			resource.TestStep{
   135  				Config: testAccAWSCloudFormationConfig_templateUrl_withParams,
   136  				Check: resource.ComposeTestCheckFunc(
   137  					testAccCheckCloudFormationStackExists("aws_cloudformation_stack.with-url-and-params", &stack),
   138  				),
   139  			},
   140  			resource.TestStep{
   141  				Config: testAccAWSCloudFormationConfig_templateUrl_withParams_modified,
   142  				Check: resource.ComposeTestCheckFunc(
   143  					testAccCheckCloudFormationStackExists("aws_cloudformation_stack.with-url-and-params", &stack),
   144  				),
   145  			},
   146  		},
   147  	})
   148  }
   149  
   150  func testAccCheckCloudFormationStackExists(n string, stack *cloudformation.Stack) resource.TestCheckFunc {
   151  	return func(s *terraform.State) error {
   152  		rs, ok := s.RootModule().Resources[n]
   153  		if !ok {
   154  			return fmt.Errorf("Not found: %s", n)
   155  		}
   156  
   157  		conn := testAccProvider.Meta().(*AWSClient).cfconn
   158  		params := &cloudformation.DescribeStacksInput{
   159  			StackName: aws.String(rs.Primary.ID),
   160  		}
   161  		resp, err := conn.DescribeStacks(params)
   162  		if err != nil {
   163  			return err
   164  		}
   165  		if len(resp.Stacks) == 0 {
   166  			return fmt.Errorf("CloudFormation stack not found")
   167  		}
   168  
   169  		return nil
   170  	}
   171  }
   172  
   173  func testAccCheckAWSCloudFormationDestroy(s *terraform.State) error {
   174  	conn := testAccProvider.Meta().(*AWSClient).cfconn
   175  
   176  	for _, rs := range s.RootModule().Resources {
   177  		if rs.Type != "aws_cloudformation_stack" {
   178  			continue
   179  		}
   180  
   181  		params := cloudformation.DescribeStacksInput{
   182  			StackName: aws.String(rs.Primary.ID),
   183  		}
   184  
   185  		resp, err := conn.DescribeStacks(&params)
   186  
   187  		if err != nil {
   188  			return err
   189  		}
   190  
   191  		for _, s := range resp.Stacks {
   192  			if *s.StackId == rs.Primary.ID && *s.StackStatus != "DELETE_COMPLETE" {
   193  				return fmt.Errorf("CloudFormation stack still exists: %q", rs.Primary.ID)
   194  			}
   195  		}
   196  	}
   197  
   198  	return nil
   199  }
   200  
   201  var testAccAWSCloudFormationConfig = `
   202  resource "aws_cloudformation_stack" "network" {
   203    name = "tf-networking-stack"
   204    template_body = <<STACK
   205  {
   206    "Resources" : {
   207      "MyVPC": {
   208        "Type" : "AWS::EC2::VPC",
   209        "Properties" : {
   210          "CidrBlock" : "10.0.0.0/16",
   211          "Tags" : [
   212            {"Key": "Name", "Value": "Primary_CF_VPC"}
   213          ]
   214        }
   215      }
   216    },
   217    "Outputs" : {
   218      "DefaultSgId" : {
   219        "Description": "The ID of default security group",
   220        "Value" : { "Fn::GetAtt" : [ "MyVPC", "DefaultSecurityGroup" ]}
   221      },
   222      "VpcID" : {
   223        "Description": "The VPC ID",
   224        "Value" : { "Ref" : "MyVPC" }
   225      }
   226    }
   227  }
   228  STACK
   229  }`
   230  
   231  var testAccAWSCloudFormationConfig_defaultParams = `
   232  resource "aws_cloudformation_stack" "asg-demo" {
   233    name = "tf-asg-demo-stack"
   234    template_body = <<BODY
   235  {
   236      "Parameters": {
   237          "TopicName": {
   238              "Type": "String"
   239          },
   240          "VPCCIDR": {
   241              "Type": "String",
   242              "Default": "10.10.0.0/16"
   243          }
   244      },
   245      "Resources": {
   246          "NotificationTopic": {
   247              "Type": "AWS::SNS::Topic",
   248              "Properties": {
   249                  "TopicName": {
   250                      "Ref": "TopicName"
   251                  }
   252              }
   253          },
   254          "MyVPC": {
   255              "Type": "AWS::EC2::VPC",
   256              "Properties": {
   257                  "CidrBlock": {
   258                      "Ref": "VPCCIDR"
   259                  },
   260                  "Tags": [
   261                      {
   262                          "Key": "Name",
   263                          "Value": "Primary_CF_VPC"
   264                      }
   265                  ]
   266              }
   267          }
   268      },
   269      "Outputs": {
   270          "VPCCIDR": {
   271              "Value": {
   272                  "Ref": "VPCCIDR"
   273              }
   274          }
   275      }
   276  }
   277  BODY
   278  
   279    parameters {
   280      TopicName = "ExampleTopic"
   281    }
   282  }
   283  `
   284  
   285  var testAccAWSCloudFormationConfig_allAttributesWithBodies_tpl = `
   286  resource "aws_cloudformation_stack" "full" {
   287    name = "tf-full-stack"
   288    template_body = <<STACK
   289  {
   290    "Parameters" : {
   291      "VpcCIDR" : {
   292        "Description" : "CIDR to be used for the VPC",
   293        "Type" : "String"
   294      }
   295    },
   296    "Resources" : {
   297      "MyVPC": {
   298        "Type" : "AWS::EC2::VPC",
   299        "Properties" : {
   300          "CidrBlock" : {"Ref": "VpcCIDR"},
   301          "Tags" : [
   302            {"Key": "Name", "Value": "%s"}
   303          ]
   304        }
   305      },
   306      "StaticVPC": {
   307        "Type" : "AWS::EC2::VPC",
   308        "Properties" : {
   309          "CidrBlock" : {"Ref": "VpcCIDR"},
   310          "Tags" : [
   311            {"Key": "Name", "Value": "Static_CF_VPC"}
   312          ]
   313        }
   314      },
   315      "InstanceRole" : {
   316        "Type" : "AWS::IAM::Role",
   317        "Properties" : {
   318          "AssumeRolePolicyDocument": {
   319            "Version": "2012-10-17",
   320            "Statement": [ {
   321              "Effect": "Allow",
   322              "Principal": { "Service": "ec2.amazonaws.com" },
   323              "Action": "sts:AssumeRole"
   324            } ]
   325          },
   326          "Path" : "/",
   327          "Policies" : [ {
   328            "PolicyName": "terraformtest",
   329            "PolicyDocument": {
   330              "Version": "2012-10-17",
   331              "Statement": [ {
   332                "Effect": "Allow",
   333                "Action": [ "ec2:DescribeSnapshots" ],
   334                "Resource": [ "*" ]
   335              } ]
   336            }
   337          } ]
   338        }
   339      }
   340    }
   341  }
   342  STACK
   343    parameters {
   344      VpcCIDR = "10.0.0.0/16"
   345    }
   346  
   347    policy_body = <<POLICY
   348  %s
   349  POLICY
   350    capabilities = ["CAPABILITY_IAM"]
   351    notification_arns = ["${aws_sns_topic.cf-updates.arn}"]
   352    on_failure = "DELETE"
   353    timeout_in_minutes = 10
   354    tags {
   355      First = "Mickey"
   356      Second = "Mouse"
   357    }
   358  }
   359  
   360  resource "aws_sns_topic" "cf-updates" {
   361    name = "tf-cf-notifications"
   362  }
   363  `
   364  
   365  var policyBody = `
   366  {
   367    "Statement" : [
   368      {
   369        "Effect" : "Deny",
   370        "Action" : "Update:*",
   371        "Principal": "*",
   372        "Resource" : "LogicalResourceId/StaticVPC"
   373      },
   374      {
   375        "Effect" : "Allow",
   376        "Action" : "Update:*",
   377        "Principal": "*",
   378        "Resource" : "*"
   379      }
   380    ]
   381  }
   382  `
   383  
   384  var testAccAWSCloudFormationConfig_allAttributesWithBodies = fmt.Sprintf(
   385  	testAccAWSCloudFormationConfig_allAttributesWithBodies_tpl,
   386  	"Primary_CF_VPC",
   387  	policyBody)
   388  var testAccAWSCloudFormationConfig_allAttributesWithBodies_modified = fmt.Sprintf(
   389  	testAccAWSCloudFormationConfig_allAttributesWithBodies_tpl,
   390  	"Primary_CloudFormation_VPC",
   391  	policyBody)
   392  
   393  var tpl_testAccAWSCloudFormationConfig_withParams = `
   394  resource "aws_cloudformation_stack" "with_params" {
   395    name = "tf-stack-with-params"
   396    parameters {
   397      VpcCIDR = "%s"
   398    }
   399    template_body = <<STACK
   400  {
   401    "Parameters" : {
   402      "VpcCIDR" : {
   403        "Description" : "CIDR to be used for the VPC",
   404        "Type" : "String"
   405      }
   406    },
   407    "Resources" : {
   408      "MyVPC": {
   409        "Type" : "AWS::EC2::VPC",
   410        "Properties" : {
   411          "CidrBlock" : {"Ref": "VpcCIDR"},
   412          "Tags" : [
   413            {"Key": "Name", "Value": "Primary_CF_VPC"}
   414          ]
   415        }
   416      }
   417    }
   418  }
   419  STACK
   420  
   421    on_failure = "DELETE"
   422    timeout_in_minutes = 1
   423  }
   424  `
   425  
   426  var testAccAWSCloudFormationConfig_withParams = fmt.Sprintf(
   427  	tpl_testAccAWSCloudFormationConfig_withParams,
   428  	"10.0.0.0/16")
   429  var testAccAWSCloudFormationConfig_withParams_modified = fmt.Sprintf(
   430  	tpl_testAccAWSCloudFormationConfig_withParams,
   431  	"12.0.0.0/16")
   432  
   433  var tpl_testAccAWSCloudFormationConfig_templateUrl_withParams = `
   434  resource "aws_s3_bucket" "b" {
   435    bucket = "%s"
   436    acl = "public-read"
   437    policy = <<POLICY
   438  {
   439    "Version":"2008-10-17",
   440    "Statement": [
   441      {
   442        "Sid":"AllowPublicRead",
   443        "Effect":"Allow",
   444        "Principal": {
   445          "AWS": "*"
   446        },
   447        "Action": "s3:GetObject",
   448        "Resource": "arn:aws:s3:::%s/*"
   449      }
   450    ]
   451  }
   452  POLICY
   453  
   454    website {
   455        index_document = "index.html"
   456        error_document = "error.html"
   457    }
   458  }
   459  
   460  resource "aws_s3_bucket_object" "object" {
   461    bucket = "${aws_s3_bucket.b.id}"
   462    key = "tf-cf-stack.json"
   463    source = "test-fixtures/cloudformation-template.json"
   464  }
   465  
   466  resource "aws_cloudformation_stack" "with-url-and-params" {
   467    name = "tf-stack-template-url-with-params"
   468    parameters {
   469      VpcCIDR = "%s"
   470    }
   471    template_url = "https://${aws_s3_bucket.b.id}.s3-us-west-2.amazonaws.com/${aws_s3_bucket_object.object.key}"
   472    on_failure = "DELETE"
   473    timeout_in_minutes = 1
   474  }
   475  `
   476  
   477  var cfRandInt = rand.New(rand.NewSource(time.Now().UnixNano())).Int()
   478  var cfBucketName = "tf-stack-with-url-and-params-" + fmt.Sprintf("%d", cfRandInt)
   479  
   480  var testAccAWSCloudFormationConfig_templateUrl_withParams = fmt.Sprintf(
   481  	tpl_testAccAWSCloudFormationConfig_templateUrl_withParams,
   482  	cfBucketName, cfBucketName, "11.0.0.0/16")
   483  var testAccAWSCloudFormationConfig_templateUrl_withParams_modified = fmt.Sprintf(
   484  	tpl_testAccAWSCloudFormationConfig_templateUrl_withParams,
   485  	cfBucketName, cfBucketName, "13.0.0.0/16")