github.com/articulate/terraform@v0.6.13-0.20160303003731-8d31c93862de/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  	"github.com/aws/aws-sdk-go/aws"
    16  	"github.com/aws/aws-sdk-go/aws/awserr"
    17  	"github.com/aws/aws-sdk-go/service/s3"
    18  )
    19  
    20  func TestAccAWSS3Bucket_basic(t *testing.T) {
    21  	rInt := acctest.RandInt()
    22  	arnRegexp := regexp.MustCompile(
    23  		"^arn:aws:s3:::")
    24  
    25  	resource.Test(t, resource.TestCase{
    26  		PreCheck:     func() { testAccPreCheck(t) },
    27  		Providers:    testAccProviders,
    28  		CheckDestroy: testAccCheckAWSS3BucketDestroy,
    29  		Steps: []resource.TestStep{
    30  			resource.TestStep{
    31  				Config: testAccAWSS3BucketConfig(rInt),
    32  				Check: resource.ComposeTestCheckFunc(
    33  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
    34  					resource.TestCheckResourceAttr(
    35  						"aws_s3_bucket.bucket", "hosted_zone_id", HostedZoneIDForRegion("us-west-2")),
    36  					resource.TestCheckResourceAttr(
    37  						"aws_s3_bucket.bucket", "region", "us-west-2"),
    38  					resource.TestCheckResourceAttr(
    39  						"aws_s3_bucket.bucket", "website_endpoint", ""),
    40  					resource.TestMatchResourceAttr(
    41  						"aws_s3_bucket.bucket", "arn", arnRegexp),
    42  				),
    43  			},
    44  		},
    45  	})
    46  }
    47  
    48  func TestAccAWSS3Bucket_Policy(t *testing.T) {
    49  	rInt := acctest.RandInt()
    50  
    51  	resource.Test(t, resource.TestCase{
    52  		PreCheck:     func() { testAccPreCheck(t) },
    53  		Providers:    testAccProviders,
    54  		CheckDestroy: testAccCheckAWSS3BucketDestroy,
    55  		Steps: []resource.TestStep{
    56  			resource.TestStep{
    57  				Config: testAccAWSS3BucketConfigWithPolicy(rInt),
    58  				Check: resource.ComposeTestCheckFunc(
    59  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
    60  					testAccCheckAWSS3BucketPolicy(
    61  						"aws_s3_bucket.bucket", testAccAWSS3BucketPolicy(rInt)),
    62  				),
    63  			},
    64  			resource.TestStep{
    65  				Config: testAccAWSS3BucketConfig(rInt),
    66  				Check: resource.ComposeTestCheckFunc(
    67  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
    68  					testAccCheckAWSS3BucketPolicy(
    69  						"aws_s3_bucket.bucket", ""),
    70  				),
    71  			},
    72  		},
    73  	})
    74  }
    75  
    76  func TestAccAWSS3Bucket_UpdateAcl(t *testing.T) {
    77  	ri := acctest.RandInt()
    78  	preConfig := fmt.Sprintf(testAccAWSS3BucketConfigWithAcl, ri)
    79  	postConfig := fmt.Sprintf(testAccAWSS3BucketConfigWithAclUpdate, ri)
    80  
    81  	resource.Test(t, resource.TestCase{
    82  		PreCheck:     func() { testAccPreCheck(t) },
    83  		Providers:    testAccProviders,
    84  		CheckDestroy: testAccCheckAWSS3BucketDestroy,
    85  		Steps: []resource.TestStep{
    86  			resource.TestStep{
    87  				Config: preConfig,
    88  				Check: resource.ComposeTestCheckFunc(
    89  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
    90  					resource.TestCheckResourceAttr(
    91  						"aws_s3_bucket.bucket", "acl", "public-read"),
    92  				),
    93  			},
    94  			resource.TestStep{
    95  				Config: postConfig,
    96  				Check: resource.ComposeTestCheckFunc(
    97  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
    98  					resource.TestCheckResourceAttr(
    99  						"aws_s3_bucket.bucket", "acl", "private"),
   100  				),
   101  			},
   102  		},
   103  	})
   104  }
   105  
   106  func TestAccAWSS3Bucket_Website_Simple(t *testing.T) {
   107  	rInt := acctest.RandInt()
   108  	resource.Test(t, resource.TestCase{
   109  		PreCheck:     func() { testAccPreCheck(t) },
   110  		Providers:    testAccProviders,
   111  		CheckDestroy: testAccCheckAWSS3BucketDestroy,
   112  		Steps: []resource.TestStep{
   113  			resource.TestStep{
   114  				Config: testAccAWSS3BucketWebsiteConfig(rInt),
   115  				Check: resource.ComposeTestCheckFunc(
   116  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
   117  					testAccCheckAWSS3BucketWebsite(
   118  						"aws_s3_bucket.bucket", "index.html", "", "", ""),
   119  					resource.TestCheckResourceAttr(
   120  						"aws_s3_bucket.bucket", "website_endpoint", testAccWebsiteEndpoint(rInt)),
   121  				),
   122  			},
   123  			resource.TestStep{
   124  				Config: testAccAWSS3BucketWebsiteConfigWithError(rInt),
   125  				Check: resource.ComposeTestCheckFunc(
   126  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
   127  					testAccCheckAWSS3BucketWebsite(
   128  						"aws_s3_bucket.bucket", "index.html", "error.html", "", ""),
   129  					resource.TestCheckResourceAttr(
   130  						"aws_s3_bucket.bucket", "website_endpoint", testAccWebsiteEndpoint(rInt)),
   131  				),
   132  			},
   133  			resource.TestStep{
   134  				Config: testAccAWSS3BucketConfig(rInt),
   135  				Check: resource.ComposeTestCheckFunc(
   136  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
   137  					testAccCheckAWSS3BucketWebsite(
   138  						"aws_s3_bucket.bucket", "", "", "", ""),
   139  					resource.TestCheckResourceAttr(
   140  						"aws_s3_bucket.bucket", "website_endpoint", ""),
   141  				),
   142  			},
   143  		},
   144  	})
   145  }
   146  
   147  func TestAccAWSS3Bucket_WebsiteRedirect(t *testing.T) {
   148  	rInt := acctest.RandInt()
   149  	resource.Test(t, resource.TestCase{
   150  		PreCheck:     func() { testAccPreCheck(t) },
   151  		Providers:    testAccProviders,
   152  		CheckDestroy: testAccCheckAWSS3BucketDestroy,
   153  		Steps: []resource.TestStep{
   154  			resource.TestStep{
   155  				Config: testAccAWSS3BucketWebsiteConfigWithRedirect(rInt),
   156  				Check: resource.ComposeTestCheckFunc(
   157  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
   158  					testAccCheckAWSS3BucketWebsite(
   159  						"aws_s3_bucket.bucket", "", "", "", "hashicorp.com"),
   160  					resource.TestCheckResourceAttr(
   161  						"aws_s3_bucket.bucket", "website_endpoint", testAccWebsiteEndpoint(rInt)),
   162  				),
   163  			},
   164  			resource.TestStep{
   165  				Config: testAccAWSS3BucketWebsiteConfigWithHttpsRedirect(rInt),
   166  				Check: resource.ComposeTestCheckFunc(
   167  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
   168  					testAccCheckAWSS3BucketWebsite(
   169  						"aws_s3_bucket.bucket", "", "", "https", "hashicorp.com"),
   170  					resource.TestCheckResourceAttr(
   171  						"aws_s3_bucket.bucket", "website_endpoint", testAccWebsiteEndpoint(rInt)),
   172  				),
   173  			},
   174  			resource.TestStep{
   175  				Config: testAccAWSS3BucketConfig(rInt),
   176  				Check: resource.ComposeTestCheckFunc(
   177  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
   178  					testAccCheckAWSS3BucketWebsite(
   179  						"aws_s3_bucket.bucket", "", "", "", ""),
   180  					resource.TestCheckResourceAttr(
   181  						"aws_s3_bucket.bucket", "website_endpoint", ""),
   182  				),
   183  			},
   184  		},
   185  	})
   186  }
   187  
   188  func TestAccAWSS3Bucket_WebsiteRoutingRules(t *testing.T) {
   189  	rInt := acctest.RandInt()
   190  	resource.Test(t, resource.TestCase{
   191  		PreCheck:     func() { testAccPreCheck(t) },
   192  		Providers:    testAccProviders,
   193  		CheckDestroy: testAccCheckAWSS3BucketDestroy,
   194  		Steps: []resource.TestStep{
   195  			resource.TestStep{
   196  				Config: testAccAWSS3BucketWebsiteConfigWithRoutingRules(rInt),
   197  				Check: resource.ComposeTestCheckFunc(
   198  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
   199  					testAccCheckAWSS3BucketWebsite(
   200  						"aws_s3_bucket.bucket", "index.html", "error.html", "", ""),
   201  					testAccCheckAWSS3BucketWebsiteRoutingRules(
   202  						"aws_s3_bucket.bucket",
   203  						[]*s3.RoutingRule{
   204  							&s3.RoutingRule{
   205  								Condition: &s3.Condition{
   206  									KeyPrefixEquals: aws.String("docs/"),
   207  								},
   208  								Redirect: &s3.Redirect{
   209  									ReplaceKeyPrefixWith: aws.String("documents/"),
   210  								},
   211  							},
   212  						},
   213  					),
   214  					resource.TestCheckResourceAttr(
   215  						"aws_s3_bucket.bucket", "website_endpoint", testAccWebsiteEndpoint(rInt)),
   216  				),
   217  			},
   218  			resource.TestStep{
   219  				Config: testAccAWSS3BucketConfig(rInt),
   220  				Check: resource.ComposeTestCheckFunc(
   221  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
   222  					testAccCheckAWSS3BucketWebsite(
   223  						"aws_s3_bucket.bucket", "", "", "", ""),
   224  					testAccCheckAWSS3BucketWebsiteRoutingRules("aws_s3_bucket.bucket", nil),
   225  					resource.TestCheckResourceAttr(
   226  						"aws_s3_bucket.bucket", "website_endpoint", ""),
   227  				),
   228  			},
   229  		},
   230  	})
   231  }
   232  
   233  // Test TestAccAWSS3Bucket_shouldFailNotFound is designed to fail with a "plan
   234  // not empty" error in Terraform, to check against regresssions.
   235  // See https://github.com/hashicorp/terraform/pull/2925
   236  func TestAccAWSS3Bucket_shouldFailNotFound(t *testing.T) {
   237  	rInt := acctest.RandInt()
   238  	resource.Test(t, resource.TestCase{
   239  		PreCheck:     func() { testAccPreCheck(t) },
   240  		Providers:    testAccProviders,
   241  		CheckDestroy: testAccCheckAWSS3BucketDestroy,
   242  		Steps: []resource.TestStep{
   243  			resource.TestStep{
   244  				Config: testAccAWSS3BucketDestroyedConfig(rInt),
   245  				Check: resource.ComposeTestCheckFunc(
   246  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
   247  					testAccCheckAWSS3DestroyBucket("aws_s3_bucket.bucket"),
   248  				),
   249  				ExpectNonEmptyPlan: true,
   250  			},
   251  		},
   252  	})
   253  }
   254  
   255  func TestAccAWSS3Bucket_Versioning(t *testing.T) {
   256  	rInt := acctest.RandInt()
   257  	resource.Test(t, resource.TestCase{
   258  		PreCheck:     func() { testAccPreCheck(t) },
   259  		Providers:    testAccProviders,
   260  		CheckDestroy: testAccCheckAWSS3BucketDestroy,
   261  		Steps: []resource.TestStep{
   262  			resource.TestStep{
   263  				Config: testAccAWSS3BucketConfig(rInt),
   264  				Check: resource.ComposeTestCheckFunc(
   265  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
   266  					testAccCheckAWSS3BucketVersioning(
   267  						"aws_s3_bucket.bucket", ""),
   268  				),
   269  			},
   270  			resource.TestStep{
   271  				Config: testAccAWSS3BucketConfigWithVersioning(rInt),
   272  				Check: resource.ComposeTestCheckFunc(
   273  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
   274  					testAccCheckAWSS3BucketVersioning(
   275  						"aws_s3_bucket.bucket", s3.BucketVersioningStatusEnabled),
   276  				),
   277  			},
   278  			resource.TestStep{
   279  				Config: testAccAWSS3BucketConfigWithDisableVersioning(rInt),
   280  				Check: resource.ComposeTestCheckFunc(
   281  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
   282  					testAccCheckAWSS3BucketVersioning(
   283  						"aws_s3_bucket.bucket", s3.BucketVersioningStatusSuspended),
   284  				),
   285  			},
   286  		},
   287  	})
   288  }
   289  
   290  func TestAccAWSS3Bucket_Cors(t *testing.T) {
   291  	rInt := acctest.RandInt()
   292  	resource.Test(t, resource.TestCase{
   293  		PreCheck:     func() { testAccPreCheck(t) },
   294  		Providers:    testAccProviders,
   295  		CheckDestroy: testAccCheckAWSS3BucketDestroy,
   296  		Steps: []resource.TestStep{
   297  			resource.TestStep{
   298  				Config: testAccAWSS3BucketConfigWithCORS(rInt),
   299  				Check: resource.ComposeTestCheckFunc(
   300  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
   301  					testAccCheckAWSS3BucketCors(
   302  						"aws_s3_bucket.bucket",
   303  						[]*s3.CORSRule{
   304  							&s3.CORSRule{
   305  								AllowedHeaders: []*string{aws.String("*")},
   306  								AllowedMethods: []*string{aws.String("PUT"), aws.String("POST")},
   307  								AllowedOrigins: []*string{aws.String("https://www.example.com")},
   308  								ExposeHeaders:  []*string{aws.String("x-amz-server-side-encryption"), aws.String("ETag")},
   309  								MaxAgeSeconds:  aws.Int64(3000),
   310  							},
   311  						},
   312  					),
   313  				),
   314  			},
   315  		},
   316  	})
   317  }
   318  
   319  func TestAccAWSS3Bucket_Logging(t *testing.T) {
   320  	rInt := acctest.RandInt()
   321  	resource.Test(t, resource.TestCase{
   322  		PreCheck:     func() { testAccPreCheck(t) },
   323  		Providers:    testAccProviders,
   324  		CheckDestroy: testAccCheckAWSS3BucketDestroy,
   325  		Steps: []resource.TestStep{
   326  			resource.TestStep{
   327  				Config: testAccAWSS3BucketConfigWithLogging(rInt),
   328  				Check: resource.ComposeTestCheckFunc(
   329  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
   330  					testAccCheckAWSS3BucketLogging(
   331  						"aws_s3_bucket.bucket", "aws_s3_bucket.log_bucket", "log/"),
   332  				),
   333  			},
   334  		},
   335  	})
   336  }
   337  
   338  func testAccCheckAWSS3BucketDestroy(s *terraform.State) error {
   339  	conn := testAccProvider.Meta().(*AWSClient).s3conn
   340  
   341  	for _, rs := range s.RootModule().Resources {
   342  		if rs.Type != "aws_s3_bucket" {
   343  			continue
   344  		}
   345  		_, err := conn.DeleteBucket(&s3.DeleteBucketInput{
   346  			Bucket: aws.String(rs.Primary.ID),
   347  		})
   348  		if err != nil {
   349  			if awsErr, ok := err.(awserr.Error); ok && awsErr.Code() == "NoSuchBucket" {
   350  				return nil
   351  			}
   352  			return err
   353  		}
   354  	}
   355  	return nil
   356  }
   357  
   358  func testAccCheckAWSS3BucketExists(n string) resource.TestCheckFunc {
   359  	return func(s *terraform.State) error {
   360  		rs, ok := s.RootModule().Resources[n]
   361  		if !ok {
   362  			return fmt.Errorf("Not found: %s", n)
   363  		}
   364  
   365  		if rs.Primary.ID == "" {
   366  			return fmt.Errorf("No S3 Bucket ID is set")
   367  		}
   368  
   369  		conn := testAccProvider.Meta().(*AWSClient).s3conn
   370  		_, err := conn.HeadBucket(&s3.HeadBucketInput{
   371  			Bucket: aws.String(rs.Primary.ID),
   372  		})
   373  
   374  		if err != nil {
   375  			return fmt.Errorf("S3Bucket error: %v", err)
   376  		}
   377  		return nil
   378  	}
   379  }
   380  
   381  func testAccCheckAWSS3DestroyBucket(n string) resource.TestCheckFunc {
   382  	return func(s *terraform.State) error {
   383  		rs, ok := s.RootModule().Resources[n]
   384  		if !ok {
   385  			return fmt.Errorf("Not found: %s", n)
   386  		}
   387  
   388  		if rs.Primary.ID == "" {
   389  			return fmt.Errorf("No S3 Bucket ID is set")
   390  		}
   391  
   392  		conn := testAccProvider.Meta().(*AWSClient).s3conn
   393  		_, err := conn.DeleteBucket(&s3.DeleteBucketInput{
   394  			Bucket: aws.String(rs.Primary.ID),
   395  		})
   396  
   397  		if err != nil {
   398  			return fmt.Errorf("Error destroying Bucket (%s) in testAccCheckAWSS3DestroyBucket: %s", rs.Primary.ID, err)
   399  		}
   400  		return nil
   401  	}
   402  }
   403  
   404  func testAccCheckAWSS3BucketPolicy(n string, policy string) resource.TestCheckFunc {
   405  	return func(s *terraform.State) error {
   406  		rs, _ := s.RootModule().Resources[n]
   407  		conn := testAccProvider.Meta().(*AWSClient).s3conn
   408  
   409  		out, err := conn.GetBucketPolicy(&s3.GetBucketPolicyInput{
   410  			Bucket: aws.String(rs.Primary.ID),
   411  		})
   412  
   413  		if err != nil {
   414  			if policy == "" {
   415  				// expected
   416  				return nil
   417  			} else {
   418  				return fmt.Errorf("GetBucketPolicy error: %v, expected %s", err, policy)
   419  			}
   420  		}
   421  
   422  		if v := out.Policy; v == nil {
   423  			if policy != "" {
   424  				return fmt.Errorf("bad policy, found nil, expected: %s", policy)
   425  			}
   426  		} else {
   427  			expected := make(map[string]interface{})
   428  			if err := json.Unmarshal([]byte(policy), &expected); err != nil {
   429  				return err
   430  			}
   431  			actual := make(map[string]interface{})
   432  			if err := json.Unmarshal([]byte(*v), &actual); err != nil {
   433  				return err
   434  			}
   435  
   436  			if !reflect.DeepEqual(expected, actual) {
   437  				return fmt.Errorf("bad policy, expected: %#v, got %#v", expected, actual)
   438  			}
   439  		}
   440  
   441  		return nil
   442  	}
   443  }
   444  
   445  func testAccCheckAWSS3BucketWebsite(n string, indexDoc string, errorDoc string, redirectProtocol string, redirectTo string) resource.TestCheckFunc {
   446  	return func(s *terraform.State) error {
   447  		rs, _ := s.RootModule().Resources[n]
   448  		conn := testAccProvider.Meta().(*AWSClient).s3conn
   449  
   450  		out, err := conn.GetBucketWebsite(&s3.GetBucketWebsiteInput{
   451  			Bucket: aws.String(rs.Primary.ID),
   452  		})
   453  
   454  		if err != nil {
   455  			if indexDoc == "" {
   456  				// If we want to assert that the website is not there, than
   457  				// this error is expected
   458  				return nil
   459  			} else {
   460  				return fmt.Errorf("S3BucketWebsite error: %v", err)
   461  			}
   462  		}
   463  
   464  		if v := out.IndexDocument; v == nil {
   465  			if indexDoc != "" {
   466  				return fmt.Errorf("bad index doc, found nil, expected: %s", indexDoc)
   467  			}
   468  		} else {
   469  			if *v.Suffix != indexDoc {
   470  				return fmt.Errorf("bad index doc, expected: %s, got %#v", indexDoc, out.IndexDocument)
   471  			}
   472  		}
   473  
   474  		if v := out.ErrorDocument; v == nil {
   475  			if errorDoc != "" {
   476  				return fmt.Errorf("bad error doc, found nil, expected: %s", errorDoc)
   477  			}
   478  		} else {
   479  			if *v.Key != errorDoc {
   480  				return fmt.Errorf("bad error doc, expected: %s, got %#v", errorDoc, out.ErrorDocument)
   481  			}
   482  		}
   483  
   484  		if v := out.RedirectAllRequestsTo; v == nil {
   485  			if redirectTo != "" {
   486  				return fmt.Errorf("bad redirect to, found nil, expected: %s", redirectTo)
   487  			}
   488  		} else {
   489  			if *v.HostName != redirectTo {
   490  				return fmt.Errorf("bad redirect to, expected: %s, got %#v", redirectTo, out.RedirectAllRequestsTo)
   491  			}
   492  			if redirectProtocol != "" && v.Protocol != nil && *v.Protocol != redirectProtocol {
   493  				return fmt.Errorf("bad redirect protocol to, expected: %s, got %#v", redirectProtocol, out.RedirectAllRequestsTo)
   494  			}
   495  		}
   496  
   497  		return nil
   498  	}
   499  }
   500  
   501  func testAccCheckAWSS3BucketWebsiteRoutingRules(n string, routingRules []*s3.RoutingRule) resource.TestCheckFunc {
   502  	return func(s *terraform.State) error {
   503  		rs, _ := s.RootModule().Resources[n]
   504  		conn := testAccProvider.Meta().(*AWSClient).s3conn
   505  
   506  		out, err := conn.GetBucketWebsite(&s3.GetBucketWebsiteInput{
   507  			Bucket: aws.String(rs.Primary.ID),
   508  		})
   509  
   510  		if err != nil {
   511  			if routingRules == nil {
   512  				return nil
   513  			}
   514  			return fmt.Errorf("GetBucketWebsite error: %v", err)
   515  		}
   516  
   517  		if !reflect.DeepEqual(out.RoutingRules, routingRules) {
   518  			return fmt.Errorf("bad routing rule, expected: %v, got %v", routingRules, out.RoutingRules)
   519  		}
   520  
   521  		return nil
   522  	}
   523  }
   524  
   525  func testAccCheckAWSS3BucketVersioning(n string, versioningStatus string) resource.TestCheckFunc {
   526  	return func(s *terraform.State) error {
   527  		rs, _ := s.RootModule().Resources[n]
   528  		conn := testAccProvider.Meta().(*AWSClient).s3conn
   529  
   530  		out, err := conn.GetBucketVersioning(&s3.GetBucketVersioningInput{
   531  			Bucket: aws.String(rs.Primary.ID),
   532  		})
   533  
   534  		if err != nil {
   535  			return fmt.Errorf("GetBucketVersioning error: %v", err)
   536  		}
   537  
   538  		if v := out.Status; v == nil {
   539  			if versioningStatus != "" {
   540  				return fmt.Errorf("bad error versioning status, found nil, expected: %s", versioningStatus)
   541  			}
   542  		} else {
   543  			if *v != versioningStatus {
   544  				return fmt.Errorf("bad error versioning status, expected: %s, got %s", versioningStatus, *v)
   545  			}
   546  		}
   547  
   548  		return nil
   549  	}
   550  }
   551  
   552  func testAccCheckAWSS3BucketCors(n string, corsRules []*s3.CORSRule) resource.TestCheckFunc {
   553  	return func(s *terraform.State) error {
   554  		rs, _ := s.RootModule().Resources[n]
   555  		conn := testAccProvider.Meta().(*AWSClient).s3conn
   556  
   557  		out, err := conn.GetBucketCors(&s3.GetBucketCorsInput{
   558  			Bucket: aws.String(rs.Primary.ID),
   559  		})
   560  
   561  		if err != nil {
   562  			return fmt.Errorf("GetBucketCors error: %v", err)
   563  		}
   564  
   565  		if !reflect.DeepEqual(out.CORSRules, corsRules) {
   566  			return fmt.Errorf("bad error cors rule, expected: %v, got %v", corsRules, out.CORSRules)
   567  		}
   568  
   569  		return nil
   570  	}
   571  }
   572  
   573  func testAccCheckAWSS3BucketLogging(n, b, p string) resource.TestCheckFunc {
   574  	return func(s *terraform.State) error {
   575  		rs, _ := s.RootModule().Resources[n]
   576  		conn := testAccProvider.Meta().(*AWSClient).s3conn
   577  
   578  		out, err := conn.GetBucketLogging(&s3.GetBucketLoggingInput{
   579  			Bucket: aws.String(rs.Primary.ID),
   580  		})
   581  
   582  		if err != nil {
   583  			return fmt.Errorf("GetBucketLogging error: %v", err)
   584  		}
   585  
   586  		tb, _ := s.RootModule().Resources[b]
   587  
   588  		if v := out.LoggingEnabled.TargetBucket; v == nil {
   589  			if tb.Primary.ID != "" {
   590  				return fmt.Errorf("bad target bucket, found nil, expected: %s", tb.Primary.ID)
   591  			}
   592  		} else {
   593  			if *v != tb.Primary.ID {
   594  				return fmt.Errorf("bad target bucket, expected: %s, got %s", tb.Primary.ID, *v)
   595  			}
   596  		}
   597  
   598  		if v := out.LoggingEnabled.TargetPrefix; v == nil {
   599  			if p != "" {
   600  				return fmt.Errorf("bad target prefix, found nil, expected: %s", p)
   601  			}
   602  		} else {
   603  			if *v != p {
   604  				return fmt.Errorf("bad target prefix, expected: %s, got %s", p, *v)
   605  			}
   606  		}
   607  
   608  		return nil
   609  	}
   610  }
   611  
   612  // These need a bit of randomness as the name can only be used once globally
   613  // within AWS
   614  func testAccWebsiteEndpoint(randInt int) string {
   615  	return fmt.Sprintf("tf-test-bucket-%d.s3-website-us-west-2.amazonaws.com", randInt)
   616  }
   617  
   618  func testAccAWSS3BucketPolicy(randInt int) string {
   619  	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)
   620  }
   621  
   622  func testAccAWSS3BucketConfig(randInt int) string {
   623  	return fmt.Sprintf(`
   624  resource "aws_s3_bucket" "bucket" {
   625  	bucket = "tf-test-bucket-%d"
   626  	acl = "public-read"
   627  }
   628  `, randInt)
   629  }
   630  
   631  func testAccAWSS3BucketWebsiteConfig(randInt int) string {
   632  	return fmt.Sprintf(`
   633  resource "aws_s3_bucket" "bucket" {
   634  	bucket = "tf-test-bucket-%d"
   635  	acl = "public-read"
   636  
   637  	website {
   638  		index_document = "index.html"
   639  	}
   640  }
   641  `, randInt)
   642  }
   643  
   644  func testAccAWSS3BucketWebsiteConfigWithError(randInt int) string {
   645  	return fmt.Sprintf(`
   646  resource "aws_s3_bucket" "bucket" {
   647  	bucket = "tf-test-bucket-%d"
   648  	acl = "public-read"
   649  
   650  	website {
   651  		index_document = "index.html"
   652  		error_document = "error.html"
   653  	}
   654  }
   655  `, randInt)
   656  }
   657  
   658  func testAccAWSS3BucketWebsiteConfigWithRedirect(randInt int) string {
   659  	return fmt.Sprintf(`
   660  resource "aws_s3_bucket" "bucket" {
   661  	bucket = "tf-test-bucket-%d"
   662  	acl = "public-read"
   663  
   664  	website {
   665  		redirect_all_requests_to = "hashicorp.com"
   666  	}
   667  }
   668  `, randInt)
   669  }
   670  
   671  func testAccAWSS3BucketWebsiteConfigWithHttpsRedirect(randInt int) string {
   672  	return fmt.Sprintf(`
   673  resource "aws_s3_bucket" "bucket" {
   674  	bucket = "tf-test-bucket-%d"
   675  	acl = "public-read"
   676  
   677  	website {
   678  		redirect_all_requests_to = "https://hashicorp.com"
   679  	}
   680  }
   681  `, randInt)
   682  }
   683  
   684  func testAccAWSS3BucketWebsiteConfigWithRoutingRules(randInt int) string {
   685  	return fmt.Sprintf(`
   686  resource "aws_s3_bucket" "bucket" {
   687  	bucket = "tf-test-bucket-%d"
   688  	acl = "public-read"
   689  
   690  	website {
   691  		index_document = "index.html"
   692  		error_document = "error.html"
   693  		routing_rules = <<EOF
   694  [{
   695  	"Condition": {
   696  		"KeyPrefixEquals": "docs/"
   697  	},
   698  	"Redirect": {
   699  		"ReplaceKeyPrefixWith": "documents/"
   700  	}
   701  }]
   702  EOF
   703  	}
   704  }
   705  `, randInt)
   706  }
   707  
   708  func testAccAWSS3BucketConfigWithPolicy(randInt int) string {
   709  	return fmt.Sprintf(`
   710  resource "aws_s3_bucket" "bucket" {
   711  	bucket = "tf-test-bucket-%d"
   712  	acl = "public-read"
   713  	policy = %s
   714  }
   715  `, randInt, strconv.Quote(testAccAWSS3BucketPolicy(randInt)))
   716  }
   717  
   718  func testAccAWSS3BucketDestroyedConfig(randInt int) string {
   719  	return fmt.Sprintf(`
   720  resource "aws_s3_bucket" "bucket" {
   721  	bucket = "tf-test-bucket-%d"
   722  	acl = "public-read"
   723  }
   724  `, randInt)
   725  }
   726  
   727  func testAccAWSS3BucketConfigWithVersioning(randInt int) string {
   728  	return fmt.Sprintf(`
   729  resource "aws_s3_bucket" "bucket" {
   730  	bucket = "tf-test-bucket-%d"
   731  	acl = "public-read"
   732  	versioning {
   733  	  enabled = true
   734  	}
   735  }
   736  `, randInt)
   737  }
   738  
   739  func testAccAWSS3BucketConfigWithDisableVersioning(randInt int) string {
   740  	return fmt.Sprintf(`
   741  resource "aws_s3_bucket" "bucket" {
   742  	bucket = "tf-test-bucket-%d"
   743  	acl = "public-read"
   744  	versioning {
   745  	  enabled = false
   746  	}
   747  }
   748  `, randInt)
   749  }
   750  
   751  func testAccAWSS3BucketConfigWithCORS(randInt int) string {
   752  	return fmt.Sprintf(`
   753  resource "aws_s3_bucket" "bucket" {
   754  	bucket = "tf-test-bucket-%d"
   755  	acl = "public-read"
   756  	cors_rule {
   757  			allowed_headers = ["*"]
   758  			allowed_methods = ["PUT","POST"]
   759  			allowed_origins = ["https://www.example.com"]
   760  			expose_headers = ["x-amz-server-side-encryption","ETag"]
   761  			max_age_seconds = 3000
   762  	}
   763  }
   764  `, randInt)
   765  }
   766  
   767  var testAccAWSS3BucketConfigWithAcl = `
   768  resource "aws_s3_bucket" "bucket" {
   769  	bucket = "tf-test-bucket-%d"
   770  	acl = "public-read"
   771  }
   772  `
   773  
   774  var testAccAWSS3BucketConfigWithAclUpdate = `
   775  resource "aws_s3_bucket" "bucket" {
   776  	bucket = "tf-test-bucket-%d"
   777  	acl = "private"
   778  }
   779  `
   780  
   781  func testAccAWSS3BucketConfigWithLogging(randInt int) string {
   782  	return fmt.Sprintf(`
   783  resource "aws_s3_bucket" "log_bucket" {
   784  	bucket = "tf-test-log-bucket-%d"
   785  	acl = "log-delivery-write"
   786  }
   787  resource "aws_s3_bucket" "bucket" {
   788  	bucket = "tf-test-bucket-%d"
   789  	acl = "private"
   790  	logging {
   791  		target_bucket = "${aws_s3_bucket.log_bucket.id}"
   792  		target_prefix = "log/"
   793  	}
   794  }
   795  `, randInt, randInt)
   796  }