github.com/minamijoyo/terraform@v0.7.8-0.20161029001309-18b3736ba44b/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 /* 28 IDRefreshName: "aws_s3_bucket.bucket", 29 IDRefreshIgnore: []string{"force_destroy"}, 30 */ 31 Providers: testAccProviders, 32 CheckDestroy: testAccCheckAWSS3BucketDestroy, 33 Steps: []resource.TestStep{ 34 resource.TestStep{ 35 Config: testAccAWSS3BucketConfig(rInt), 36 Check: resource.ComposeTestCheckFunc( 37 testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"), 38 resource.TestCheckResourceAttr( 39 "aws_s3_bucket.bucket", "hosted_zone_id", HostedZoneIDForRegion("us-west-2")), 40 resource.TestCheckResourceAttr( 41 "aws_s3_bucket.bucket", "region", "us-west-2"), 42 resource.TestCheckResourceAttr( 43 "aws_s3_bucket.bucket", "website_endpoint", ""), 44 resource.TestMatchResourceAttr( 45 "aws_s3_bucket.bucket", "arn", arnRegexp), 46 ), 47 }, 48 }, 49 }) 50 } 51 52 func TestAccAWSS3Bucket_acceleration(t *testing.T) { 53 rInt := acctest.RandInt() 54 55 resource.Test(t, resource.TestCase{ 56 PreCheck: func() { testAccPreCheck(t) }, 57 Providers: testAccProviders, 58 CheckDestroy: testAccCheckAWSS3BucketDestroy, 59 Steps: []resource.TestStep{ 60 resource.TestStep{ 61 Config: testAccAWSS3BucketConfigWithAcceleration(rInt), 62 Check: resource.ComposeTestCheckFunc( 63 testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"), 64 resource.TestCheckResourceAttr( 65 "aws_s3_bucket.bucket", "acceleration_status", "Enabled"), 66 ), 67 }, 68 resource.TestStep{ 69 Config: testAccAWSS3BucketConfigWithoutAcceleration(rInt), 70 Check: resource.ComposeTestCheckFunc( 71 testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"), 72 resource.TestCheckResourceAttr( 73 "aws_s3_bucket.bucket", "acceleration_status", "Suspended"), 74 ), 75 }, 76 }, 77 }) 78 } 79 80 func TestAccAWSS3Bucket_RequestPayer(t *testing.T) { 81 rInt := acctest.RandInt() 82 83 resource.Test(t, resource.TestCase{ 84 PreCheck: func() { testAccPreCheck(t) }, 85 Providers: testAccProviders, 86 CheckDestroy: testAccCheckAWSS3BucketDestroy, 87 Steps: []resource.TestStep{ 88 resource.TestStep{ 89 Config: testAccAWSS3BucketConfigRequestPayerBucketOwner(rInt), 90 Check: resource.ComposeTestCheckFunc( 91 testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"), 92 resource.TestCheckResourceAttr( 93 "aws_s3_bucket.bucket", 94 "request_payer", 95 "BucketOwner"), 96 testAccCheckAWSS3RequestPayer( 97 "aws_s3_bucket.bucket", 98 "BucketOwner"), 99 ), 100 }, 101 resource.TestStep{ 102 Config: testAccAWSS3BucketConfigRequestPayerRequester(rInt), 103 Check: resource.ComposeTestCheckFunc( 104 testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"), 105 resource.TestCheckResourceAttr( 106 "aws_s3_bucket.bucket", 107 "request_payer", 108 "Requester"), 109 testAccCheckAWSS3RequestPayer( 110 "aws_s3_bucket.bucket", 111 "Requester"), 112 ), 113 }, 114 }, 115 }) 116 } 117 118 func TestResourceAWSS3BucketRequestPayer_validation(t *testing.T) { 119 _, errors := validateS3BucketRequestPayerType("incorrect", "request_payer") 120 if len(errors) == 0 { 121 t.Fatalf("Expected to trigger a validation error") 122 } 123 124 var testCases = []struct { 125 Value string 126 ErrCount int 127 }{ 128 { 129 Value: "Requester", 130 ErrCount: 0, 131 }, 132 { 133 Value: "BucketOwner", 134 ErrCount: 0, 135 }, 136 } 137 138 for _, tc := range testCases { 139 _, errors := validateS3BucketRequestPayerType(tc.Value, "request_payer") 140 if len(errors) != tc.ErrCount { 141 t.Fatalf("Expected not to trigger a validation error") 142 } 143 } 144 } 145 146 func TestAccAWSS3Bucket_Policy(t *testing.T) { 147 rInt := acctest.RandInt() 148 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: testAccAWSS3BucketConfigWithPolicy(rInt), 156 Check: resource.ComposeTestCheckFunc( 157 testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"), 158 testAccCheckAWSS3BucketPolicy( 159 "aws_s3_bucket.bucket", testAccAWSS3BucketPolicy(rInt)), 160 ), 161 }, 162 resource.TestStep{ 163 Config: testAccAWSS3BucketConfig(rInt), 164 Check: resource.ComposeTestCheckFunc( 165 testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"), 166 testAccCheckAWSS3BucketPolicy( 167 "aws_s3_bucket.bucket", ""), 168 ), 169 }, 170 resource.TestStep{ 171 Config: testAccAWSS3BucketConfigWithEmptyPolicy(rInt), 172 Check: resource.ComposeTestCheckFunc( 173 testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"), 174 testAccCheckAWSS3BucketPolicy( 175 "aws_s3_bucket.bucket", ""), 176 ), 177 }, 178 }, 179 }) 180 } 181 182 func TestAccAWSS3Bucket_UpdateAcl(t *testing.T) { 183 ri := acctest.RandInt() 184 preConfig := fmt.Sprintf(testAccAWSS3BucketConfigWithAcl, ri) 185 postConfig := fmt.Sprintf(testAccAWSS3BucketConfigWithAclUpdate, ri) 186 187 resource.Test(t, resource.TestCase{ 188 PreCheck: func() { testAccPreCheck(t) }, 189 Providers: testAccProviders, 190 CheckDestroy: testAccCheckAWSS3BucketDestroy, 191 Steps: []resource.TestStep{ 192 resource.TestStep{ 193 Config: preConfig, 194 Check: resource.ComposeTestCheckFunc( 195 testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"), 196 resource.TestCheckResourceAttr( 197 "aws_s3_bucket.bucket", "acl", "public-read"), 198 ), 199 }, 200 resource.TestStep{ 201 Config: postConfig, 202 Check: resource.ComposeTestCheckFunc( 203 testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"), 204 resource.TestCheckResourceAttr( 205 "aws_s3_bucket.bucket", "acl", "private"), 206 ), 207 }, 208 }, 209 }) 210 } 211 212 func TestAccAWSS3Bucket_Website_Simple(t *testing.T) { 213 rInt := acctest.RandInt() 214 resource.Test(t, resource.TestCase{ 215 PreCheck: func() { testAccPreCheck(t) }, 216 Providers: testAccProviders, 217 CheckDestroy: testAccCheckAWSS3BucketDestroy, 218 Steps: []resource.TestStep{ 219 resource.TestStep{ 220 Config: testAccAWSS3BucketWebsiteConfig(rInt), 221 Check: resource.ComposeTestCheckFunc( 222 testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"), 223 testAccCheckAWSS3BucketWebsite( 224 "aws_s3_bucket.bucket", "index.html", "", "", ""), 225 resource.TestCheckResourceAttr( 226 "aws_s3_bucket.bucket", "website_endpoint", testAccWebsiteEndpoint(rInt)), 227 ), 228 }, 229 resource.TestStep{ 230 Config: testAccAWSS3BucketWebsiteConfigWithError(rInt), 231 Check: resource.ComposeTestCheckFunc( 232 testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"), 233 testAccCheckAWSS3BucketWebsite( 234 "aws_s3_bucket.bucket", "index.html", "error.html", "", ""), 235 resource.TestCheckResourceAttr( 236 "aws_s3_bucket.bucket", "website_endpoint", testAccWebsiteEndpoint(rInt)), 237 ), 238 }, 239 resource.TestStep{ 240 Config: testAccAWSS3BucketConfig(rInt), 241 Check: resource.ComposeTestCheckFunc( 242 testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"), 243 testAccCheckAWSS3BucketWebsite( 244 "aws_s3_bucket.bucket", "", "", "", ""), 245 resource.TestCheckResourceAttr( 246 "aws_s3_bucket.bucket", "website_endpoint", ""), 247 ), 248 }, 249 }, 250 }) 251 } 252 253 func TestAccAWSS3Bucket_WebsiteRedirect(t *testing.T) { 254 rInt := acctest.RandInt() 255 resource.Test(t, resource.TestCase{ 256 PreCheck: func() { testAccPreCheck(t) }, 257 Providers: testAccProviders, 258 CheckDestroy: testAccCheckAWSS3BucketDestroy, 259 Steps: []resource.TestStep{ 260 resource.TestStep{ 261 Config: testAccAWSS3BucketWebsiteConfigWithRedirect(rInt), 262 Check: resource.ComposeTestCheckFunc( 263 testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"), 264 testAccCheckAWSS3BucketWebsite( 265 "aws_s3_bucket.bucket", "", "", "", "hashicorp.com"), 266 resource.TestCheckResourceAttr( 267 "aws_s3_bucket.bucket", "website_endpoint", testAccWebsiteEndpoint(rInt)), 268 ), 269 }, 270 resource.TestStep{ 271 Config: testAccAWSS3BucketWebsiteConfigWithHttpsRedirect(rInt), 272 Check: resource.ComposeTestCheckFunc( 273 testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"), 274 testAccCheckAWSS3BucketWebsite( 275 "aws_s3_bucket.bucket", "", "", "https", "hashicorp.com"), 276 resource.TestCheckResourceAttr( 277 "aws_s3_bucket.bucket", "website_endpoint", testAccWebsiteEndpoint(rInt)), 278 ), 279 }, 280 resource.TestStep{ 281 Config: testAccAWSS3BucketConfig(rInt), 282 Check: resource.ComposeTestCheckFunc( 283 testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"), 284 testAccCheckAWSS3BucketWebsite( 285 "aws_s3_bucket.bucket", "", "", "", ""), 286 resource.TestCheckResourceAttr( 287 "aws_s3_bucket.bucket", "website_endpoint", ""), 288 ), 289 }, 290 }, 291 }) 292 } 293 294 func TestAccAWSS3Bucket_WebsiteRoutingRules(t *testing.T) { 295 rInt := acctest.RandInt() 296 resource.Test(t, resource.TestCase{ 297 PreCheck: func() { testAccPreCheck(t) }, 298 Providers: testAccProviders, 299 CheckDestroy: testAccCheckAWSS3BucketDestroy, 300 Steps: []resource.TestStep{ 301 resource.TestStep{ 302 Config: testAccAWSS3BucketWebsiteConfigWithRoutingRules(rInt), 303 Check: resource.ComposeTestCheckFunc( 304 testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"), 305 testAccCheckAWSS3BucketWebsite( 306 "aws_s3_bucket.bucket", "index.html", "error.html", "", ""), 307 testAccCheckAWSS3BucketWebsiteRoutingRules( 308 "aws_s3_bucket.bucket", 309 []*s3.RoutingRule{ 310 &s3.RoutingRule{ 311 Condition: &s3.Condition{ 312 KeyPrefixEquals: aws.String("docs/"), 313 }, 314 Redirect: &s3.Redirect{ 315 ReplaceKeyPrefixWith: aws.String("documents/"), 316 }, 317 }, 318 }, 319 ), 320 resource.TestCheckResourceAttr( 321 "aws_s3_bucket.bucket", "website_endpoint", testAccWebsiteEndpoint(rInt)), 322 ), 323 }, 324 resource.TestStep{ 325 Config: testAccAWSS3BucketConfig(rInt), 326 Check: resource.ComposeTestCheckFunc( 327 testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"), 328 testAccCheckAWSS3BucketWebsite( 329 "aws_s3_bucket.bucket", "", "", "", ""), 330 testAccCheckAWSS3BucketWebsiteRoutingRules("aws_s3_bucket.bucket", nil), 331 resource.TestCheckResourceAttr( 332 "aws_s3_bucket.bucket", "website_endpoint", ""), 333 ), 334 }, 335 }, 336 }) 337 } 338 339 // Test TestAccAWSS3Bucket_shouldFailNotFound is designed to fail with a "plan 340 // not empty" error in Terraform, to check against regresssions. 341 // See https://github.com/hashicorp/terraform/pull/2925 342 func TestAccAWSS3Bucket_shouldFailNotFound(t *testing.T) { 343 rInt := acctest.RandInt() 344 resource.Test(t, resource.TestCase{ 345 PreCheck: func() { testAccPreCheck(t) }, 346 Providers: testAccProviders, 347 CheckDestroy: testAccCheckAWSS3BucketDestroy, 348 Steps: []resource.TestStep{ 349 resource.TestStep{ 350 Config: testAccAWSS3BucketDestroyedConfig(rInt), 351 Check: resource.ComposeTestCheckFunc( 352 testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"), 353 testAccCheckAWSS3DestroyBucket("aws_s3_bucket.bucket"), 354 ), 355 ExpectNonEmptyPlan: true, 356 }, 357 }, 358 }) 359 } 360 361 func TestAccAWSS3Bucket_Versioning(t *testing.T) { 362 rInt := acctest.RandInt() 363 resource.Test(t, resource.TestCase{ 364 PreCheck: func() { testAccPreCheck(t) }, 365 Providers: testAccProviders, 366 CheckDestroy: testAccCheckAWSS3BucketDestroy, 367 Steps: []resource.TestStep{ 368 resource.TestStep{ 369 Config: testAccAWSS3BucketConfig(rInt), 370 Check: resource.ComposeTestCheckFunc( 371 testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"), 372 testAccCheckAWSS3BucketVersioning( 373 "aws_s3_bucket.bucket", ""), 374 ), 375 }, 376 resource.TestStep{ 377 Config: testAccAWSS3BucketConfigWithVersioning(rInt), 378 Check: resource.ComposeTestCheckFunc( 379 testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"), 380 testAccCheckAWSS3BucketVersioning( 381 "aws_s3_bucket.bucket", s3.BucketVersioningStatusEnabled), 382 ), 383 }, 384 resource.TestStep{ 385 Config: testAccAWSS3BucketConfigWithDisableVersioning(rInt), 386 Check: resource.ComposeTestCheckFunc( 387 testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"), 388 testAccCheckAWSS3BucketVersioning( 389 "aws_s3_bucket.bucket", s3.BucketVersioningStatusSuspended), 390 ), 391 }, 392 }, 393 }) 394 } 395 396 func TestAccAWSS3Bucket_Cors(t *testing.T) { 397 rInt := acctest.RandInt() 398 399 updateBucketCors := func(n string) resource.TestCheckFunc { 400 return func(s *terraform.State) error { 401 rs, ok := s.RootModule().Resources[n] 402 if !ok { 403 return fmt.Errorf("Not found: %s", n) 404 } 405 406 conn := testAccProvider.Meta().(*AWSClient).s3conn 407 _, err := conn.PutBucketCors(&s3.PutBucketCorsInput{ 408 Bucket: aws.String(rs.Primary.ID), 409 CORSConfiguration: &s3.CORSConfiguration{ 410 CORSRules: []*s3.CORSRule{ 411 &s3.CORSRule{ 412 AllowedHeaders: []*string{aws.String("*")}, 413 AllowedMethods: []*string{aws.String("GET")}, 414 AllowedOrigins: []*string{aws.String("https://www.example.com")}, 415 }, 416 }, 417 }, 418 }) 419 if err != nil { 420 if awsErr, ok := err.(awserr.Error); ok && awsErr.Code() != "NoSuchCORSConfiguration" { 421 return err 422 } 423 } 424 return nil 425 } 426 } 427 428 resource.Test(t, resource.TestCase{ 429 PreCheck: func() { testAccPreCheck(t) }, 430 Providers: testAccProviders, 431 CheckDestroy: testAccCheckAWSS3BucketDestroy, 432 Steps: []resource.TestStep{ 433 resource.TestStep{ 434 Config: testAccAWSS3BucketConfigWithCORS(rInt), 435 Check: resource.ComposeTestCheckFunc( 436 testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"), 437 testAccCheckAWSS3BucketCors( 438 "aws_s3_bucket.bucket", 439 []*s3.CORSRule{ 440 &s3.CORSRule{ 441 AllowedHeaders: []*string{aws.String("*")}, 442 AllowedMethods: []*string{aws.String("PUT"), aws.String("POST")}, 443 AllowedOrigins: []*string{aws.String("https://www.example.com")}, 444 ExposeHeaders: []*string{aws.String("x-amz-server-side-encryption"), aws.String("ETag")}, 445 MaxAgeSeconds: aws.Int64(3000), 446 }, 447 }, 448 ), 449 updateBucketCors("aws_s3_bucket.bucket"), 450 ), 451 ExpectNonEmptyPlan: true, 452 }, 453 resource.TestStep{ 454 Config: testAccAWSS3BucketConfigWithCORS(rInt), 455 Check: resource.ComposeTestCheckFunc( 456 testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"), 457 testAccCheckAWSS3BucketCors( 458 "aws_s3_bucket.bucket", 459 []*s3.CORSRule{ 460 &s3.CORSRule{ 461 AllowedHeaders: []*string{aws.String("*")}, 462 AllowedMethods: []*string{aws.String("PUT"), aws.String("POST")}, 463 AllowedOrigins: []*string{aws.String("https://www.example.com")}, 464 ExposeHeaders: []*string{aws.String("x-amz-server-side-encryption"), aws.String("ETag")}, 465 MaxAgeSeconds: aws.Int64(3000), 466 }, 467 }, 468 ), 469 ), 470 }, 471 }, 472 }) 473 } 474 475 func TestAccAWSS3Bucket_Logging(t *testing.T) { 476 rInt := acctest.RandInt() 477 resource.Test(t, resource.TestCase{ 478 PreCheck: func() { testAccPreCheck(t) }, 479 Providers: testAccProviders, 480 CheckDestroy: testAccCheckAWSS3BucketDestroy, 481 Steps: []resource.TestStep{ 482 resource.TestStep{ 483 Config: testAccAWSS3BucketConfigWithLogging(rInt), 484 Check: resource.ComposeTestCheckFunc( 485 testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"), 486 testAccCheckAWSS3BucketLogging( 487 "aws_s3_bucket.bucket", "aws_s3_bucket.log_bucket", "log/"), 488 ), 489 }, 490 }, 491 }) 492 } 493 494 func TestAccAWSS3Bucket_Lifecycle(t *testing.T) { 495 rInt := acctest.RandInt() 496 resource.Test(t, resource.TestCase{ 497 PreCheck: func() { testAccPreCheck(t) }, 498 Providers: testAccProviders, 499 CheckDestroy: testAccCheckAWSS3BucketDestroy, 500 Steps: []resource.TestStep{ 501 resource.TestStep{ 502 Config: testAccAWSS3BucketConfigWithLifecycle(rInt), 503 Check: resource.ComposeTestCheckFunc( 504 testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"), 505 resource.TestCheckResourceAttr( 506 "aws_s3_bucket.bucket", "lifecycle_rule.0.id", "id1"), 507 resource.TestCheckResourceAttr( 508 "aws_s3_bucket.bucket", "lifecycle_rule.0.prefix", "path1/"), 509 resource.TestCheckResourceAttr( 510 "aws_s3_bucket.bucket", "lifecycle_rule.0.expiration.2613713285.days", "365"), 511 resource.TestCheckResourceAttr( 512 "aws_s3_bucket.bucket", "lifecycle_rule.0.expiration.2613713285.date", ""), 513 resource.TestCheckResourceAttr( 514 "aws_s3_bucket.bucket", "lifecycle_rule.0.expiration.2613713285.expired_object_delete_marker", "false"), 515 resource.TestCheckResourceAttr( 516 "aws_s3_bucket.bucket", "lifecycle_rule.0.transition.2000431762.date", ""), 517 resource.TestCheckResourceAttr( 518 "aws_s3_bucket.bucket", "lifecycle_rule.0.transition.2000431762.days", "30"), 519 resource.TestCheckResourceAttr( 520 "aws_s3_bucket.bucket", "lifecycle_rule.0.transition.2000431762.storage_class", "STANDARD_IA"), 521 resource.TestCheckResourceAttr( 522 "aws_s3_bucket.bucket", "lifecycle_rule.0.transition.6450812.date", ""), 523 resource.TestCheckResourceAttr( 524 "aws_s3_bucket.bucket", "lifecycle_rule.0.transition.6450812.days", "60"), 525 resource.TestCheckResourceAttr( 526 "aws_s3_bucket.bucket", "lifecycle_rule.0.transition.6450812.storage_class", "GLACIER"), 527 resource.TestCheckResourceAttr( 528 "aws_s3_bucket.bucket", "lifecycle_rule.1.id", "id2"), 529 resource.TestCheckResourceAttr( 530 "aws_s3_bucket.bucket", "lifecycle_rule.1.prefix", "path2/"), 531 resource.TestCheckResourceAttr( 532 "aws_s3_bucket.bucket", "lifecycle_rule.1.expiration.2855832418.date", "2016-01-12"), 533 resource.TestCheckResourceAttr( 534 "aws_s3_bucket.bucket", "lifecycle_rule.1.expiration.2855832418.days", "0"), 535 resource.TestCheckResourceAttr( 536 "aws_s3_bucket.bucket", "lifecycle_rule.1.expiration.2855832418.expired_object_delete_marker", "false"), 537 ), 538 }, 539 resource.TestStep{ 540 Config: testAccAWSS3BucketConfigWithVersioningLifecycle(rInt), 541 Check: resource.ComposeTestCheckFunc( 542 testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"), 543 resource.TestCheckResourceAttr( 544 "aws_s3_bucket.bucket", "lifecycle_rule.0.id", "id1"), 545 resource.TestCheckResourceAttr( 546 "aws_s3_bucket.bucket", "lifecycle_rule.0.prefix", "path1/"), 547 resource.TestCheckResourceAttr( 548 "aws_s3_bucket.bucket", "lifecycle_rule.0.enabled", "true"), 549 resource.TestCheckResourceAttr( 550 "aws_s3_bucket.bucket", "lifecycle_rule.0.noncurrent_version_expiration.80908210.days", "365"), 551 resource.TestCheckResourceAttr( 552 "aws_s3_bucket.bucket", "lifecycle_rule.0.noncurrent_version_transition.1377917700.days", "30"), 553 resource.TestCheckResourceAttr( 554 "aws_s3_bucket.bucket", "lifecycle_rule.0.noncurrent_version_transition.1377917700.storage_class", "STANDARD_IA"), 555 resource.TestCheckResourceAttr( 556 "aws_s3_bucket.bucket", "lifecycle_rule.0.noncurrent_version_transition.2528035817.days", "60"), 557 resource.TestCheckResourceAttr( 558 "aws_s3_bucket.bucket", "lifecycle_rule.0.noncurrent_version_transition.2528035817.storage_class", "GLACIER"), 559 resource.TestCheckResourceAttr( 560 "aws_s3_bucket.bucket", "lifecycle_rule.1.id", "id2"), 561 resource.TestCheckResourceAttr( 562 "aws_s3_bucket.bucket", "lifecycle_rule.1.prefix", "path2/"), 563 resource.TestCheckResourceAttr( 564 "aws_s3_bucket.bucket", "lifecycle_rule.1.enabled", "false"), 565 resource.TestCheckResourceAttr( 566 "aws_s3_bucket.bucket", "lifecycle_rule.1.noncurrent_version_expiration.80908210.days", "365"), 567 ), 568 }, 569 resource.TestStep{ 570 Config: testAccAWSS3BucketConfig(rInt), 571 Check: resource.ComposeTestCheckFunc( 572 testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"), 573 ), 574 }, 575 }, 576 }) 577 } 578 579 func testAccCheckAWSS3BucketDestroy(s *terraform.State) error { 580 conn := testAccProvider.Meta().(*AWSClient).s3conn 581 582 for _, rs := range s.RootModule().Resources { 583 if rs.Type != "aws_s3_bucket" { 584 continue 585 } 586 _, err := conn.DeleteBucket(&s3.DeleteBucketInput{ 587 Bucket: aws.String(rs.Primary.ID), 588 }) 589 if err != nil { 590 if awsErr, ok := err.(awserr.Error); ok && awsErr.Code() == "NoSuchBucket" { 591 return nil 592 } 593 return err 594 } 595 } 596 return nil 597 } 598 599 func testAccCheckAWSS3BucketExists(n string) resource.TestCheckFunc { 600 return func(s *terraform.State) error { 601 rs, ok := s.RootModule().Resources[n] 602 if !ok { 603 return fmt.Errorf("Not found: %s", n) 604 } 605 606 if rs.Primary.ID == "" { 607 return fmt.Errorf("No S3 Bucket ID is set") 608 } 609 610 conn := testAccProvider.Meta().(*AWSClient).s3conn 611 _, err := conn.HeadBucket(&s3.HeadBucketInput{ 612 Bucket: aws.String(rs.Primary.ID), 613 }) 614 615 if err != nil { 616 return fmt.Errorf("S3Bucket error: %v", err) 617 } 618 return nil 619 } 620 } 621 622 func testAccCheckAWSS3DestroyBucket(n string) resource.TestCheckFunc { 623 return func(s *terraform.State) error { 624 rs, ok := s.RootModule().Resources[n] 625 if !ok { 626 return fmt.Errorf("Not found: %s", n) 627 } 628 629 if rs.Primary.ID == "" { 630 return fmt.Errorf("No S3 Bucket ID is set") 631 } 632 633 conn := testAccProvider.Meta().(*AWSClient).s3conn 634 _, err := conn.DeleteBucket(&s3.DeleteBucketInput{ 635 Bucket: aws.String(rs.Primary.ID), 636 }) 637 638 if err != nil { 639 return fmt.Errorf("Error destroying Bucket (%s) in testAccCheckAWSS3DestroyBucket: %s", rs.Primary.ID, err) 640 } 641 return nil 642 } 643 } 644 645 func testAccCheckAWSS3BucketPolicy(n string, policy string) resource.TestCheckFunc { 646 return func(s *terraform.State) error { 647 rs, _ := s.RootModule().Resources[n] 648 conn := testAccProvider.Meta().(*AWSClient).s3conn 649 650 out, err := conn.GetBucketPolicy(&s3.GetBucketPolicyInput{ 651 Bucket: aws.String(rs.Primary.ID), 652 }) 653 654 if policy == "" { 655 if awsErr, ok := err.(awserr.Error); ok && awsErr.Code() == "NoSuchBucketPolicy" { 656 // expected 657 return nil 658 } 659 if err == nil { 660 return fmt.Errorf("Expected no policy, got: %#v", *out.Policy) 661 } else { 662 return fmt.Errorf("GetBucketPolicy error: %v, expected %s", err, policy) 663 } 664 } 665 if err != nil { 666 return fmt.Errorf("GetBucketPolicy error: %v, expected %s", err, policy) 667 } 668 669 if v := out.Policy; v == nil { 670 if policy != "" { 671 return fmt.Errorf("bad policy, found nil, expected: %s", policy) 672 } 673 } else { 674 expected := make(map[string]interface{}) 675 if err := json.Unmarshal([]byte(policy), &expected); err != nil { 676 return err 677 } 678 actual := make(map[string]interface{}) 679 if err := json.Unmarshal([]byte(*v), &actual); err != nil { 680 return err 681 } 682 683 if !reflect.DeepEqual(expected, actual) { 684 return fmt.Errorf("bad policy, expected: %#v, got %#v", expected, actual) 685 } 686 } 687 688 return nil 689 } 690 } 691 692 func testAccCheckAWSS3BucketWebsite(n string, indexDoc string, errorDoc string, redirectProtocol string, redirectTo string) resource.TestCheckFunc { 693 return func(s *terraform.State) error { 694 rs, _ := s.RootModule().Resources[n] 695 conn := testAccProvider.Meta().(*AWSClient).s3conn 696 697 out, err := conn.GetBucketWebsite(&s3.GetBucketWebsiteInput{ 698 Bucket: aws.String(rs.Primary.ID), 699 }) 700 701 if err != nil { 702 if indexDoc == "" { 703 // If we want to assert that the website is not there, than 704 // this error is expected 705 return nil 706 } else { 707 return fmt.Errorf("S3BucketWebsite error: %v", err) 708 } 709 } 710 711 if v := out.IndexDocument; v == nil { 712 if indexDoc != "" { 713 return fmt.Errorf("bad index doc, found nil, expected: %s", indexDoc) 714 } 715 } else { 716 if *v.Suffix != indexDoc { 717 return fmt.Errorf("bad index doc, expected: %s, got %#v", indexDoc, out.IndexDocument) 718 } 719 } 720 721 if v := out.ErrorDocument; v == nil { 722 if errorDoc != "" { 723 return fmt.Errorf("bad error doc, found nil, expected: %s", errorDoc) 724 } 725 } else { 726 if *v.Key != errorDoc { 727 return fmt.Errorf("bad error doc, expected: %s, got %#v", errorDoc, out.ErrorDocument) 728 } 729 } 730 731 if v := out.RedirectAllRequestsTo; v == nil { 732 if redirectTo != "" { 733 return fmt.Errorf("bad redirect to, found nil, expected: %s", redirectTo) 734 } 735 } else { 736 if *v.HostName != redirectTo { 737 return fmt.Errorf("bad redirect to, expected: %s, got %#v", redirectTo, out.RedirectAllRequestsTo) 738 } 739 if redirectProtocol != "" && v.Protocol != nil && *v.Protocol != redirectProtocol { 740 return fmt.Errorf("bad redirect protocol to, expected: %s, got %#v", redirectProtocol, out.RedirectAllRequestsTo) 741 } 742 } 743 744 return nil 745 } 746 } 747 748 func testAccCheckAWSS3BucketWebsiteRoutingRules(n string, routingRules []*s3.RoutingRule) resource.TestCheckFunc { 749 return func(s *terraform.State) error { 750 rs, _ := s.RootModule().Resources[n] 751 conn := testAccProvider.Meta().(*AWSClient).s3conn 752 753 out, err := conn.GetBucketWebsite(&s3.GetBucketWebsiteInput{ 754 Bucket: aws.String(rs.Primary.ID), 755 }) 756 757 if err != nil { 758 if routingRules == nil { 759 return nil 760 } 761 return fmt.Errorf("GetBucketWebsite error: %v", err) 762 } 763 764 if !reflect.DeepEqual(out.RoutingRules, routingRules) { 765 return fmt.Errorf("bad routing rule, expected: %v, got %v", routingRules, out.RoutingRules) 766 } 767 768 return nil 769 } 770 } 771 772 func testAccCheckAWSS3BucketVersioning(n string, versioningStatus string) resource.TestCheckFunc { 773 return func(s *terraform.State) error { 774 rs, _ := s.RootModule().Resources[n] 775 conn := testAccProvider.Meta().(*AWSClient).s3conn 776 777 out, err := conn.GetBucketVersioning(&s3.GetBucketVersioningInput{ 778 Bucket: aws.String(rs.Primary.ID), 779 }) 780 781 if err != nil { 782 return fmt.Errorf("GetBucketVersioning error: %v", err) 783 } 784 785 if v := out.Status; v == nil { 786 if versioningStatus != "" { 787 return fmt.Errorf("bad error versioning status, found nil, expected: %s", versioningStatus) 788 } 789 } else { 790 if *v != versioningStatus { 791 return fmt.Errorf("bad error versioning status, expected: %s, got %s", versioningStatus, *v) 792 } 793 } 794 795 return nil 796 } 797 } 798 799 func testAccCheckAWSS3BucketCors(n string, corsRules []*s3.CORSRule) resource.TestCheckFunc { 800 return func(s *terraform.State) error { 801 rs, _ := s.RootModule().Resources[n] 802 conn := testAccProvider.Meta().(*AWSClient).s3conn 803 804 out, err := conn.GetBucketCors(&s3.GetBucketCorsInput{ 805 Bucket: aws.String(rs.Primary.ID), 806 }) 807 808 if err != nil { 809 return fmt.Errorf("GetBucketCors error: %v", err) 810 } 811 812 if !reflect.DeepEqual(out.CORSRules, corsRules) { 813 return fmt.Errorf("bad error cors rule, expected: %v, got %v", corsRules, out.CORSRules) 814 } 815 816 return nil 817 } 818 } 819 820 func testAccCheckAWSS3RequestPayer(n, expectedPayer string) resource.TestCheckFunc { 821 return func(s *terraform.State) error { 822 rs, _ := s.RootModule().Resources[n] 823 conn := testAccProvider.Meta().(*AWSClient).s3conn 824 825 out, err := conn.GetBucketRequestPayment(&s3.GetBucketRequestPaymentInput{ 826 Bucket: aws.String(rs.Primary.ID), 827 }) 828 829 if err != nil { 830 return fmt.Errorf("GetBucketRequestPayment error: %v", err) 831 } 832 833 if *out.Payer != expectedPayer { 834 return fmt.Errorf("bad error request payer type, expected: %v, got %v", 835 expectedPayer, out.Payer) 836 } 837 838 return nil 839 } 840 } 841 842 func testAccCheckAWSS3BucketLogging(n, b, p string) resource.TestCheckFunc { 843 return func(s *terraform.State) error { 844 rs, _ := s.RootModule().Resources[n] 845 conn := testAccProvider.Meta().(*AWSClient).s3conn 846 847 out, err := conn.GetBucketLogging(&s3.GetBucketLoggingInput{ 848 Bucket: aws.String(rs.Primary.ID), 849 }) 850 851 if err != nil { 852 return fmt.Errorf("GetBucketLogging error: %v", err) 853 } 854 855 tb, _ := s.RootModule().Resources[b] 856 857 if v := out.LoggingEnabled.TargetBucket; v == nil { 858 if tb.Primary.ID != "" { 859 return fmt.Errorf("bad target bucket, found nil, expected: %s", tb.Primary.ID) 860 } 861 } else { 862 if *v != tb.Primary.ID { 863 return fmt.Errorf("bad target bucket, expected: %s, got %s", tb.Primary.ID, *v) 864 } 865 } 866 867 if v := out.LoggingEnabled.TargetPrefix; v == nil { 868 if p != "" { 869 return fmt.Errorf("bad target prefix, found nil, expected: %s", p) 870 } 871 } else { 872 if *v != p { 873 return fmt.Errorf("bad target prefix, expected: %s, got %s", p, *v) 874 } 875 } 876 877 return nil 878 } 879 } 880 881 // These need a bit of randomness as the name can only be used once globally 882 // within AWS 883 func testAccWebsiteEndpoint(randInt int) string { 884 return fmt.Sprintf("tf-test-bucket-%d.s3-website-us-west-2.amazonaws.com", randInt) 885 } 886 887 func testAccAWSS3BucketPolicy(randInt int) string { 888 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) 889 } 890 891 func testAccAWSS3BucketConfig(randInt int) string { 892 return fmt.Sprintf(` 893 resource "aws_s3_bucket" "bucket" { 894 bucket = "tf-test-bucket-%d" 895 acl = "public-read" 896 } 897 `, randInt) 898 } 899 900 func testAccAWSS3BucketWebsiteConfig(randInt int) string { 901 return fmt.Sprintf(` 902 resource "aws_s3_bucket" "bucket" { 903 bucket = "tf-test-bucket-%d" 904 acl = "public-read" 905 906 website { 907 index_document = "index.html" 908 } 909 } 910 `, randInt) 911 } 912 913 func testAccAWSS3BucketWebsiteConfigWithError(randInt int) string { 914 return fmt.Sprintf(` 915 resource "aws_s3_bucket" "bucket" { 916 bucket = "tf-test-bucket-%d" 917 acl = "public-read" 918 919 website { 920 index_document = "index.html" 921 error_document = "error.html" 922 } 923 } 924 `, randInt) 925 } 926 927 func testAccAWSS3BucketWebsiteConfigWithRedirect(randInt int) string { 928 return fmt.Sprintf(` 929 resource "aws_s3_bucket" "bucket" { 930 bucket = "tf-test-bucket-%d" 931 acl = "public-read" 932 933 website { 934 redirect_all_requests_to = "hashicorp.com" 935 } 936 } 937 `, randInt) 938 } 939 940 func testAccAWSS3BucketWebsiteConfigWithHttpsRedirect(randInt int) string { 941 return fmt.Sprintf(` 942 resource "aws_s3_bucket" "bucket" { 943 bucket = "tf-test-bucket-%d" 944 acl = "public-read" 945 946 website { 947 redirect_all_requests_to = "https://hashicorp.com" 948 } 949 } 950 `, randInt) 951 } 952 953 func testAccAWSS3BucketWebsiteConfigWithRoutingRules(randInt int) string { 954 return fmt.Sprintf(` 955 resource "aws_s3_bucket" "bucket" { 956 bucket = "tf-test-bucket-%d" 957 acl = "public-read" 958 959 website { 960 index_document = "index.html" 961 error_document = "error.html" 962 routing_rules = <<EOF 963 [{ 964 "Condition": { 965 "KeyPrefixEquals": "docs/" 966 }, 967 "Redirect": { 968 "ReplaceKeyPrefixWith": "documents/" 969 } 970 }] 971 EOF 972 } 973 } 974 `, randInt) 975 } 976 977 func testAccAWSS3BucketConfigWithAcceleration(randInt int) string { 978 return fmt.Sprintf(` 979 resource "aws_s3_bucket" "bucket" { 980 bucket = "tf-test-bucket-%d" 981 acl = "public-read" 982 acceleration_status = "Enabled" 983 } 984 `, randInt) 985 } 986 987 func testAccAWSS3BucketConfigWithoutAcceleration(randInt int) string { 988 return fmt.Sprintf(` 989 resource "aws_s3_bucket" "bucket" { 990 bucket = "tf-test-bucket-%d" 991 acl = "public-read" 992 acceleration_status = "Suspended" 993 } 994 `, randInt) 995 } 996 997 func testAccAWSS3BucketConfigRequestPayerBucketOwner(randInt int) string { 998 return fmt.Sprintf(` 999 resource "aws_s3_bucket" "bucket" { 1000 bucket = "tf-test-bucket-%d" 1001 acl = "public-read" 1002 request_payer = "BucketOwner" 1003 } 1004 `, randInt) 1005 } 1006 1007 func testAccAWSS3BucketConfigRequestPayerRequester(randInt int) string { 1008 return fmt.Sprintf(` 1009 resource "aws_s3_bucket" "bucket" { 1010 bucket = "tf-test-bucket-%d" 1011 acl = "public-read" 1012 request_payer = "Requester" 1013 } 1014 `, randInt) 1015 } 1016 1017 func testAccAWSS3BucketConfigWithPolicy(randInt int) string { 1018 return fmt.Sprintf(` 1019 resource "aws_s3_bucket" "bucket" { 1020 bucket = "tf-test-bucket-%d" 1021 acl = "public-read" 1022 policy = %s 1023 } 1024 `, randInt, strconv.Quote(testAccAWSS3BucketPolicy(randInt))) 1025 } 1026 1027 func testAccAWSS3BucketDestroyedConfig(randInt int) string { 1028 return fmt.Sprintf(` 1029 resource "aws_s3_bucket" "bucket" { 1030 bucket = "tf-test-bucket-%d" 1031 acl = "public-read" 1032 } 1033 `, randInt) 1034 } 1035 1036 func testAccAWSS3BucketConfigWithEmptyPolicy(randInt int) string { 1037 return fmt.Sprintf(` 1038 resource "aws_s3_bucket" "bucket" { 1039 bucket = "tf-test-bucket-%d" 1040 acl = "public-read" 1041 policy = "" 1042 } 1043 `, randInt) 1044 } 1045 1046 func testAccAWSS3BucketConfigWithVersioning(randInt int) string { 1047 return fmt.Sprintf(` 1048 resource "aws_s3_bucket" "bucket" { 1049 bucket = "tf-test-bucket-%d" 1050 acl = "public-read" 1051 versioning { 1052 enabled = true 1053 } 1054 } 1055 `, randInt) 1056 } 1057 1058 func testAccAWSS3BucketConfigWithDisableVersioning(randInt int) string { 1059 return fmt.Sprintf(` 1060 resource "aws_s3_bucket" "bucket" { 1061 bucket = "tf-test-bucket-%d" 1062 acl = "public-read" 1063 versioning { 1064 enabled = false 1065 } 1066 } 1067 `, randInt) 1068 } 1069 1070 func testAccAWSS3BucketConfigWithCORS(randInt int) string { 1071 return fmt.Sprintf(` 1072 resource "aws_s3_bucket" "bucket" { 1073 bucket = "tf-test-bucket-%d" 1074 acl = "public-read" 1075 cors_rule { 1076 allowed_headers = ["*"] 1077 allowed_methods = ["PUT","POST"] 1078 allowed_origins = ["https://www.example.com"] 1079 expose_headers = ["x-amz-server-side-encryption","ETag"] 1080 max_age_seconds = 3000 1081 } 1082 } 1083 `, randInt) 1084 } 1085 1086 var testAccAWSS3BucketConfigWithAcl = ` 1087 resource "aws_s3_bucket" "bucket" { 1088 bucket = "tf-test-bucket-%d" 1089 acl = "public-read" 1090 } 1091 ` 1092 1093 var testAccAWSS3BucketConfigWithAclUpdate = ` 1094 resource "aws_s3_bucket" "bucket" { 1095 bucket = "tf-test-bucket-%d" 1096 acl = "private" 1097 } 1098 ` 1099 1100 func testAccAWSS3BucketConfigWithLogging(randInt int) string { 1101 return fmt.Sprintf(` 1102 resource "aws_s3_bucket" "log_bucket" { 1103 bucket = "tf-test-log-bucket-%d" 1104 acl = "log-delivery-write" 1105 } 1106 resource "aws_s3_bucket" "bucket" { 1107 bucket = "tf-test-bucket-%d" 1108 acl = "private" 1109 logging { 1110 target_bucket = "${aws_s3_bucket.log_bucket.id}" 1111 target_prefix = "log/" 1112 } 1113 } 1114 `, randInt, randInt) 1115 } 1116 1117 func testAccAWSS3BucketConfigWithLifecycle(randInt int) string { 1118 return fmt.Sprintf(` 1119 resource "aws_s3_bucket" "bucket" { 1120 bucket = "tf-test-bucket-%d" 1121 acl = "private" 1122 lifecycle_rule { 1123 id = "id1" 1124 prefix = "path1/" 1125 enabled = true 1126 1127 expiration { 1128 days = 365 1129 } 1130 1131 transition { 1132 days = 30 1133 storage_class = "STANDARD_IA" 1134 } 1135 transition { 1136 days = 60 1137 storage_class = "GLACIER" 1138 } 1139 } 1140 lifecycle_rule { 1141 id = "id2" 1142 prefix = "path2/" 1143 enabled = true 1144 1145 expiration { 1146 date = "2016-01-12" 1147 } 1148 } 1149 } 1150 `, randInt) 1151 } 1152 1153 func testAccAWSS3BucketConfigWithVersioningLifecycle(randInt int) string { 1154 return fmt.Sprintf(` 1155 resource "aws_s3_bucket" "bucket" { 1156 bucket = "tf-test-bucket-%d" 1157 acl = "private" 1158 versioning { 1159 enabled = false 1160 } 1161 lifecycle_rule { 1162 id = "id1" 1163 prefix = "path1/" 1164 enabled = true 1165 1166 noncurrent_version_expiration { 1167 days = 365 1168 } 1169 noncurrent_version_transition { 1170 days = 30 1171 storage_class = "STANDARD_IA" 1172 } 1173 noncurrent_version_transition { 1174 days = 60 1175 storage_class = "GLACIER" 1176 } 1177 } 1178 lifecycle_rule { 1179 id = "id2" 1180 prefix = "path2/" 1181 enabled = false 1182 1183 noncurrent_version_expiration { 1184 days = 365 1185 } 1186 } 1187 } 1188 `, randInt) 1189 }