github.com/koding/terraform@v0.6.4-0.20170608090606-5d7e0339779d/builtin/providers/aws/resource_aws_cloudformation_stack_test.go (about)

     1  package aws
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  
     7  	"github.com/aws/aws-sdk-go/aws"
     8  	"github.com/aws/aws-sdk-go/service/cloudformation"
     9  	"github.com/hashicorp/terraform/helper/acctest"
    10  	"github.com/hashicorp/terraform/helper/resource"
    11  	"github.com/hashicorp/terraform/terraform"
    12  )
    13  
    14  func TestAccAWSCloudFormation_basic(t *testing.T) {
    15  	var stack cloudformation.Stack
    16  	stackName := fmt.Sprintf("tf-acc-test-basic-%s", acctest.RandString(10))
    17  
    18  	resource.Test(t, resource.TestCase{
    19  		PreCheck:     func() { testAccPreCheck(t) },
    20  		Providers:    testAccProviders,
    21  		CheckDestroy: testAccCheckAWSCloudFormationDestroy,
    22  		Steps: []resource.TestStep{
    23  			{
    24  				Config: testAccAWSCloudFormationConfig(stackName),
    25  				Check: resource.ComposeTestCheckFunc(
    26  					testAccCheckCloudFormationStackExists("aws_cloudformation_stack.network", &stack),
    27  				),
    28  			},
    29  		},
    30  	})
    31  }
    32  
    33  func TestAccAWSCloudFormation_yaml(t *testing.T) {
    34  	var stack cloudformation.Stack
    35  	stackName := fmt.Sprintf("tf-acc-test-yaml-%s", acctest.RandString(10))
    36  
    37  	resource.Test(t, resource.TestCase{
    38  		PreCheck:     func() { testAccPreCheck(t) },
    39  		Providers:    testAccProviders,
    40  		CheckDestroy: testAccCheckAWSCloudFormationDestroy,
    41  		Steps: []resource.TestStep{
    42  			{
    43  				Config: testAccAWSCloudFormationConfig_yaml(stackName),
    44  				Check: resource.ComposeTestCheckFunc(
    45  					testAccCheckCloudFormationStackExists("aws_cloudformation_stack.yaml", &stack),
    46  				),
    47  			},
    48  		},
    49  	})
    50  }
    51  
    52  func TestAccAWSCloudFormation_defaultParams(t *testing.T) {
    53  	var stack cloudformation.Stack
    54  	stackName := fmt.Sprintf("tf-acc-test-default-params-%s", acctest.RandString(10))
    55  
    56  	resource.Test(t, resource.TestCase{
    57  		PreCheck:     func() { testAccPreCheck(t) },
    58  		Providers:    testAccProviders,
    59  		CheckDestroy: testAccCheckAWSCloudFormationDestroy,
    60  		Steps: []resource.TestStep{
    61  			{
    62  				Config: testAccAWSCloudFormationConfig_defaultParams(stackName),
    63  				Check: resource.ComposeTestCheckFunc(
    64  					testAccCheckCloudFormationStackExists("aws_cloudformation_stack.asg-demo", &stack),
    65  				),
    66  			},
    67  		},
    68  	})
    69  }
    70  
    71  func TestAccAWSCloudFormation_allAttributes(t *testing.T) {
    72  	var stack cloudformation.Stack
    73  	stackName := fmt.Sprintf("tf-acc-test-all-attributes-%s", acctest.RandString(10))
    74  
    75  	expectedPolicyBody := "{\"Statement\":[{\"Action\":\"Update:*\",\"Effect\":\"Deny\",\"Principal\":\"*\",\"Resource\":\"LogicalResourceId/StaticVPC\"},{\"Action\":\"Update:*\",\"Effect\":\"Allow\",\"Principal\":\"*\",\"Resource\":\"*\"}]}"
    76  	resource.Test(t, resource.TestCase{
    77  		PreCheck:     func() { testAccPreCheck(t) },
    78  		Providers:    testAccProviders,
    79  		CheckDestroy: testAccCheckAWSCloudFormationDestroy,
    80  		Steps: []resource.TestStep{
    81  			{
    82  				Config: testAccAWSCloudFormationConfig_allAttributesWithBodies(stackName),
    83  				Check: resource.ComposeTestCheckFunc(
    84  					testAccCheckCloudFormationStackExists("aws_cloudformation_stack.full", &stack),
    85  					resource.TestCheckResourceAttr("aws_cloudformation_stack.full", "name", stackName),
    86  					resource.TestCheckResourceAttr("aws_cloudformation_stack.full", "capabilities.#", "1"),
    87  					resource.TestCheckResourceAttr("aws_cloudformation_stack.full", "capabilities.1328347040", "CAPABILITY_IAM"),
    88  					resource.TestCheckResourceAttr("aws_cloudformation_stack.full", "disable_rollback", "false"),
    89  					resource.TestCheckResourceAttr("aws_cloudformation_stack.full", "notification_arns.#", "1"),
    90  					resource.TestCheckResourceAttr("aws_cloudformation_stack.full", "parameters.%", "1"),
    91  					resource.TestCheckResourceAttr("aws_cloudformation_stack.full", "parameters.VpcCIDR", "10.0.0.0/16"),
    92  					resource.TestCheckResourceAttr("aws_cloudformation_stack.full", "policy_body", expectedPolicyBody),
    93  					resource.TestCheckResourceAttr("aws_cloudformation_stack.full", "tags.%", "2"),
    94  					resource.TestCheckResourceAttr("aws_cloudformation_stack.full", "tags.First", "Mickey"),
    95  					resource.TestCheckResourceAttr("aws_cloudformation_stack.full", "tags.Second", "Mouse"),
    96  					resource.TestCheckResourceAttr("aws_cloudformation_stack.full", "timeout_in_minutes", "10"),
    97  				),
    98  			},
    99  			{
   100  				Config: testAccAWSCloudFormationConfig_allAttributesWithBodies_modified(stackName),
   101  				Check: resource.ComposeTestCheckFunc(
   102  					testAccCheckCloudFormationStackExists("aws_cloudformation_stack.full", &stack),
   103  					resource.TestCheckResourceAttr("aws_cloudformation_stack.full", "name", stackName),
   104  					resource.TestCheckResourceAttr("aws_cloudformation_stack.full", "capabilities.#", "1"),
   105  					resource.TestCheckResourceAttr("aws_cloudformation_stack.full", "capabilities.1328347040", "CAPABILITY_IAM"),
   106  					resource.TestCheckResourceAttr("aws_cloudformation_stack.full", "disable_rollback", "false"),
   107  					resource.TestCheckResourceAttr("aws_cloudformation_stack.full", "notification_arns.#", "1"),
   108  					resource.TestCheckResourceAttr("aws_cloudformation_stack.full", "parameters.%", "1"),
   109  					resource.TestCheckResourceAttr("aws_cloudformation_stack.full", "parameters.VpcCIDR", "10.0.0.0/16"),
   110  					resource.TestCheckResourceAttr("aws_cloudformation_stack.full", "policy_body", expectedPolicyBody),
   111  					resource.TestCheckResourceAttr("aws_cloudformation_stack.full", "tags.%", "2"),
   112  					resource.TestCheckResourceAttr("aws_cloudformation_stack.full", "tags.First", "Mickey"),
   113  					resource.TestCheckResourceAttr("aws_cloudformation_stack.full", "tags.Second", "Mouse"),
   114  					resource.TestCheckResourceAttr("aws_cloudformation_stack.full", "timeout_in_minutes", "10"),
   115  				),
   116  			},
   117  		},
   118  	})
   119  }
   120  
   121  // Regression for https://github.com/hashicorp/terraform/issues/4332
   122  func TestAccAWSCloudFormation_withParams(t *testing.T) {
   123  	var stack cloudformation.Stack
   124  	stackName := fmt.Sprintf("tf-acc-test-with-params-%s", acctest.RandString(10))
   125  
   126  	resource.Test(t, resource.TestCase{
   127  		PreCheck:     func() { testAccPreCheck(t) },
   128  		Providers:    testAccProviders,
   129  		CheckDestroy: testAccCheckAWSCloudFormationDestroy,
   130  		Steps: []resource.TestStep{
   131  			{
   132  				Config: testAccAWSCloudFormationConfig_withParams(stackName),
   133  				Check: resource.ComposeTestCheckFunc(
   134  					testAccCheckCloudFormationStackExists("aws_cloudformation_stack.with_params", &stack),
   135  				),
   136  			},
   137  			{
   138  				Config: testAccAWSCloudFormationConfig_withParams_modified(stackName),
   139  				Check: resource.ComposeTestCheckFunc(
   140  					testAccCheckCloudFormationStackExists("aws_cloudformation_stack.with_params", &stack),
   141  				),
   142  			},
   143  		},
   144  	})
   145  }
   146  
   147  // Regression for https://github.com/hashicorp/terraform/issues/4534
   148  func TestAccAWSCloudFormation_withUrl_withParams(t *testing.T) {
   149  	var stack cloudformation.Stack
   150  	rName := fmt.Sprintf("tf-acc-test-with-url-and-params-%s", acctest.RandString(10))
   151  
   152  	resource.Test(t, resource.TestCase{
   153  		PreCheck:     func() { testAccPreCheck(t) },
   154  		Providers:    testAccProviders,
   155  		CheckDestroy: testAccCheckAWSCloudFormationDestroy,
   156  		Steps: []resource.TestStep{
   157  			{
   158  				Config: testAccAWSCloudFormationConfig_templateUrl_withParams(rName, "tf-cf-stack.json", "11.0.0.0/16"),
   159  				Check: resource.ComposeTestCheckFunc(
   160  					testAccCheckCloudFormationStackExists("aws_cloudformation_stack.with-url-and-params", &stack),
   161  				),
   162  			},
   163  			{
   164  				Config: testAccAWSCloudFormationConfig_templateUrl_withParams(rName, "tf-cf-stack.json", "13.0.0.0/16"),
   165  				Check: resource.ComposeTestCheckFunc(
   166  					testAccCheckCloudFormationStackExists("aws_cloudformation_stack.with-url-and-params", &stack),
   167  				),
   168  			},
   169  		},
   170  	})
   171  }
   172  
   173  func TestAccAWSCloudFormation_withUrl_withParams_withYaml(t *testing.T) {
   174  	var stack cloudformation.Stack
   175  	rName := fmt.Sprintf("tf-acc-test-with-params-and-yaml-%s", acctest.RandString(10))
   176  
   177  	resource.Test(t, resource.TestCase{
   178  		PreCheck:     func() { testAccPreCheck(t) },
   179  		Providers:    testAccProviders,
   180  		CheckDestroy: testAccCheckAWSCloudFormationDestroy,
   181  		Steps: []resource.TestStep{
   182  			{
   183  				Config: testAccAWSCloudFormationConfig_templateUrl_withParams_withYaml(rName, "tf-cf-stack.yaml", "13.0.0.0/16"),
   184  				Check: resource.ComposeTestCheckFunc(
   185  					testAccCheckCloudFormationStackExists("aws_cloudformation_stack.with-url-and-params-and-yaml", &stack),
   186  				),
   187  			},
   188  		},
   189  	})
   190  }
   191  
   192  // Test for https://github.com/hashicorp/terraform/issues/5653
   193  func TestAccAWSCloudFormation_withUrl_withParams_noUpdate(t *testing.T) {
   194  	var stack cloudformation.Stack
   195  	rName := fmt.Sprintf("tf-acc-test-with-params-no-update-%s", acctest.RandString(10))
   196  
   197  	resource.Test(t, resource.TestCase{
   198  		PreCheck:     func() { testAccPreCheck(t) },
   199  		Providers:    testAccProviders,
   200  		CheckDestroy: testAccCheckAWSCloudFormationDestroy,
   201  		Steps: []resource.TestStep{
   202  			{
   203  				Config: testAccAWSCloudFormationConfig_templateUrl_withParams(rName, "tf-cf-stack-1.json", "11.0.0.0/16"),
   204  				Check: resource.ComposeTestCheckFunc(
   205  					testAccCheckCloudFormationStackExists("aws_cloudformation_stack.with-url-and-params", &stack),
   206  				),
   207  			},
   208  			{
   209  				Config: testAccAWSCloudFormationConfig_templateUrl_withParams(rName, "tf-cf-stack-2.json", "11.0.0.0/16"),
   210  				Check: resource.ComposeTestCheckFunc(
   211  					testAccCheckCloudFormationStackExists("aws_cloudformation_stack.with-url-and-params", &stack),
   212  				),
   213  			},
   214  		},
   215  	})
   216  }
   217  
   218  func testAccCheckCloudFormationStackExists(n string, stack *cloudformation.Stack) resource.TestCheckFunc {
   219  	return func(s *terraform.State) error {
   220  		rs, ok := s.RootModule().Resources[n]
   221  		if !ok {
   222  			return fmt.Errorf("Not found: %s", n)
   223  		}
   224  
   225  		conn := testAccProvider.Meta().(*AWSClient).cfconn
   226  		params := &cloudformation.DescribeStacksInput{
   227  			StackName: aws.String(rs.Primary.ID),
   228  		}
   229  		resp, err := conn.DescribeStacks(params)
   230  		if err != nil {
   231  			return err
   232  		}
   233  		if len(resp.Stacks) == 0 {
   234  			return fmt.Errorf("CloudFormation stack not found")
   235  		}
   236  
   237  		return nil
   238  	}
   239  }
   240  
   241  func testAccCheckAWSCloudFormationDestroy(s *terraform.State) error {
   242  	conn := testAccProvider.Meta().(*AWSClient).cfconn
   243  
   244  	for _, rs := range s.RootModule().Resources {
   245  		if rs.Type != "aws_cloudformation_stack" {
   246  			continue
   247  		}
   248  
   249  		params := cloudformation.DescribeStacksInput{
   250  			StackName: aws.String(rs.Primary.ID),
   251  		}
   252  
   253  		resp, err := conn.DescribeStacks(&params)
   254  
   255  		if err != nil {
   256  			return err
   257  		}
   258  
   259  		for _, s := range resp.Stacks {
   260  			if *s.StackId == rs.Primary.ID && *s.StackStatus != "DELETE_COMPLETE" {
   261  				return fmt.Errorf("CloudFormation stack still exists: %q", rs.Primary.ID)
   262  			}
   263  		}
   264  	}
   265  
   266  	return nil
   267  }
   268  
   269  func testAccAWSCloudFormationConfig(stackName string) string {
   270  	return fmt.Sprintf(`
   271  resource "aws_cloudformation_stack" "network" {
   272    name = "%s"
   273    template_body = <<STACK
   274  {
   275    "Resources" : {
   276      "MyVPC": {
   277        "Type" : "AWS::EC2::VPC",
   278        "Properties" : {
   279          "CidrBlock" : "10.0.0.0/16",
   280          "Tags" : [
   281            {"Key": "Name", "Value": "Primary_CF_VPC"}
   282          ]
   283        }
   284      }
   285    },
   286    "Outputs" : {
   287      "DefaultSgId" : {
   288        "Description": "The ID of default security group",
   289        "Value" : { "Fn::GetAtt" : [ "MyVPC", "DefaultSecurityGroup" ]}
   290      },
   291      "VpcID" : {
   292        "Description": "The VPC ID",
   293        "Value" : { "Ref" : "MyVPC" }
   294      }
   295    }
   296  }
   297  STACK
   298  }`, stackName)
   299  }
   300  
   301  func testAccAWSCloudFormationConfig_yaml(stackName string) string {
   302  	return fmt.Sprintf(`
   303  resource "aws_cloudformation_stack" "yaml" {
   304    name = "%s"
   305    template_body = <<STACK
   306  Resources:
   307    MyVPC:
   308      Type: AWS::EC2::VPC
   309      Properties:
   310        CidrBlock: 10.0.0.0/16
   311        Tags:
   312          -
   313            Key: Name
   314            Value: Primary_CF_VPC
   315  
   316  Outputs:
   317    DefaultSgId:
   318      Description: The ID of default security group
   319      Value: !GetAtt MyVPC.DefaultSecurityGroup
   320    VpcID:
   321      Description: The VPC ID
   322      Value: !Ref MyVPC
   323  STACK
   324  }`, stackName)
   325  }
   326  
   327  func testAccAWSCloudFormationConfig_defaultParams(stackName string) string {
   328  	return fmt.Sprintf(`
   329  resource "aws_cloudformation_stack" "asg-demo" {
   330    name = "%s"
   331    template_body = <<BODY
   332  {
   333      "Parameters": {
   334          "TopicName": {
   335              "Type": "String"
   336          },
   337          "VPCCIDR": {
   338              "Type": "String",
   339              "Default": "10.10.0.0/16"
   340          }
   341      },
   342      "Resources": {
   343          "NotificationTopic": {
   344              "Type": "AWS::SNS::Topic",
   345              "Properties": {
   346                  "TopicName": {
   347                      "Ref": "TopicName"
   348                  }
   349              }
   350          },
   351          "MyVPC": {
   352              "Type": "AWS::EC2::VPC",
   353              "Properties": {
   354                  "CidrBlock": {
   355                      "Ref": "VPCCIDR"
   356                  },
   357                  "Tags": [
   358                      {
   359                          "Key": "Name",
   360                          "Value": "Primary_CF_VPC"
   361                      }
   362                  ]
   363              }
   364          }
   365      },
   366      "Outputs": {
   367          "VPCCIDR": {
   368              "Value": {
   369                  "Ref": "VPCCIDR"
   370              }
   371          }
   372      }
   373  }
   374  BODY
   375  
   376    parameters {
   377      TopicName = "ExampleTopic"
   378    }
   379  }
   380  `, stackName)
   381  }
   382  
   383  var testAccAWSCloudFormationConfig_allAttributesWithBodies_tpl = `
   384  resource "aws_cloudformation_stack" "full" {
   385    name = "%s"
   386    template_body = <<STACK
   387  {
   388    "Parameters" : {
   389      "VpcCIDR" : {
   390        "Description" : "CIDR to be used for the VPC",
   391        "Type" : "String"
   392      }
   393    },
   394    "Resources" : {
   395      "MyVPC": {
   396        "Type" : "AWS::EC2::VPC",
   397        "Properties" : {
   398          "CidrBlock" : {"Ref": "VpcCIDR"},
   399          "Tags" : [
   400            {"Key": "Name", "Value": "%s"}
   401          ]
   402        }
   403      },
   404      "StaticVPC": {
   405        "Type" : "AWS::EC2::VPC",
   406        "Properties" : {
   407          "CidrBlock" : {"Ref": "VpcCIDR"},
   408          "Tags" : [
   409            {"Key": "Name", "Value": "Static_CF_VPC"}
   410          ]
   411        }
   412      },
   413      "InstanceRole" : {
   414        "Type" : "AWS::IAM::Role",
   415        "Properties" : {
   416          "AssumeRolePolicyDocument": {
   417            "Version": "2012-10-17",
   418            "Statement": [ {
   419              "Effect": "Allow",
   420              "Principal": { "Service": "ec2.amazonaws.com" },
   421              "Action": "sts:AssumeRole"
   422            } ]
   423          },
   424          "Path" : "/",
   425          "Policies" : [ {
   426            "PolicyName": "terraformtest",
   427            "PolicyDocument": {
   428              "Version": "2012-10-17",
   429              "Statement": [ {
   430                "Effect": "Allow",
   431                "Action": [ "ec2:DescribeSnapshots" ],
   432                "Resource": [ "*" ]
   433              } ]
   434            }
   435          } ]
   436        }
   437      }
   438    }
   439  }
   440  STACK
   441    parameters {
   442      VpcCIDR = "10.0.0.0/16"
   443    }
   444  
   445    policy_body = <<POLICY
   446  %s
   447  POLICY
   448    capabilities = ["CAPABILITY_IAM"]
   449    notification_arns = ["${aws_sns_topic.cf-updates.arn}"]
   450    on_failure = "DELETE"
   451    timeout_in_minutes = 10
   452    tags {
   453      First = "Mickey"
   454      Second = "Mouse"
   455    }
   456  }
   457  
   458  resource "aws_sns_topic" "cf-updates" {
   459    name = "tf-cf-notifications"
   460  }
   461  `
   462  
   463  var policyBody = `
   464  {
   465    "Statement" : [
   466      {
   467        "Effect" : "Deny",
   468        "Action" : "Update:*",
   469        "Principal": "*",
   470        "Resource" : "LogicalResourceId/StaticVPC"
   471      },
   472      {
   473        "Effect" : "Allow",
   474        "Action" : "Update:*",
   475        "Principal": "*",
   476        "Resource" : "*"
   477      }
   478    ]
   479  }
   480  `
   481  
   482  func testAccAWSCloudFormationConfig_allAttributesWithBodies(stackName string) string {
   483  	return fmt.Sprintf(
   484  		testAccAWSCloudFormationConfig_allAttributesWithBodies_tpl,
   485  		stackName,
   486  		"Primary_CF_VPC",
   487  		policyBody)
   488  }
   489  
   490  func testAccAWSCloudFormationConfig_allAttributesWithBodies_modified(stackName string) string {
   491  	return fmt.Sprintf(
   492  		testAccAWSCloudFormationConfig_allAttributesWithBodies_tpl,
   493  		stackName,
   494  		"Primary_CloudFormation_VPC",
   495  		policyBody)
   496  }
   497  
   498  var tpl_testAccAWSCloudFormationConfig_withParams = `
   499  resource "aws_cloudformation_stack" "with_params" {
   500    name = "%s"
   501    parameters {
   502      VpcCIDR = "%s"
   503    }
   504    template_body = <<STACK
   505  {
   506    "Parameters" : {
   507      "VpcCIDR" : {
   508        "Description" : "CIDR to be used for the VPC",
   509        "Type" : "String"
   510      }
   511    },
   512    "Resources" : {
   513      "MyVPC": {
   514        "Type" : "AWS::EC2::VPC",
   515        "Properties" : {
   516          "CidrBlock" : {"Ref": "VpcCIDR"},
   517          "Tags" : [
   518            {"Key": "Name", "Value": "Primary_CF_VPC"}
   519          ]
   520        }
   521      }
   522    }
   523  }
   524  STACK
   525  
   526    on_failure = "DELETE"
   527    timeout_in_minutes = 1
   528  }
   529  `
   530  
   531  func testAccAWSCloudFormationConfig_withParams(stackName string) string {
   532  	return fmt.Sprintf(
   533  		tpl_testAccAWSCloudFormationConfig_withParams,
   534  		stackName,
   535  		"10.0.0.0/16")
   536  }
   537  
   538  func testAccAWSCloudFormationConfig_withParams_modified(stackName string) string {
   539  	return fmt.Sprintf(
   540  		tpl_testAccAWSCloudFormationConfig_withParams,
   541  		stackName,
   542  		"12.0.0.0/16")
   543  }
   544  
   545  func testAccAWSCloudFormationConfig_templateUrl_withParams(rName, bucketKey, vpcCidr string) string {
   546  	return fmt.Sprintf(`
   547  resource "aws_s3_bucket" "b" {
   548    bucket = "%s"
   549    acl = "public-read"
   550    policy = <<POLICY
   551  {
   552    "Version":"2008-10-17",
   553    "Statement": [
   554      {
   555        "Sid":"AllowPublicRead",
   556        "Effect":"Allow",
   557        "Principal": {
   558          "AWS": "*"
   559        },
   560        "Action": "s3:GetObject",
   561        "Resource": "arn:aws:s3:::%s/*"
   562      }
   563    ]
   564  }
   565  POLICY
   566  
   567    website {
   568        index_document = "index.html"
   569        error_document = "error.html"
   570    }
   571  }
   572  
   573  resource "aws_s3_bucket_object" "object" {
   574    bucket = "${aws_s3_bucket.b.id}"
   575    key = "%s"
   576    source = "test-fixtures/cloudformation-template.json"
   577  }
   578  
   579  resource "aws_cloudformation_stack" "with-url-and-params" {
   580    name = "%s"
   581    parameters {
   582      VpcCIDR = "%s"
   583    }
   584    template_url = "https://${aws_s3_bucket.b.id}.s3-us-west-2.amazonaws.com/${aws_s3_bucket_object.object.key}"
   585    on_failure = "DELETE"
   586    timeout_in_minutes = 1
   587  }
   588  `, rName, rName, bucketKey, rName, vpcCidr)
   589  }
   590  
   591  func testAccAWSCloudFormationConfig_templateUrl_withParams_withYaml(rName, bucketKey, vpcCidr string) string {
   592  	return fmt.Sprintf(`
   593  resource "aws_s3_bucket" "b" {
   594    bucket = "%s"
   595    acl = "public-read"
   596    policy = <<POLICY
   597  {
   598    "Version":"2008-10-17",
   599    "Statement": [
   600      {
   601        "Sid":"AllowPublicRead",
   602        "Effect":"Allow",
   603        "Principal": {
   604          "AWS": "*"
   605        },
   606        "Action": "s3:GetObject",
   607        "Resource": "arn:aws:s3:::%s/*"
   608      }
   609    ]
   610  }
   611  POLICY
   612  
   613    website {
   614        index_document = "index.html"
   615        error_document = "error.html"
   616    }
   617  }
   618  
   619  resource "aws_s3_bucket_object" "object" {
   620    bucket = "${aws_s3_bucket.b.id}"
   621    key = "%s"
   622    source = "test-fixtures/cloudformation-template.yaml"
   623  }
   624  
   625  resource "aws_cloudformation_stack" "with-url-and-params-and-yaml" {
   626    name = "%s"
   627    parameters {
   628      VpcCIDR = "%s"
   629    }
   630    template_url = "https://${aws_s3_bucket.b.id}.s3-us-west-2.amazonaws.com/${aws_s3_bucket_object.object.key}"
   631    on_failure = "DELETE"
   632    timeout_in_minutes = 1
   633  }
   634  `, rName, rName, bucketKey, rName, vpcCidr)
   635  }