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