github.com/vtorhonen/terraform@v0.9.0-beta2.0.20170307220345-5d894e4ffda7/builtin/providers/aws/resource_aws_s3_bucket_test.go (about)

     1  package aws
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"reflect"
     7  	"regexp"
     8  	"strconv"
     9  	"testing"
    10  
    11  	"github.com/hashicorp/terraform/helper/acctest"
    12  	"github.com/hashicorp/terraform/helper/resource"
    13  	"github.com/hashicorp/terraform/terraform"
    14  
    15  	"strings"
    16  
    17  	"github.com/aws/aws-sdk-go/aws"
    18  	"github.com/aws/aws-sdk-go/aws/awserr"
    19  	"github.com/aws/aws-sdk-go/service/s3"
    20  	"github.com/hashicorp/terraform/helper/schema"
    21  )
    22  
    23  func TestAccAWSS3Bucket_basic(t *testing.T) {
    24  	rInt := acctest.RandInt()
    25  	arnRegexp := regexp.MustCompile(
    26  		"^arn:aws:s3:::")
    27  
    28  	resource.Test(t, resource.TestCase{
    29  		PreCheck: func() { testAccPreCheck(t) },
    30  		/*
    31  			IDRefreshName:   "aws_s3_bucket.bucket",
    32  			IDRefreshIgnore: []string{"force_destroy"},
    33  		*/
    34  		Providers:    testAccProviders,
    35  		CheckDestroy: testAccCheckAWSS3BucketDestroy,
    36  		Steps: []resource.TestStep{
    37  			{
    38  				Config: testAccAWSS3BucketConfig(rInt),
    39  				Check: resource.ComposeTestCheckFunc(
    40  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
    41  					resource.TestCheckResourceAttr(
    42  						"aws_s3_bucket.bucket", "hosted_zone_id", HostedZoneIDForRegion("us-west-2")),
    43  					resource.TestCheckResourceAttr(
    44  						"aws_s3_bucket.bucket", "region", "us-west-2"),
    45  					resource.TestCheckNoResourceAttr(
    46  						"aws_s3_bucket.bucket", "website_endpoint"),
    47  					resource.TestMatchResourceAttr(
    48  						"aws_s3_bucket.bucket", "arn", arnRegexp),
    49  					resource.TestCheckResourceAttr(
    50  						"aws_s3_bucket.bucket", "bucket", testAccBucketName(rInt)),
    51  					resource.TestCheckResourceAttr(
    52  						"aws_s3_bucket.bucket", "bucket_domain_name", testAccBucketDomainName(rInt)),
    53  				),
    54  			},
    55  		},
    56  	})
    57  }
    58  
    59  func TestAccAWSS3Bucket_region(t *testing.T) {
    60  	rInt := acctest.RandInt()
    61  
    62  	resource.Test(t, resource.TestCase{
    63  		PreCheck:     func() { testAccPreCheck(t) },
    64  		Providers:    testAccProviders,
    65  		CheckDestroy: testAccCheckAWSS3BucketDestroy,
    66  		Steps: []resource.TestStep{
    67  			{
    68  				Config: testAccAWSS3BucketConfigWithRegion(rInt),
    69  				Check: resource.ComposeTestCheckFunc(
    70  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
    71  					resource.TestCheckResourceAttr("aws_s3_bucket.bucket", "region", "eu-west-1"),
    72  				),
    73  			},
    74  		},
    75  	})
    76  }
    77  
    78  func TestAccAWSS3Bucket_acceleration(t *testing.T) {
    79  	rInt := acctest.RandInt()
    80  
    81  	resource.Test(t, resource.TestCase{
    82  		PreCheck:     func() { testAccPreCheck(t) },
    83  		Providers:    testAccProviders,
    84  		CheckDestroy: testAccCheckAWSS3BucketDestroy,
    85  		Steps: []resource.TestStep{
    86  			{
    87  				Config: testAccAWSS3BucketConfigWithAcceleration(rInt),
    88  				Check: resource.ComposeTestCheckFunc(
    89  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
    90  					resource.TestCheckResourceAttr(
    91  						"aws_s3_bucket.bucket", "acceleration_status", "Enabled"),
    92  				),
    93  			},
    94  			{
    95  				Config: testAccAWSS3BucketConfigWithoutAcceleration(rInt),
    96  				Check: resource.ComposeTestCheckFunc(
    97  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
    98  					resource.TestCheckResourceAttr(
    99  						"aws_s3_bucket.bucket", "acceleration_status", "Suspended"),
   100  				),
   101  			},
   102  		},
   103  	})
   104  }
   105  
   106  func TestAccAWSS3Bucket_RequestPayer(t *testing.T) {
   107  	rInt := acctest.RandInt()
   108  
   109  	resource.Test(t, resource.TestCase{
   110  		PreCheck:     func() { testAccPreCheck(t) },
   111  		Providers:    testAccProviders,
   112  		CheckDestroy: testAccCheckAWSS3BucketDestroy,
   113  		Steps: []resource.TestStep{
   114  			{
   115  				Config: testAccAWSS3BucketConfigRequestPayerBucketOwner(rInt),
   116  				Check: resource.ComposeTestCheckFunc(
   117  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
   118  					resource.TestCheckResourceAttr(
   119  						"aws_s3_bucket.bucket",
   120  						"request_payer",
   121  						"BucketOwner"),
   122  					testAccCheckAWSS3RequestPayer(
   123  						"aws_s3_bucket.bucket",
   124  						"BucketOwner"),
   125  				),
   126  			},
   127  			{
   128  				Config: testAccAWSS3BucketConfigRequestPayerRequester(rInt),
   129  				Check: resource.ComposeTestCheckFunc(
   130  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
   131  					resource.TestCheckResourceAttr(
   132  						"aws_s3_bucket.bucket",
   133  						"request_payer",
   134  						"Requester"),
   135  					testAccCheckAWSS3RequestPayer(
   136  						"aws_s3_bucket.bucket",
   137  						"Requester"),
   138  				),
   139  			},
   140  		},
   141  	})
   142  }
   143  
   144  func TestResourceAWSS3BucketRequestPayer_validation(t *testing.T) {
   145  	_, errors := validateS3BucketRequestPayerType("incorrect", "request_payer")
   146  	if len(errors) == 0 {
   147  		t.Fatalf("Expected to trigger a validation error")
   148  	}
   149  
   150  	var testCases = []struct {
   151  		Value    string
   152  		ErrCount int
   153  	}{
   154  		{
   155  			Value:    "Requester",
   156  			ErrCount: 0,
   157  		},
   158  		{
   159  			Value:    "BucketOwner",
   160  			ErrCount: 0,
   161  		},
   162  	}
   163  
   164  	for _, tc := range testCases {
   165  		_, errors := validateS3BucketRequestPayerType(tc.Value, "request_payer")
   166  		if len(errors) != tc.ErrCount {
   167  			t.Fatalf("Expected not to trigger a validation error")
   168  		}
   169  	}
   170  }
   171  
   172  func TestAccAWSS3Bucket_Policy(t *testing.T) {
   173  	rInt := acctest.RandInt()
   174  
   175  	resource.Test(t, resource.TestCase{
   176  		PreCheck:     func() { testAccPreCheck(t) },
   177  		Providers:    testAccProviders,
   178  		CheckDestroy: testAccCheckAWSS3BucketDestroy,
   179  		Steps: []resource.TestStep{
   180  			{
   181  				Config: testAccAWSS3BucketConfigWithPolicy(rInt),
   182  				Check: resource.ComposeTestCheckFunc(
   183  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
   184  					testAccCheckAWSS3BucketPolicy(
   185  						"aws_s3_bucket.bucket", testAccAWSS3BucketPolicy(rInt)),
   186  				),
   187  			},
   188  			{
   189  				Config: testAccAWSS3BucketConfig(rInt),
   190  				Check: resource.ComposeTestCheckFunc(
   191  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
   192  					testAccCheckAWSS3BucketPolicy(
   193  						"aws_s3_bucket.bucket", ""),
   194  				),
   195  			},
   196  			{
   197  				Config: testAccAWSS3BucketConfigWithEmptyPolicy(rInt),
   198  				Check: resource.ComposeTestCheckFunc(
   199  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
   200  					testAccCheckAWSS3BucketPolicy(
   201  						"aws_s3_bucket.bucket", ""),
   202  				),
   203  			},
   204  		},
   205  	})
   206  }
   207  
   208  func TestAccAWSS3Bucket_UpdateAcl(t *testing.T) {
   209  	ri := acctest.RandInt()
   210  	preConfig := fmt.Sprintf(testAccAWSS3BucketConfigWithAcl, ri)
   211  	postConfig := fmt.Sprintf(testAccAWSS3BucketConfigWithAclUpdate, ri)
   212  
   213  	resource.Test(t, resource.TestCase{
   214  		PreCheck:     func() { testAccPreCheck(t) },
   215  		Providers:    testAccProviders,
   216  		CheckDestroy: testAccCheckAWSS3BucketDestroy,
   217  		Steps: []resource.TestStep{
   218  			{
   219  				Config: preConfig,
   220  				Check: resource.ComposeTestCheckFunc(
   221  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
   222  					resource.TestCheckResourceAttr(
   223  						"aws_s3_bucket.bucket", "acl", "public-read"),
   224  				),
   225  			},
   226  			{
   227  				Config: postConfig,
   228  				Check: resource.ComposeTestCheckFunc(
   229  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
   230  					resource.TestCheckResourceAttr(
   231  						"aws_s3_bucket.bucket", "acl", "private"),
   232  				),
   233  			},
   234  		},
   235  	})
   236  }
   237  
   238  func TestAccAWSS3Bucket_Website_Simple(t *testing.T) {
   239  	rInt := acctest.RandInt()
   240  	resource.Test(t, resource.TestCase{
   241  		PreCheck:     func() { testAccPreCheck(t) },
   242  		Providers:    testAccProviders,
   243  		CheckDestroy: testAccCheckAWSS3BucketDestroy,
   244  		Steps: []resource.TestStep{
   245  			{
   246  				Config: testAccAWSS3BucketWebsiteConfig(rInt),
   247  				Check: resource.ComposeTestCheckFunc(
   248  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
   249  					testAccCheckAWSS3BucketWebsite(
   250  						"aws_s3_bucket.bucket", "index.html", "", "", ""),
   251  					resource.TestCheckResourceAttr(
   252  						"aws_s3_bucket.bucket", "website_endpoint", testAccWebsiteEndpoint(rInt)),
   253  				),
   254  			},
   255  			{
   256  				Config: testAccAWSS3BucketWebsiteConfigWithError(rInt),
   257  				Check: resource.ComposeTestCheckFunc(
   258  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
   259  					testAccCheckAWSS3BucketWebsite(
   260  						"aws_s3_bucket.bucket", "index.html", "error.html", "", ""),
   261  					resource.TestCheckResourceAttr(
   262  						"aws_s3_bucket.bucket", "website_endpoint", testAccWebsiteEndpoint(rInt)),
   263  				),
   264  			},
   265  			{
   266  				Config: testAccAWSS3BucketConfig(rInt),
   267  				Check: resource.ComposeTestCheckFunc(
   268  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
   269  					testAccCheckAWSS3BucketWebsite(
   270  						"aws_s3_bucket.bucket", "", "", "", ""),
   271  					resource.TestCheckResourceAttr(
   272  						"aws_s3_bucket.bucket", "website_endpoint", ""),
   273  				),
   274  			},
   275  		},
   276  	})
   277  }
   278  
   279  func TestAccAWSS3Bucket_WebsiteRedirect(t *testing.T) {
   280  	rInt := acctest.RandInt()
   281  	resource.Test(t, resource.TestCase{
   282  		PreCheck:     func() { testAccPreCheck(t) },
   283  		Providers:    testAccProviders,
   284  		CheckDestroy: testAccCheckAWSS3BucketDestroy,
   285  		Steps: []resource.TestStep{
   286  			{
   287  				Config: testAccAWSS3BucketWebsiteConfigWithRedirect(rInt),
   288  				Check: resource.ComposeTestCheckFunc(
   289  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
   290  					testAccCheckAWSS3BucketWebsite(
   291  						"aws_s3_bucket.bucket", "", "", "", "hashicorp.com"),
   292  					resource.TestCheckResourceAttr(
   293  						"aws_s3_bucket.bucket", "website_endpoint", testAccWebsiteEndpoint(rInt)),
   294  				),
   295  			},
   296  			{
   297  				Config: testAccAWSS3BucketWebsiteConfigWithHttpsRedirect(rInt),
   298  				Check: resource.ComposeTestCheckFunc(
   299  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
   300  					testAccCheckAWSS3BucketWebsite(
   301  						"aws_s3_bucket.bucket", "", "", "https", "hashicorp.com"),
   302  					resource.TestCheckResourceAttr(
   303  						"aws_s3_bucket.bucket", "website_endpoint", testAccWebsiteEndpoint(rInt)),
   304  				),
   305  			},
   306  			{
   307  				Config: testAccAWSS3BucketConfig(rInt),
   308  				Check: resource.ComposeTestCheckFunc(
   309  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
   310  					testAccCheckAWSS3BucketWebsite(
   311  						"aws_s3_bucket.bucket", "", "", "", ""),
   312  					resource.TestCheckResourceAttr(
   313  						"aws_s3_bucket.bucket", "website_endpoint", ""),
   314  				),
   315  			},
   316  		},
   317  	})
   318  }
   319  
   320  func TestAccAWSS3Bucket_WebsiteRoutingRules(t *testing.T) {
   321  	rInt := acctest.RandInt()
   322  	resource.Test(t, resource.TestCase{
   323  		PreCheck:     func() { testAccPreCheck(t) },
   324  		Providers:    testAccProviders,
   325  		CheckDestroy: testAccCheckAWSS3BucketDestroy,
   326  		Steps: []resource.TestStep{
   327  			{
   328  				Config: testAccAWSS3BucketWebsiteConfigWithRoutingRules(rInt),
   329  				Check: resource.ComposeTestCheckFunc(
   330  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
   331  					testAccCheckAWSS3BucketWebsite(
   332  						"aws_s3_bucket.bucket", "index.html", "error.html", "", ""),
   333  					testAccCheckAWSS3BucketWebsiteRoutingRules(
   334  						"aws_s3_bucket.bucket",
   335  						[]*s3.RoutingRule{
   336  							{
   337  								Condition: &s3.Condition{
   338  									KeyPrefixEquals: aws.String("docs/"),
   339  								},
   340  								Redirect: &s3.Redirect{
   341  									ReplaceKeyPrefixWith: aws.String("documents/"),
   342  								},
   343  							},
   344  						},
   345  					),
   346  					resource.TestCheckResourceAttr(
   347  						"aws_s3_bucket.bucket", "website_endpoint", testAccWebsiteEndpoint(rInt)),
   348  				),
   349  			},
   350  			{
   351  				Config: testAccAWSS3BucketConfig(rInt),
   352  				Check: resource.ComposeTestCheckFunc(
   353  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
   354  					testAccCheckAWSS3BucketWebsite(
   355  						"aws_s3_bucket.bucket", "", "", "", ""),
   356  					testAccCheckAWSS3BucketWebsiteRoutingRules("aws_s3_bucket.bucket", nil),
   357  					resource.TestCheckResourceAttr(
   358  						"aws_s3_bucket.bucket", "website_endpoint", ""),
   359  				),
   360  			},
   361  		},
   362  	})
   363  }
   364  
   365  // Test TestAccAWSS3Bucket_shouldFailNotFound is designed to fail with a "plan
   366  // not empty" error in Terraform, to check against regresssions.
   367  // See https://github.com/hashicorp/terraform/pull/2925
   368  func TestAccAWSS3Bucket_shouldFailNotFound(t *testing.T) {
   369  	rInt := acctest.RandInt()
   370  	resource.Test(t, resource.TestCase{
   371  		PreCheck:     func() { testAccPreCheck(t) },
   372  		Providers:    testAccProviders,
   373  		CheckDestroy: testAccCheckAWSS3BucketDestroy,
   374  		Steps: []resource.TestStep{
   375  			{
   376  				Config: testAccAWSS3BucketDestroyedConfig(rInt),
   377  				Check: resource.ComposeTestCheckFunc(
   378  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
   379  					testAccCheckAWSS3DestroyBucket("aws_s3_bucket.bucket"),
   380  				),
   381  				ExpectNonEmptyPlan: true,
   382  			},
   383  		},
   384  	})
   385  }
   386  
   387  func TestAccAWSS3Bucket_Versioning(t *testing.T) {
   388  	rInt := acctest.RandInt()
   389  	resource.Test(t, resource.TestCase{
   390  		PreCheck:     func() { testAccPreCheck(t) },
   391  		Providers:    testAccProviders,
   392  		CheckDestroy: testAccCheckAWSS3BucketDestroy,
   393  		Steps: []resource.TestStep{
   394  			{
   395  				Config: testAccAWSS3BucketConfig(rInt),
   396  				Check: resource.ComposeTestCheckFunc(
   397  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
   398  					testAccCheckAWSS3BucketVersioning(
   399  						"aws_s3_bucket.bucket", ""),
   400  				),
   401  			},
   402  			{
   403  				Config: testAccAWSS3BucketConfigWithVersioning(rInt),
   404  				Check: resource.ComposeTestCheckFunc(
   405  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
   406  					testAccCheckAWSS3BucketVersioning(
   407  						"aws_s3_bucket.bucket", s3.BucketVersioningStatusEnabled),
   408  				),
   409  			},
   410  			{
   411  				Config: testAccAWSS3BucketConfigWithDisableVersioning(rInt),
   412  				Check: resource.ComposeTestCheckFunc(
   413  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
   414  					testAccCheckAWSS3BucketVersioning(
   415  						"aws_s3_bucket.bucket", s3.BucketVersioningStatusSuspended),
   416  				),
   417  			},
   418  		},
   419  	})
   420  }
   421  
   422  func TestAccAWSS3Bucket_Cors(t *testing.T) {
   423  	rInt := acctest.RandInt()
   424  
   425  	updateBucketCors := func(n string) resource.TestCheckFunc {
   426  		return func(s *terraform.State) error {
   427  			rs, ok := s.RootModule().Resources[n]
   428  			if !ok {
   429  				return fmt.Errorf("Not found: %s", n)
   430  			}
   431  
   432  			conn := testAccProvider.Meta().(*AWSClient).s3conn
   433  			_, err := conn.PutBucketCors(&s3.PutBucketCorsInput{
   434  				Bucket: aws.String(rs.Primary.ID),
   435  				CORSConfiguration: &s3.CORSConfiguration{
   436  					CORSRules: []*s3.CORSRule{
   437  						{
   438  							AllowedHeaders: []*string{aws.String("*")},
   439  							AllowedMethods: []*string{aws.String("GET")},
   440  							AllowedOrigins: []*string{aws.String("https://www.example.com")},
   441  						},
   442  					},
   443  				},
   444  			})
   445  			if err != nil {
   446  				if awsErr, ok := err.(awserr.Error); ok && awsErr.Code() != "NoSuchCORSConfiguration" {
   447  					return err
   448  				}
   449  			}
   450  			return nil
   451  		}
   452  	}
   453  
   454  	resource.Test(t, resource.TestCase{
   455  		PreCheck:     func() { testAccPreCheck(t) },
   456  		Providers:    testAccProviders,
   457  		CheckDestroy: testAccCheckAWSS3BucketDestroy,
   458  		Steps: []resource.TestStep{
   459  			{
   460  				Config: testAccAWSS3BucketConfigWithCORS(rInt),
   461  				Check: resource.ComposeTestCheckFunc(
   462  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
   463  					testAccCheckAWSS3BucketCors(
   464  						"aws_s3_bucket.bucket",
   465  						[]*s3.CORSRule{
   466  							{
   467  								AllowedHeaders: []*string{aws.String("*")},
   468  								AllowedMethods: []*string{aws.String("PUT"), aws.String("POST")},
   469  								AllowedOrigins: []*string{aws.String("https://www.example.com")},
   470  								ExposeHeaders:  []*string{aws.String("x-amz-server-side-encryption"), aws.String("ETag")},
   471  								MaxAgeSeconds:  aws.Int64(3000),
   472  							},
   473  						},
   474  					),
   475  					updateBucketCors("aws_s3_bucket.bucket"),
   476  				),
   477  				ExpectNonEmptyPlan: true,
   478  			},
   479  			{
   480  				Config: testAccAWSS3BucketConfigWithCORS(rInt),
   481  				Check: resource.ComposeTestCheckFunc(
   482  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
   483  					testAccCheckAWSS3BucketCors(
   484  						"aws_s3_bucket.bucket",
   485  						[]*s3.CORSRule{
   486  							{
   487  								AllowedHeaders: []*string{aws.String("*")},
   488  								AllowedMethods: []*string{aws.String("PUT"), aws.String("POST")},
   489  								AllowedOrigins: []*string{aws.String("https://www.example.com")},
   490  								ExposeHeaders:  []*string{aws.String("x-amz-server-side-encryption"), aws.String("ETag")},
   491  								MaxAgeSeconds:  aws.Int64(3000),
   492  							},
   493  						},
   494  					),
   495  				),
   496  			},
   497  		},
   498  	})
   499  }
   500  
   501  func TestAccAWSS3Bucket_Logging(t *testing.T) {
   502  	rInt := acctest.RandInt()
   503  	resource.Test(t, resource.TestCase{
   504  		PreCheck:     func() { testAccPreCheck(t) },
   505  		Providers:    testAccProviders,
   506  		CheckDestroy: testAccCheckAWSS3BucketDestroy,
   507  		Steps: []resource.TestStep{
   508  			{
   509  				Config: testAccAWSS3BucketConfigWithLogging(rInt),
   510  				Check: resource.ComposeTestCheckFunc(
   511  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
   512  					testAccCheckAWSS3BucketLogging(
   513  						"aws_s3_bucket.bucket", "aws_s3_bucket.log_bucket", "log/"),
   514  				),
   515  			},
   516  		},
   517  	})
   518  }
   519  
   520  func TestAccAWSS3Bucket_Lifecycle(t *testing.T) {
   521  	rInt := acctest.RandInt()
   522  	resource.Test(t, resource.TestCase{
   523  		PreCheck:     func() { testAccPreCheck(t) },
   524  		Providers:    testAccProviders,
   525  		CheckDestroy: testAccCheckAWSS3BucketDestroy,
   526  		Steps: []resource.TestStep{
   527  			{
   528  				Config: testAccAWSS3BucketConfigWithLifecycle(rInt),
   529  				Check: resource.ComposeTestCheckFunc(
   530  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
   531  					resource.TestCheckResourceAttr(
   532  						"aws_s3_bucket.bucket", "lifecycle_rule.0.id", "id1"),
   533  					resource.TestCheckResourceAttr(
   534  						"aws_s3_bucket.bucket", "lifecycle_rule.0.prefix", "path1/"),
   535  					resource.TestCheckResourceAttr(
   536  						"aws_s3_bucket.bucket", "lifecycle_rule.0.expiration.2613713285.days", "365"),
   537  					resource.TestCheckResourceAttr(
   538  						"aws_s3_bucket.bucket", "lifecycle_rule.0.expiration.2613713285.date", ""),
   539  					resource.TestCheckResourceAttr(
   540  						"aws_s3_bucket.bucket", "lifecycle_rule.0.expiration.2613713285.expired_object_delete_marker", "false"),
   541  					resource.TestCheckResourceAttr(
   542  						"aws_s3_bucket.bucket", "lifecycle_rule.0.transition.2000431762.date", ""),
   543  					resource.TestCheckResourceAttr(
   544  						"aws_s3_bucket.bucket", "lifecycle_rule.0.transition.2000431762.days", "30"),
   545  					resource.TestCheckResourceAttr(
   546  						"aws_s3_bucket.bucket", "lifecycle_rule.0.transition.2000431762.storage_class", "STANDARD_IA"),
   547  					resource.TestCheckResourceAttr(
   548  						"aws_s3_bucket.bucket", "lifecycle_rule.0.transition.6450812.date", ""),
   549  					resource.TestCheckResourceAttr(
   550  						"aws_s3_bucket.bucket", "lifecycle_rule.0.transition.6450812.days", "60"),
   551  					resource.TestCheckResourceAttr(
   552  						"aws_s3_bucket.bucket", "lifecycle_rule.0.transition.6450812.storage_class", "GLACIER"),
   553  					resource.TestCheckResourceAttr(
   554  						"aws_s3_bucket.bucket", "lifecycle_rule.1.id", "id2"),
   555  					resource.TestCheckResourceAttr(
   556  						"aws_s3_bucket.bucket", "lifecycle_rule.1.prefix", "path2/"),
   557  					resource.TestCheckResourceAttr(
   558  						"aws_s3_bucket.bucket", "lifecycle_rule.1.expiration.2855832418.date", "2016-01-12"),
   559  					resource.TestCheckResourceAttr(
   560  						"aws_s3_bucket.bucket", "lifecycle_rule.1.expiration.2855832418.days", "0"),
   561  					resource.TestCheckResourceAttr(
   562  						"aws_s3_bucket.bucket", "lifecycle_rule.1.expiration.2855832418.expired_object_delete_marker", "false"),
   563  				),
   564  			},
   565  			{
   566  				Config: testAccAWSS3BucketConfigWithVersioningLifecycle(rInt),
   567  				Check: resource.ComposeTestCheckFunc(
   568  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
   569  					resource.TestCheckResourceAttr(
   570  						"aws_s3_bucket.bucket", "lifecycle_rule.0.id", "id1"),
   571  					resource.TestCheckResourceAttr(
   572  						"aws_s3_bucket.bucket", "lifecycle_rule.0.prefix", "path1/"),
   573  					resource.TestCheckResourceAttr(
   574  						"aws_s3_bucket.bucket", "lifecycle_rule.0.enabled", "true"),
   575  					resource.TestCheckResourceAttr(
   576  						"aws_s3_bucket.bucket", "lifecycle_rule.0.noncurrent_version_expiration.80908210.days", "365"),
   577  					resource.TestCheckResourceAttr(
   578  						"aws_s3_bucket.bucket", "lifecycle_rule.0.noncurrent_version_transition.1377917700.days", "30"),
   579  					resource.TestCheckResourceAttr(
   580  						"aws_s3_bucket.bucket", "lifecycle_rule.0.noncurrent_version_transition.1377917700.storage_class", "STANDARD_IA"),
   581  					resource.TestCheckResourceAttr(
   582  						"aws_s3_bucket.bucket", "lifecycle_rule.0.noncurrent_version_transition.2528035817.days", "60"),
   583  					resource.TestCheckResourceAttr(
   584  						"aws_s3_bucket.bucket", "lifecycle_rule.0.noncurrent_version_transition.2528035817.storage_class", "GLACIER"),
   585  					resource.TestCheckResourceAttr(
   586  						"aws_s3_bucket.bucket", "lifecycle_rule.1.id", "id2"),
   587  					resource.TestCheckResourceAttr(
   588  						"aws_s3_bucket.bucket", "lifecycle_rule.1.prefix", "path2/"),
   589  					resource.TestCheckResourceAttr(
   590  						"aws_s3_bucket.bucket", "lifecycle_rule.1.enabled", "false"),
   591  					resource.TestCheckResourceAttr(
   592  						"aws_s3_bucket.bucket", "lifecycle_rule.1.noncurrent_version_expiration.80908210.days", "365"),
   593  				),
   594  			},
   595  			{
   596  				Config: testAccAWSS3BucketConfig(rInt),
   597  				Check: resource.ComposeTestCheckFunc(
   598  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
   599  				),
   600  			},
   601  		},
   602  	})
   603  }
   604  
   605  func TestAccAWSS3Bucket_Replication(t *testing.T) {
   606  	rInt := acctest.RandInt()
   607  
   608  	// record the initialized providers so that we can use them to check for the instances in each region
   609  	var providers []*schema.Provider
   610  	providerFactories := map[string]terraform.ResourceProviderFactory{
   611  		"aws": func() (terraform.ResourceProvider, error) {
   612  			p := Provider()
   613  			providers = append(providers, p.(*schema.Provider))
   614  			return p, nil
   615  		},
   616  	}
   617  
   618  	resource.Test(t, resource.TestCase{
   619  		PreCheck:          func() { testAccPreCheck(t) },
   620  		ProviderFactories: providerFactories,
   621  		CheckDestroy:      testAccCheckAWSS3BucketDestroyWithProviders(&providers),
   622  		Steps: []resource.TestStep{
   623  			{
   624  				Config: testAccAWSS3BucketConfigReplication(rInt),
   625  				Check: resource.ComposeTestCheckFunc(
   626  					testAccCheckAWSS3BucketExistsWithProviders("aws_s3_bucket.bucket", &providers),
   627  				),
   628  			},
   629  			{
   630  				Config: testAccAWSS3BucketConfigReplicationWithConfiguration(rInt),
   631  				Check: resource.ComposeTestCheckFunc(
   632  					testAccCheckAWSS3BucketExistsWithProviders("aws_s3_bucket.bucket", &providers),
   633  					resource.TestCheckResourceAttr("aws_s3_bucket.bucket", "replication_configuration.#", "1"),
   634  					resource.TestCheckResourceAttr("aws_s3_bucket.bucket", "replication_configuration.0.rules.#", "1"),
   635  					resource.TestCheckResourceAttr("aws_s3_bucket.bucket", "replication_configuration.0.rules.2229345141.id", "foobar"),
   636  					resource.TestCheckResourceAttr("aws_s3_bucket.bucket", "replication_configuration.0.rules.2229345141.prefix", "foo"),
   637  					resource.TestCheckResourceAttr("aws_s3_bucket.bucket", "replication_configuration.0.rules.2229345141.status", s3.ReplicationRuleStatusEnabled),
   638  				),
   639  			},
   640  		},
   641  	})
   642  }
   643  
   644  // StorageClass issue: https://github.com/hashicorp/terraform/issues/10909
   645  func TestAccAWSS3Bucket_ReplicationWithoutStorageClass(t *testing.T) {
   646  	rInt := acctest.RandInt()
   647  
   648  	// record the initialized providers so that we can use them to check for the instances in each region
   649  	var providers []*schema.Provider
   650  	providerFactories := map[string]terraform.ResourceProviderFactory{
   651  		"aws": func() (terraform.ResourceProvider, error) {
   652  			p := Provider()
   653  			providers = append(providers, p.(*schema.Provider))
   654  			return p, nil
   655  		},
   656  	}
   657  
   658  	resource.Test(t, resource.TestCase{
   659  		PreCheck:          func() { testAccPreCheck(t) },
   660  		ProviderFactories: providerFactories,
   661  		CheckDestroy:      testAccCheckAWSS3BucketDestroyWithProviders(&providers),
   662  		Steps: []resource.TestStep{
   663  			{
   664  				Config: testAccAWSS3BucketConfigReplicationWithoutStorageClass(rInt),
   665  				Check: resource.ComposeTestCheckFunc(
   666  					testAccCheckAWSS3BucketExistsWithProviders("aws_s3_bucket.bucket", &providers),
   667  				),
   668  			},
   669  		},
   670  	})
   671  }
   672  
   673  func TestAccAWSS3Bucket_ReplicationExpectVersioningValidationError(t *testing.T) {
   674  	rInt := acctest.RandInt()
   675  
   676  	// record the initialized providers so that we can use them to check for the instances in each region
   677  	var providers []*schema.Provider
   678  	providerFactories := map[string]terraform.ResourceProviderFactory{
   679  		"aws": func() (terraform.ResourceProvider, error) {
   680  			p := Provider()
   681  			providers = append(providers, p.(*schema.Provider))
   682  			return p, nil
   683  		},
   684  	}
   685  
   686  	resource.Test(t, resource.TestCase{
   687  		PreCheck:          func() { testAccPreCheck(t) },
   688  		ProviderFactories: providerFactories,
   689  		CheckDestroy:      testAccCheckAWSS3BucketDestroyWithProviders(&providers),
   690  		Steps: []resource.TestStep{
   691  			{
   692  				Config:      testAccAWSS3BucketConfigReplicationNoVersioning(rInt),
   693  				ExpectError: regexp.MustCompile(`versioning must be enabled to allow S3 bucket replication`),
   694  			},
   695  		},
   696  	})
   697  }
   698  
   699  func TestAWSS3BucketName(t *testing.T) {
   700  	validDnsNames := []string{
   701  		"foobar",
   702  		"foo.bar",
   703  		"foo.bar.baz",
   704  		"1234",
   705  		"foo-bar",
   706  		strings.Repeat("x", 63),
   707  	}
   708  
   709  	for _, v := range validDnsNames {
   710  		if err := validateS3BucketName(v, "us-west-2"); err != nil {
   711  			t.Fatalf("%q should be a valid S3 bucket name", v)
   712  		}
   713  	}
   714  
   715  	invalidDnsNames := []string{
   716  		"foo..bar",
   717  		"Foo.Bar",
   718  		"192.168.0.1",
   719  		"127.0.0.1",
   720  		".foo",
   721  		"bar.",
   722  		"foo_bar",
   723  		strings.Repeat("x", 64),
   724  	}
   725  
   726  	for _, v := range invalidDnsNames {
   727  		if err := validateS3BucketName(v, "us-west-2"); err == nil {
   728  			t.Fatalf("%q should not be a valid S3 bucket name", v)
   729  		}
   730  	}
   731  
   732  	validEastNames := []string{
   733  		"foobar",
   734  		"foo_bar",
   735  		"127.0.0.1",
   736  		"foo..bar",
   737  		"foo_bar_baz",
   738  		"foo.bar.baz",
   739  		"Foo.Bar",
   740  		strings.Repeat("x", 255),
   741  	}
   742  
   743  	for _, v := range validEastNames {
   744  		if err := validateS3BucketName(v, "us-east-1"); err != nil {
   745  			t.Fatalf("%q should be a valid S3 bucket name", v)
   746  		}
   747  	}
   748  
   749  	invalidEastNames := []string{
   750  		"foo;bar",
   751  		strings.Repeat("x", 256),
   752  	}
   753  
   754  	for _, v := range invalidEastNames {
   755  		if err := validateS3BucketName(v, "us-east-1"); err == nil {
   756  			t.Fatalf("%q should not be a valid S3 bucket name", v)
   757  		}
   758  	}
   759  }
   760  
   761  func testAccCheckAWSS3BucketDestroy(s *terraform.State) error {
   762  	return testAccCheckInstanceDestroyWithProvider(s, testAccProvider)
   763  }
   764  
   765  func testAccCheckAWSS3BucketDestroyWithProviders(providers *[]*schema.Provider) resource.TestCheckFunc {
   766  	return func(s *terraform.State) error {
   767  		for _, provider := range *providers {
   768  			if provider.Meta() == nil {
   769  				continue
   770  			}
   771  			if err := testAccCheckAWSS3BucketDestroyWithProvider(s, provider); err != nil {
   772  				return err
   773  			}
   774  		}
   775  		return nil
   776  	}
   777  }
   778  
   779  func testAccCheckAWSS3BucketDestroyWithProvider(s *terraform.State, provider *schema.Provider) error {
   780  	conn := provider.Meta().(*AWSClient).s3conn
   781  
   782  	for _, rs := range s.RootModule().Resources {
   783  		if rs.Type != "aws_s3_bucket" {
   784  			continue
   785  		}
   786  		_, err := conn.DeleteBucket(&s3.DeleteBucketInput{
   787  			Bucket: aws.String(rs.Primary.ID),
   788  		})
   789  		if err != nil {
   790  			if awsErr, ok := err.(awserr.Error); ok && awsErr.Code() == "NoSuchBucket" {
   791  				return nil
   792  			}
   793  			return err
   794  		}
   795  	}
   796  	return nil
   797  }
   798  
   799  func testAccCheckAWSS3BucketExists(n string) resource.TestCheckFunc {
   800  	providers := []*schema.Provider{testAccProvider}
   801  	return testAccCheckAWSS3BucketExistsWithProviders(n, &providers)
   802  }
   803  
   804  func testAccCheckAWSS3BucketExistsWithProviders(n string, providers *[]*schema.Provider) resource.TestCheckFunc {
   805  	return func(s *terraform.State) error {
   806  		rs, ok := s.RootModule().Resources[n]
   807  		if !ok {
   808  			return fmt.Errorf("Not found: %s", n)
   809  		}
   810  
   811  		if rs.Primary.ID == "" {
   812  			return fmt.Errorf("No ID is set")
   813  		}
   814  		for _, provider := range *providers {
   815  			// Ignore if Meta is empty, this can happen for validation providers
   816  			if provider.Meta() == nil {
   817  				continue
   818  			}
   819  
   820  			conn := provider.Meta().(*AWSClient).s3conn
   821  			_, err := conn.HeadBucket(&s3.HeadBucketInput{
   822  				Bucket: aws.String(rs.Primary.ID),
   823  			})
   824  
   825  			if err != nil {
   826  				return fmt.Errorf("S3Bucket error: %v", err)
   827  			}
   828  			return nil
   829  		}
   830  
   831  		return fmt.Errorf("Instance not found")
   832  	}
   833  }
   834  
   835  func testAccCheckAWSS3DestroyBucket(n string) resource.TestCheckFunc {
   836  	return func(s *terraform.State) error {
   837  		rs, ok := s.RootModule().Resources[n]
   838  		if !ok {
   839  			return fmt.Errorf("Not found: %s", n)
   840  		}
   841  
   842  		if rs.Primary.ID == "" {
   843  			return fmt.Errorf("No S3 Bucket ID is set")
   844  		}
   845  
   846  		conn := testAccProvider.Meta().(*AWSClient).s3conn
   847  		_, err := conn.DeleteBucket(&s3.DeleteBucketInput{
   848  			Bucket: aws.String(rs.Primary.ID),
   849  		})
   850  
   851  		if err != nil {
   852  			return fmt.Errorf("Error destroying Bucket (%s) in testAccCheckAWSS3DestroyBucket: %s", rs.Primary.ID, err)
   853  		}
   854  		return nil
   855  	}
   856  }
   857  
   858  func testAccCheckAWSS3BucketPolicy(n string, policy string) resource.TestCheckFunc {
   859  	return func(s *terraform.State) error {
   860  		rs, _ := s.RootModule().Resources[n]
   861  		conn := testAccProvider.Meta().(*AWSClient).s3conn
   862  
   863  		out, err := conn.GetBucketPolicy(&s3.GetBucketPolicyInput{
   864  			Bucket: aws.String(rs.Primary.ID),
   865  		})
   866  
   867  		if policy == "" {
   868  			if awsErr, ok := err.(awserr.Error); ok && awsErr.Code() == "NoSuchBucketPolicy" {
   869  				// expected
   870  				return nil
   871  			}
   872  			if err == nil {
   873  				return fmt.Errorf("Expected no policy, got: %#v", *out.Policy)
   874  			} else {
   875  				return fmt.Errorf("GetBucketPolicy error: %v, expected %s", err, policy)
   876  			}
   877  		}
   878  		if err != nil {
   879  			return fmt.Errorf("GetBucketPolicy error: %v, expected %s", err, policy)
   880  		}
   881  
   882  		if v := out.Policy; v == nil {
   883  			if policy != "" {
   884  				return fmt.Errorf("bad policy, found nil, expected: %s", policy)
   885  			}
   886  		} else {
   887  			expected := make(map[string]interface{})
   888  			if err := json.Unmarshal([]byte(policy), &expected); err != nil {
   889  				return err
   890  			}
   891  			actual := make(map[string]interface{})
   892  			if err := json.Unmarshal([]byte(*v), &actual); err != nil {
   893  				return err
   894  			}
   895  
   896  			if !reflect.DeepEqual(expected, actual) {
   897  				return fmt.Errorf("bad policy, expected: %#v, got %#v", expected, actual)
   898  			}
   899  		}
   900  
   901  		return nil
   902  	}
   903  }
   904  
   905  func testAccCheckAWSS3BucketWebsite(n string, indexDoc string, errorDoc string, redirectProtocol string, redirectTo string) resource.TestCheckFunc {
   906  	return func(s *terraform.State) error {
   907  		rs, _ := s.RootModule().Resources[n]
   908  		conn := testAccProvider.Meta().(*AWSClient).s3conn
   909  
   910  		out, err := conn.GetBucketWebsite(&s3.GetBucketWebsiteInput{
   911  			Bucket: aws.String(rs.Primary.ID),
   912  		})
   913  
   914  		if err != nil {
   915  			if indexDoc == "" {
   916  				// If we want to assert that the website is not there, than
   917  				// this error is expected
   918  				return nil
   919  			} else {
   920  				return fmt.Errorf("S3BucketWebsite error: %v", err)
   921  			}
   922  		}
   923  
   924  		if v := out.IndexDocument; v == nil {
   925  			if indexDoc != "" {
   926  				return fmt.Errorf("bad index doc, found nil, expected: %s", indexDoc)
   927  			}
   928  		} else {
   929  			if *v.Suffix != indexDoc {
   930  				return fmt.Errorf("bad index doc, expected: %s, got %#v", indexDoc, out.IndexDocument)
   931  			}
   932  		}
   933  
   934  		if v := out.ErrorDocument; v == nil {
   935  			if errorDoc != "" {
   936  				return fmt.Errorf("bad error doc, found nil, expected: %s", errorDoc)
   937  			}
   938  		} else {
   939  			if *v.Key != errorDoc {
   940  				return fmt.Errorf("bad error doc, expected: %s, got %#v", errorDoc, out.ErrorDocument)
   941  			}
   942  		}
   943  
   944  		if v := out.RedirectAllRequestsTo; v == nil {
   945  			if redirectTo != "" {
   946  				return fmt.Errorf("bad redirect to, found nil, expected: %s", redirectTo)
   947  			}
   948  		} else {
   949  			if *v.HostName != redirectTo {
   950  				return fmt.Errorf("bad redirect to, expected: %s, got %#v", redirectTo, out.RedirectAllRequestsTo)
   951  			}
   952  			if redirectProtocol != "" && v.Protocol != nil && *v.Protocol != redirectProtocol {
   953  				return fmt.Errorf("bad redirect protocol to, expected: %s, got %#v", redirectProtocol, out.RedirectAllRequestsTo)
   954  			}
   955  		}
   956  
   957  		return nil
   958  	}
   959  }
   960  
   961  func testAccCheckAWSS3BucketWebsiteRoutingRules(n string, routingRules []*s3.RoutingRule) resource.TestCheckFunc {
   962  	return func(s *terraform.State) error {
   963  		rs, _ := s.RootModule().Resources[n]
   964  		conn := testAccProvider.Meta().(*AWSClient).s3conn
   965  
   966  		out, err := conn.GetBucketWebsite(&s3.GetBucketWebsiteInput{
   967  			Bucket: aws.String(rs.Primary.ID),
   968  		})
   969  
   970  		if err != nil {
   971  			if routingRules == nil {
   972  				return nil
   973  			}
   974  			return fmt.Errorf("GetBucketWebsite error: %v", err)
   975  		}
   976  
   977  		if !reflect.DeepEqual(out.RoutingRules, routingRules) {
   978  			return fmt.Errorf("bad routing rule, expected: %v, got %v", routingRules, out.RoutingRules)
   979  		}
   980  
   981  		return nil
   982  	}
   983  }
   984  
   985  func testAccCheckAWSS3BucketVersioning(n string, versioningStatus string) resource.TestCheckFunc {
   986  	return func(s *terraform.State) error {
   987  		rs, _ := s.RootModule().Resources[n]
   988  		conn := testAccProvider.Meta().(*AWSClient).s3conn
   989  
   990  		out, err := conn.GetBucketVersioning(&s3.GetBucketVersioningInput{
   991  			Bucket: aws.String(rs.Primary.ID),
   992  		})
   993  
   994  		if err != nil {
   995  			return fmt.Errorf("GetBucketVersioning error: %v", err)
   996  		}
   997  
   998  		if v := out.Status; v == nil {
   999  			if versioningStatus != "" {
  1000  				return fmt.Errorf("bad error versioning status, found nil, expected: %s", versioningStatus)
  1001  			}
  1002  		} else {
  1003  			if *v != versioningStatus {
  1004  				return fmt.Errorf("bad error versioning status, expected: %s, got %s", versioningStatus, *v)
  1005  			}
  1006  		}
  1007  
  1008  		return nil
  1009  	}
  1010  }
  1011  
  1012  func testAccCheckAWSS3BucketCors(n string, corsRules []*s3.CORSRule) resource.TestCheckFunc {
  1013  	return func(s *terraform.State) error {
  1014  		rs, _ := s.RootModule().Resources[n]
  1015  		conn := testAccProvider.Meta().(*AWSClient).s3conn
  1016  
  1017  		out, err := conn.GetBucketCors(&s3.GetBucketCorsInput{
  1018  			Bucket: aws.String(rs.Primary.ID),
  1019  		})
  1020  
  1021  		if err != nil {
  1022  			return fmt.Errorf("GetBucketCors error: %v", err)
  1023  		}
  1024  
  1025  		if !reflect.DeepEqual(out.CORSRules, corsRules) {
  1026  			return fmt.Errorf("bad error cors rule, expected: %v, got %v", corsRules, out.CORSRules)
  1027  		}
  1028  
  1029  		return nil
  1030  	}
  1031  }
  1032  
  1033  func testAccCheckAWSS3RequestPayer(n, expectedPayer string) resource.TestCheckFunc {
  1034  	return func(s *terraform.State) error {
  1035  		rs, _ := s.RootModule().Resources[n]
  1036  		conn := testAccProvider.Meta().(*AWSClient).s3conn
  1037  
  1038  		out, err := conn.GetBucketRequestPayment(&s3.GetBucketRequestPaymentInput{
  1039  			Bucket: aws.String(rs.Primary.ID),
  1040  		})
  1041  
  1042  		if err != nil {
  1043  			return fmt.Errorf("GetBucketRequestPayment error: %v", err)
  1044  		}
  1045  
  1046  		if *out.Payer != expectedPayer {
  1047  			return fmt.Errorf("bad error request payer type, expected: %v, got %v",
  1048  				expectedPayer, out.Payer)
  1049  		}
  1050  
  1051  		return nil
  1052  	}
  1053  }
  1054  
  1055  func testAccCheckAWSS3BucketLogging(n, b, p string) resource.TestCheckFunc {
  1056  	return func(s *terraform.State) error {
  1057  		rs, _ := s.RootModule().Resources[n]
  1058  		conn := testAccProvider.Meta().(*AWSClient).s3conn
  1059  
  1060  		out, err := conn.GetBucketLogging(&s3.GetBucketLoggingInput{
  1061  			Bucket: aws.String(rs.Primary.ID),
  1062  		})
  1063  
  1064  		if err != nil {
  1065  			return fmt.Errorf("GetBucketLogging error: %v", err)
  1066  		}
  1067  
  1068  		tb, _ := s.RootModule().Resources[b]
  1069  
  1070  		if v := out.LoggingEnabled.TargetBucket; v == nil {
  1071  			if tb.Primary.ID != "" {
  1072  				return fmt.Errorf("bad target bucket, found nil, expected: %s", tb.Primary.ID)
  1073  			}
  1074  		} else {
  1075  			if *v != tb.Primary.ID {
  1076  				return fmt.Errorf("bad target bucket, expected: %s, got %s", tb.Primary.ID, *v)
  1077  			}
  1078  		}
  1079  
  1080  		if v := out.LoggingEnabled.TargetPrefix; v == nil {
  1081  			if p != "" {
  1082  				return fmt.Errorf("bad target prefix, found nil, expected: %s", p)
  1083  			}
  1084  		} else {
  1085  			if *v != p {
  1086  				return fmt.Errorf("bad target prefix, expected: %s, got %s", p, *v)
  1087  			}
  1088  		}
  1089  
  1090  		return nil
  1091  	}
  1092  }
  1093  
  1094  // These need a bit of randomness as the name can only be used once globally
  1095  // within AWS
  1096  func testAccBucketName(randInt int) string {
  1097  	return fmt.Sprintf("tf-test-bucket-%d", randInt)
  1098  }
  1099  
  1100  func testAccBucketDomainName(randInt int) string {
  1101  	return fmt.Sprintf("tf-test-bucket-%d.s3.amazonaws.com", randInt)
  1102  }
  1103  
  1104  func testAccWebsiteEndpoint(randInt int) string {
  1105  	return fmt.Sprintf("tf-test-bucket-%d.s3-website-us-west-2.amazonaws.com", randInt)
  1106  }
  1107  
  1108  func testAccAWSS3BucketPolicy(randInt int) string {
  1109  	return fmt.Sprintf(`{ "Version": "2012-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "AWS": "*" }, "Action": "s3:GetObject", "Resource": "arn:aws:s3:::tf-test-bucket-%d/*" } ] }`, randInt)
  1110  }
  1111  
  1112  func testAccAWSS3BucketConfig(randInt int) string {
  1113  	return fmt.Sprintf(`
  1114  resource "aws_s3_bucket" "bucket" {
  1115  	bucket = "tf-test-bucket-%d"
  1116  	acl = "public-read"
  1117  }
  1118  `, randInt)
  1119  }
  1120  
  1121  func testAccAWSS3BucketConfigWithRegion(randInt int) string {
  1122  	return fmt.Sprintf(`
  1123  provider "aws" {
  1124  	alias = "west"
  1125  	region = "eu-west-1"
  1126  }
  1127  
  1128  resource "aws_s3_bucket" "bucket" {
  1129  	provider = "aws.west"
  1130  	bucket = "tf-test-bucket-%d"
  1131  	region = "eu-west-1"
  1132  }
  1133  `, randInt)
  1134  }
  1135  
  1136  func testAccAWSS3BucketWebsiteConfig(randInt int) string {
  1137  	return fmt.Sprintf(`
  1138  resource "aws_s3_bucket" "bucket" {
  1139  	bucket = "tf-test-bucket-%d"
  1140  	acl = "public-read"
  1141  
  1142  	website {
  1143  		index_document = "index.html"
  1144  	}
  1145  }
  1146  `, randInt)
  1147  }
  1148  
  1149  func testAccAWSS3BucketWebsiteConfigWithError(randInt int) string {
  1150  	return fmt.Sprintf(`
  1151  resource "aws_s3_bucket" "bucket" {
  1152  	bucket = "tf-test-bucket-%d"
  1153  	acl = "public-read"
  1154  
  1155  	website {
  1156  		index_document = "index.html"
  1157  		error_document = "error.html"
  1158  	}
  1159  }
  1160  `, randInt)
  1161  }
  1162  
  1163  func testAccAWSS3BucketWebsiteConfigWithRedirect(randInt int) string {
  1164  	return fmt.Sprintf(`
  1165  resource "aws_s3_bucket" "bucket" {
  1166  	bucket = "tf-test-bucket-%d"
  1167  	acl = "public-read"
  1168  
  1169  	website {
  1170  		redirect_all_requests_to = "hashicorp.com"
  1171  	}
  1172  }
  1173  `, randInt)
  1174  }
  1175  
  1176  func testAccAWSS3BucketWebsiteConfigWithHttpsRedirect(randInt int) string {
  1177  	return fmt.Sprintf(`
  1178  resource "aws_s3_bucket" "bucket" {
  1179  	bucket = "tf-test-bucket-%d"
  1180  	acl = "public-read"
  1181  
  1182  	website {
  1183  		redirect_all_requests_to = "https://hashicorp.com"
  1184  	}
  1185  }
  1186  `, randInt)
  1187  }
  1188  
  1189  func testAccAWSS3BucketWebsiteConfigWithRoutingRules(randInt int) string {
  1190  	return fmt.Sprintf(`
  1191  resource "aws_s3_bucket" "bucket" {
  1192  	bucket = "tf-test-bucket-%d"
  1193  	acl = "public-read"
  1194  
  1195  	website {
  1196  		index_document = "index.html"
  1197  		error_document = "error.html"
  1198  		routing_rules = <<EOF
  1199  [{
  1200  	"Condition": {
  1201  		"KeyPrefixEquals": "docs/"
  1202  	},
  1203  	"Redirect": {
  1204  		"ReplaceKeyPrefixWith": "documents/"
  1205  	}
  1206  }]
  1207  EOF
  1208  	}
  1209  }
  1210  `, randInt)
  1211  }
  1212  
  1213  func testAccAWSS3BucketConfigWithAcceleration(randInt int) string {
  1214  	return fmt.Sprintf(`
  1215  provider "aws" {
  1216  	alias = "west"
  1217  	region = "eu-west-1"
  1218  }
  1219  
  1220  resource "aws_s3_bucket" "bucket" {
  1221  	provider = "aws.west"
  1222  	bucket = "tf-test-bucket-%d"
  1223  	region = "eu-west-1"
  1224  	acl = "public-read"
  1225  	acceleration_status = "Enabled"
  1226  }
  1227  `, randInt)
  1228  }
  1229  
  1230  func testAccAWSS3BucketConfigWithoutAcceleration(randInt int) string {
  1231  	return fmt.Sprintf(`
  1232  provider "aws" {
  1233  	alias = "west"
  1234  	region = "eu-west-1"
  1235  }
  1236  
  1237  resource "aws_s3_bucket" "bucket" {
  1238  	provider = "aws.west"
  1239  	bucket = "tf-test-bucket-%d"
  1240  	region = "eu-west-1"
  1241  	acl = "public-read"
  1242  	acceleration_status = "Suspended"
  1243  }
  1244  `, randInt)
  1245  }
  1246  
  1247  func testAccAWSS3BucketConfigRequestPayerBucketOwner(randInt int) string {
  1248  	return fmt.Sprintf(`
  1249  resource "aws_s3_bucket" "bucket" {
  1250  	bucket = "tf-test-bucket-%d"
  1251  	acl = "public-read"
  1252  	request_payer = "BucketOwner"
  1253  }
  1254  `, randInt)
  1255  }
  1256  
  1257  func testAccAWSS3BucketConfigRequestPayerRequester(randInt int) string {
  1258  	return fmt.Sprintf(`
  1259  resource "aws_s3_bucket" "bucket" {
  1260  	bucket = "tf-test-bucket-%d"
  1261  	acl = "public-read"
  1262  	request_payer = "Requester"
  1263  }
  1264  `, randInt)
  1265  }
  1266  
  1267  func testAccAWSS3BucketConfigWithPolicy(randInt int) string {
  1268  	return fmt.Sprintf(`
  1269  resource "aws_s3_bucket" "bucket" {
  1270  	bucket = "tf-test-bucket-%d"
  1271  	acl = "public-read"
  1272  	policy = %s
  1273  }
  1274  `, randInt, strconv.Quote(testAccAWSS3BucketPolicy(randInt)))
  1275  }
  1276  
  1277  func testAccAWSS3BucketDestroyedConfig(randInt int) string {
  1278  	return fmt.Sprintf(`
  1279  resource "aws_s3_bucket" "bucket" {
  1280  	bucket = "tf-test-bucket-%d"
  1281  	acl = "public-read"
  1282  }
  1283  `, randInt)
  1284  }
  1285  
  1286  func testAccAWSS3BucketConfigWithEmptyPolicy(randInt int) string {
  1287  	return fmt.Sprintf(`
  1288  resource "aws_s3_bucket" "bucket" {
  1289  	bucket = "tf-test-bucket-%d"
  1290  	acl = "public-read"
  1291  	policy = ""
  1292  }
  1293  `, randInt)
  1294  }
  1295  
  1296  func testAccAWSS3BucketConfigWithVersioning(randInt int) string {
  1297  	return fmt.Sprintf(`
  1298  resource "aws_s3_bucket" "bucket" {
  1299  	bucket = "tf-test-bucket-%d"
  1300  	acl = "public-read"
  1301  	versioning {
  1302  	  enabled = true
  1303  	}
  1304  }
  1305  `, randInt)
  1306  }
  1307  
  1308  func testAccAWSS3BucketConfigWithDisableVersioning(randInt int) string {
  1309  	return fmt.Sprintf(`
  1310  resource "aws_s3_bucket" "bucket" {
  1311  	bucket = "tf-test-bucket-%d"
  1312  	acl = "public-read"
  1313  	versioning {
  1314  	  enabled = false
  1315  	}
  1316  }
  1317  `, randInt)
  1318  }
  1319  
  1320  func testAccAWSS3BucketConfigWithCORS(randInt int) string {
  1321  	return fmt.Sprintf(`
  1322  resource "aws_s3_bucket" "bucket" {
  1323  	bucket = "tf-test-bucket-%d"
  1324  	acl = "public-read"
  1325  	cors_rule {
  1326  			allowed_headers = ["*"]
  1327  			allowed_methods = ["PUT","POST"]
  1328  			allowed_origins = ["https://www.example.com"]
  1329  			expose_headers = ["x-amz-server-side-encryption","ETag"]
  1330  			max_age_seconds = 3000
  1331  	}
  1332  }
  1333  `, randInt)
  1334  }
  1335  
  1336  var testAccAWSS3BucketConfigWithAcl = `
  1337  resource "aws_s3_bucket" "bucket" {
  1338  	bucket = "tf-test-bucket-%d"
  1339  	acl = "public-read"
  1340  }
  1341  `
  1342  
  1343  var testAccAWSS3BucketConfigWithAclUpdate = `
  1344  resource "aws_s3_bucket" "bucket" {
  1345  	bucket = "tf-test-bucket-%d"
  1346  	acl = "private"
  1347  }
  1348  `
  1349  
  1350  func testAccAWSS3BucketConfigWithLogging(randInt int) string {
  1351  	return fmt.Sprintf(`
  1352  resource "aws_s3_bucket" "log_bucket" {
  1353  	bucket = "tf-test-log-bucket-%d"
  1354  	acl = "log-delivery-write"
  1355  }
  1356  resource "aws_s3_bucket" "bucket" {
  1357  	bucket = "tf-test-bucket-%d"
  1358  	acl = "private"
  1359  	logging {
  1360  		target_bucket = "${aws_s3_bucket.log_bucket.id}"
  1361  		target_prefix = "log/"
  1362  	}
  1363  }
  1364  `, randInt, randInt)
  1365  }
  1366  
  1367  func testAccAWSS3BucketConfigWithLifecycle(randInt int) string {
  1368  	return fmt.Sprintf(`
  1369  resource "aws_s3_bucket" "bucket" {
  1370  	bucket = "tf-test-bucket-%d"
  1371  	acl = "private"
  1372  	lifecycle_rule {
  1373  		id = "id1"
  1374  		prefix = "path1/"
  1375  		enabled = true
  1376  
  1377  		expiration {
  1378  			days = 365
  1379  		}
  1380  
  1381  		transition {
  1382  			days = 30
  1383  			storage_class = "STANDARD_IA"
  1384  		}
  1385  		transition {
  1386  			days = 60
  1387  			storage_class = "GLACIER"
  1388  		}
  1389  	}
  1390  	lifecycle_rule {
  1391  		id = "id2"
  1392  		prefix = "path2/"
  1393  		enabled = true
  1394  
  1395  		expiration {
  1396  			date = "2016-01-12"
  1397  		}
  1398  	}
  1399  }
  1400  `, randInt)
  1401  }
  1402  
  1403  func testAccAWSS3BucketConfigWithVersioningLifecycle(randInt int) string {
  1404  	return fmt.Sprintf(`
  1405  resource "aws_s3_bucket" "bucket" {
  1406  	bucket = "tf-test-bucket-%d"
  1407  	acl = "private"
  1408  	versioning {
  1409  	  enabled = false
  1410  	}
  1411  	lifecycle_rule {
  1412  		id = "id1"
  1413  		prefix = "path1/"
  1414  		enabled = true
  1415  
  1416  		noncurrent_version_expiration {
  1417  			days = 365
  1418  		}
  1419  		noncurrent_version_transition {
  1420  			days = 30
  1421  			storage_class = "STANDARD_IA"
  1422  		}
  1423  		noncurrent_version_transition {
  1424  			days = 60
  1425  			storage_class = "GLACIER"
  1426  		}
  1427  	}
  1428  	lifecycle_rule {
  1429  		id = "id2"
  1430  		prefix = "path2/"
  1431  		enabled = false
  1432  
  1433  		noncurrent_version_expiration {
  1434  			days = 365
  1435  		}
  1436  	}
  1437  }
  1438  `, randInt)
  1439  }
  1440  
  1441  const testAccAWSS3BucketConfigReplicationBasic = `
  1442  provider "aws" {
  1443    alias  = "euwest"
  1444    region = "eu-west-1"
  1445  }
  1446  
  1447  provider "aws" {
  1448    alias  = "uswest2"
  1449    region = "us-west-2"
  1450  }
  1451  
  1452  resource "aws_iam_role" "role" {
  1453    name               = "tf-iam-role-replication-%d"
  1454    assume_role_policy = <<POLICY
  1455  {
  1456    "Version": "2012-10-17",
  1457    "Statement": [
  1458      {
  1459        "Action": "sts:AssumeRole",
  1460        "Principal": {
  1461          "Service": "s3.amazonaws.com"
  1462        },
  1463        "Effect": "Allow",
  1464        "Sid": ""
  1465      }
  1466    ]
  1467  }
  1468  POLICY
  1469  }
  1470  `
  1471  
  1472  func testAccAWSS3BucketConfigReplication(randInt int) string {
  1473  	return fmt.Sprintf(testAccAWSS3BucketConfigReplicationBasic+`
  1474  resource "aws_s3_bucket" "bucket" {
  1475      provider = "aws.uswest2"
  1476      bucket   = "tf-test-bucket-%d"
  1477      acl      = "private"
  1478  
  1479      versioning {
  1480          enabled = true
  1481      }
  1482  }
  1483  
  1484  resource "aws_s3_bucket" "destination" {
  1485      provider = "aws.euwest"
  1486      bucket   = "tf-test-bucket-destination-%d"
  1487      region   = "eu-west-1"
  1488  
  1489      versioning {
  1490          enabled = true
  1491      }
  1492  }
  1493  `, randInt, randInt, randInt)
  1494  }
  1495  
  1496  func testAccAWSS3BucketConfigReplicationWithConfiguration(randInt int) string {
  1497  	return fmt.Sprintf(testAccAWSS3BucketConfigReplicationBasic+`
  1498  resource "aws_s3_bucket" "bucket" {
  1499      provider = "aws.uswest2"
  1500      bucket   = "tf-test-bucket-%d"
  1501      acl      = "private"
  1502  
  1503      versioning {
  1504          enabled = true
  1505      }
  1506  
  1507      replication_configuration {
  1508          role = "${aws_iam_role.role.arn}"
  1509          rules {
  1510              id     = "foobar"
  1511              prefix = "foo"
  1512              status = "Enabled"
  1513  
  1514              destination {
  1515                  bucket        = "${aws_s3_bucket.destination.arn}"
  1516                  storage_class = "STANDARD"
  1517              }
  1518          }
  1519      }
  1520  }
  1521  
  1522  resource "aws_s3_bucket" "destination" {
  1523      provider = "aws.euwest"
  1524      bucket   = "tf-test-bucket-destination-%d"
  1525      region   = "eu-west-1"
  1526  
  1527      versioning {
  1528          enabled = true
  1529      }
  1530  }
  1531  `, randInt, randInt, randInt)
  1532  }
  1533  
  1534  func testAccAWSS3BucketConfigReplicationWithoutStorageClass(randInt int) string {
  1535  	return fmt.Sprintf(testAccAWSS3BucketConfigReplicationBasic+`
  1536  resource "aws_s3_bucket" "bucket" {
  1537      provider = "aws.uswest2"
  1538      bucket   = "tf-test-bucket-%d"
  1539      acl      = "private"
  1540  
  1541      versioning {
  1542          enabled = true
  1543      }
  1544  
  1545      replication_configuration {
  1546          role = "${aws_iam_role.role.arn}"
  1547          rules {
  1548              id     = "foobar"
  1549              prefix = "foo"
  1550              status = "Enabled"
  1551  
  1552              destination {
  1553                  bucket        = "${aws_s3_bucket.destination.arn}"
  1554              }
  1555          }
  1556      }
  1557  }
  1558  
  1559  resource "aws_s3_bucket" "destination" {
  1560      provider = "aws.euwest"
  1561      bucket   = "tf-test-bucket-destination-%d"
  1562      region   = "eu-west-1"
  1563  
  1564      versioning {
  1565          enabled = true
  1566      }
  1567  }
  1568  `, randInt, randInt, randInt)
  1569  }
  1570  
  1571  func testAccAWSS3BucketConfigReplicationNoVersioning(randInt int) string {
  1572  	return fmt.Sprintf(testAccAWSS3BucketConfigReplicationBasic+`
  1573  resource "aws_s3_bucket" "bucket" {
  1574      provider = "aws.uswest2"
  1575      bucket   = "tf-test-bucket-%d"
  1576      acl      = "private"
  1577  
  1578      replication_configuration {
  1579          role = "${aws_iam_role.role.arn}"
  1580          rules {
  1581              id     = "foobar"
  1582              prefix = "foo"
  1583              status = "Enabled"
  1584  
  1585              destination {
  1586                  bucket        = "${aws_s3_bucket.destination.arn}"
  1587                  storage_class = "STANDARD"
  1588              }
  1589          }
  1590      }
  1591  }
  1592  
  1593  resource "aws_s3_bucket" "destination" {
  1594      provider = "aws.euwest"
  1595      bucket   = "tf-test-bucket-destination-%d"
  1596      region   = "eu-west-1"
  1597  
  1598      versioning {
  1599          enabled = true
  1600      }
  1601  }
  1602  `, randInt, randInt, randInt)
  1603  }