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