github.com/turtlemonvh/terraform@v0.6.9-0.20151204001754-8e40b6b855e8/builtin/providers/aws/resource_aws_s3_bucket_test.go (about)

     1  package aws
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"math/rand"
     7  	"reflect"
     8  	"regexp"
     9  	"strconv"
    10  	"testing"
    11  	"time"
    12  
    13  	"github.com/hashicorp/terraform/helper/resource"
    14  	"github.com/hashicorp/terraform/terraform"
    15  
    16  	"github.com/aws/aws-sdk-go/aws"
    17  	"github.com/aws/aws-sdk-go/service/s3"
    18  )
    19  
    20  func TestAccAWSS3Bucket_basic(t *testing.T) {
    21  
    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,
    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  	resource.Test(t, resource.TestCase{
    50  		PreCheck:     func() { testAccPreCheck(t) },
    51  		Providers:    testAccProviders,
    52  		CheckDestroy: testAccCheckAWSS3BucketDestroy,
    53  		Steps: []resource.TestStep{
    54  			resource.TestStep{
    55  				Config: testAccAWSS3BucketConfigWithPolicy,
    56  				Check: resource.ComposeTestCheckFunc(
    57  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
    58  					testAccCheckAWSS3BucketPolicy(
    59  						"aws_s3_bucket.bucket", testAccAWSS3BucketPolicy),
    60  				),
    61  			},
    62  			resource.TestStep{
    63  				Config: testAccAWSS3BucketConfig,
    64  				Check: resource.ComposeTestCheckFunc(
    65  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
    66  					testAccCheckAWSS3BucketPolicy(
    67  						"aws_s3_bucket.bucket", ""),
    68  				),
    69  			},
    70  		},
    71  	})
    72  }
    73  
    74  func TestAccAWSS3Bucket_UpdateAcl(t *testing.T) {
    75  
    76  	ri := genRandInt()
    77  	preConfig := fmt.Sprintf(testAccAWSS3BucketConfigWithAcl, ri)
    78  	postConfig := fmt.Sprintf(testAccAWSS3BucketConfigWithAclUpdate, ri)
    79  
    80  	resource.Test(t, resource.TestCase{
    81  		PreCheck:     func() { testAccPreCheck(t) },
    82  		Providers:    testAccProviders,
    83  		CheckDestroy: testAccCheckAWSS3BucketDestroy,
    84  		Steps: []resource.TestStep{
    85  			resource.TestStep{
    86  				Config: preConfig,
    87  				Check: resource.ComposeTestCheckFunc(
    88  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
    89  					resource.TestCheckResourceAttr(
    90  						"aws_s3_bucket.bucket", "acl", "public-read"),
    91  				),
    92  			},
    93  			resource.TestStep{
    94  				Config: postConfig,
    95  				Check: resource.ComposeTestCheckFunc(
    96  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
    97  					resource.TestCheckResourceAttr(
    98  						"aws_s3_bucket.bucket", "acl", "private"),
    99  				),
   100  			},
   101  		},
   102  	})
   103  }
   104  
   105  func TestAccAWSS3Bucket_Website_Simple(t *testing.T) {
   106  	resource.Test(t, resource.TestCase{
   107  		PreCheck:     func() { testAccPreCheck(t) },
   108  		Providers:    testAccProviders,
   109  		CheckDestroy: testAccCheckAWSS3BucketDestroy,
   110  		Steps: []resource.TestStep{
   111  			resource.TestStep{
   112  				Config: testAccAWSS3BucketWebsiteConfig,
   113  				Check: resource.ComposeTestCheckFunc(
   114  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
   115  					testAccCheckAWSS3BucketWebsite(
   116  						"aws_s3_bucket.bucket", "index.html", "", ""),
   117  					resource.TestCheckResourceAttr(
   118  						"aws_s3_bucket.bucket", "website_endpoint", testAccWebsiteEndpoint),
   119  				),
   120  			},
   121  			resource.TestStep{
   122  				Config: testAccAWSS3BucketWebsiteConfigWithError,
   123  				Check: resource.ComposeTestCheckFunc(
   124  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
   125  					testAccCheckAWSS3BucketWebsite(
   126  						"aws_s3_bucket.bucket", "index.html", "error.html", ""),
   127  					resource.TestCheckResourceAttr(
   128  						"aws_s3_bucket.bucket", "website_endpoint", testAccWebsiteEndpoint),
   129  				),
   130  			},
   131  			resource.TestStep{
   132  				Config: testAccAWSS3BucketConfig,
   133  				Check: resource.ComposeTestCheckFunc(
   134  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
   135  					testAccCheckAWSS3BucketWebsite(
   136  						"aws_s3_bucket.bucket", "", "", ""),
   137  					resource.TestCheckResourceAttr(
   138  						"aws_s3_bucket.bucket", "website_endpoint", ""),
   139  				),
   140  			},
   141  		},
   142  	})
   143  }
   144  
   145  func TestAccAWSS3Bucket_WebsiteRedirect(t *testing.T) {
   146  	resource.Test(t, resource.TestCase{
   147  		PreCheck:     func() { testAccPreCheck(t) },
   148  		Providers:    testAccProviders,
   149  		CheckDestroy: testAccCheckAWSS3BucketDestroy,
   150  		Steps: []resource.TestStep{
   151  			resource.TestStep{
   152  				Config: testAccAWSS3BucketWebsiteConfigWithRedirect,
   153  				Check: resource.ComposeTestCheckFunc(
   154  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
   155  					testAccCheckAWSS3BucketWebsite(
   156  						"aws_s3_bucket.bucket", "", "", "hashicorp.com"),
   157  					resource.TestCheckResourceAttr(
   158  						"aws_s3_bucket.bucket", "website_endpoint", testAccWebsiteEndpoint),
   159  				),
   160  			},
   161  			resource.TestStep{
   162  				Config: testAccAWSS3BucketConfig,
   163  				Check: resource.ComposeTestCheckFunc(
   164  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
   165  					testAccCheckAWSS3BucketWebsite(
   166  						"aws_s3_bucket.bucket", "", "", ""),
   167  					resource.TestCheckResourceAttr(
   168  						"aws_s3_bucket.bucket", "website_endpoint", ""),
   169  				),
   170  			},
   171  		},
   172  	})
   173  }
   174  
   175  // Test TestAccAWSS3Bucket_shouldFailNotFound is designed to fail with a "plan
   176  // not empty" error in Terraform, to check against regresssions.
   177  // See https://github.com/hashicorp/terraform/pull/2925
   178  func TestAccAWSS3Bucket_shouldFailNotFound(t *testing.T) {
   179  	resource.Test(t, resource.TestCase{
   180  		PreCheck:     func() { testAccPreCheck(t) },
   181  		Providers:    testAccProviders,
   182  		CheckDestroy: testAccCheckAWSS3BucketDestroy,
   183  		Steps: []resource.TestStep{
   184  			resource.TestStep{
   185  				Config: testAccAWSS3BucketDestroyedConfig,
   186  				Check: resource.ComposeTestCheckFunc(
   187  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
   188  					testAccCheckAWSS3DestroyBucket("aws_s3_bucket.bucket"),
   189  				),
   190  			},
   191  		},
   192  	})
   193  }
   194  
   195  func TestAccAWSS3Bucket_Versioning(t *testing.T) {
   196  	resource.Test(t, resource.TestCase{
   197  		PreCheck:     func() { testAccPreCheck(t) },
   198  		Providers:    testAccProviders,
   199  		CheckDestroy: testAccCheckAWSS3BucketDestroy,
   200  		Steps: []resource.TestStep{
   201  			resource.TestStep{
   202  				Config: testAccAWSS3BucketConfig,
   203  				Check: resource.ComposeTestCheckFunc(
   204  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
   205  					testAccCheckAWSS3BucketVersioning(
   206  						"aws_s3_bucket.bucket", ""),
   207  				),
   208  			},
   209  			resource.TestStep{
   210  				Config: testAccAWSS3BucketConfigWithVersioning,
   211  				Check: resource.ComposeTestCheckFunc(
   212  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
   213  					testAccCheckAWSS3BucketVersioning(
   214  						"aws_s3_bucket.bucket", s3.BucketVersioningStatusEnabled),
   215  				),
   216  			},
   217  			resource.TestStep{
   218  				Config: testAccAWSS3BucketConfigWithDisableVersioning,
   219  				Check: resource.ComposeTestCheckFunc(
   220  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
   221  					testAccCheckAWSS3BucketVersioning(
   222  						"aws_s3_bucket.bucket", s3.BucketVersioningStatusSuspended),
   223  				),
   224  			},
   225  		},
   226  	})
   227  }
   228  
   229  func TestAccAWSS3Bucket_Cors(t *testing.T) {
   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: testAccAWSS3BucketConfigWithCORS,
   237  				Check: resource.ComposeTestCheckFunc(
   238  					testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
   239  					testAccCheckAWSS3BucketCors(
   240  						"aws_s3_bucket.bucket",
   241  						[]*s3.CORSRule{
   242  							&s3.CORSRule{
   243  								AllowedHeaders: []*string{aws.String("*")},
   244  								AllowedMethods: []*string{aws.String("PUT"), aws.String("POST")},
   245  								AllowedOrigins: []*string{aws.String("https://www.example.com")},
   246  								ExposeHeaders:  []*string{aws.String("x-amz-server-side-encryption"), aws.String("ETag")},
   247  								MaxAgeSeconds:  aws.Int64(3000),
   248  							},
   249  						},
   250  					),
   251  				),
   252  			},
   253  		},
   254  	})
   255  }
   256  
   257  func testAccCheckAWSS3BucketDestroy(s *terraform.State) error {
   258  	conn := testAccProvider.Meta().(*AWSClient).s3conn
   259  
   260  	for _, rs := range s.RootModule().Resources {
   261  		if rs.Type != "aws_s3_bucket" {
   262  			continue
   263  		}
   264  		_, err := conn.DeleteBucket(&s3.DeleteBucketInput{
   265  			Bucket: aws.String(rs.Primary.ID),
   266  		})
   267  		if err != nil {
   268  			return err
   269  		}
   270  	}
   271  	return nil
   272  }
   273  
   274  func testAccCheckAWSS3BucketExists(n string) resource.TestCheckFunc {
   275  	return func(s *terraform.State) error {
   276  		rs, ok := s.RootModule().Resources[n]
   277  		if !ok {
   278  			return fmt.Errorf("Not found: %s", n)
   279  		}
   280  
   281  		if rs.Primary.ID == "" {
   282  			return fmt.Errorf("No S3 Bucket ID is set")
   283  		}
   284  
   285  		conn := testAccProvider.Meta().(*AWSClient).s3conn
   286  		_, err := conn.HeadBucket(&s3.HeadBucketInput{
   287  			Bucket: aws.String(rs.Primary.ID),
   288  		})
   289  
   290  		if err != nil {
   291  			return fmt.Errorf("S3Bucket error: %v", err)
   292  		}
   293  		return nil
   294  	}
   295  }
   296  
   297  func testAccCheckAWSS3DestroyBucket(n string) resource.TestCheckFunc {
   298  	return func(s *terraform.State) error {
   299  		rs, ok := s.RootModule().Resources[n]
   300  		if !ok {
   301  			return fmt.Errorf("Not found: %s", n)
   302  		}
   303  
   304  		if rs.Primary.ID == "" {
   305  			return fmt.Errorf("No S3 Bucket ID is set")
   306  		}
   307  
   308  		conn := testAccProvider.Meta().(*AWSClient).s3conn
   309  		_, err := conn.DeleteBucket(&s3.DeleteBucketInput{
   310  			Bucket: aws.String(rs.Primary.ID),
   311  		})
   312  
   313  		if err != nil {
   314  			return fmt.Errorf("Error destroying Bucket (%s) in testAccCheckAWSS3DestroyBucket: %s", rs.Primary.ID, err)
   315  		}
   316  		return nil
   317  	}
   318  }
   319  
   320  func testAccCheckAWSS3BucketPolicy(n string, policy string) resource.TestCheckFunc {
   321  	return func(s *terraform.State) error {
   322  		rs, _ := s.RootModule().Resources[n]
   323  		conn := testAccProvider.Meta().(*AWSClient).s3conn
   324  
   325  		out, err := conn.GetBucketPolicy(&s3.GetBucketPolicyInput{
   326  			Bucket: aws.String(rs.Primary.ID),
   327  		})
   328  
   329  		if err != nil {
   330  			if policy == "" {
   331  				// expected
   332  				return nil
   333  			} else {
   334  				return fmt.Errorf("GetBucketPolicy error: %v, expected %s", err, policy)
   335  			}
   336  		}
   337  
   338  		if v := out.Policy; v == nil {
   339  			if policy != "" {
   340  				return fmt.Errorf("bad policy, found nil, expected: %s", policy)
   341  			}
   342  		} else {
   343  			expected := make(map[string]interface{})
   344  			if err := json.Unmarshal([]byte(policy), &expected); err != nil {
   345  				return err
   346  			}
   347  			actual := make(map[string]interface{})
   348  			if err := json.Unmarshal([]byte(*v), &actual); err != nil {
   349  				return err
   350  			}
   351  
   352  			if !reflect.DeepEqual(expected, actual) {
   353  				return fmt.Errorf("bad policy, expected: %#v, got %#v", expected, actual)
   354  			}
   355  		}
   356  
   357  		return nil
   358  	}
   359  }
   360  func testAccCheckAWSS3BucketWebsite(n string, indexDoc string, errorDoc string, redirectTo string) resource.TestCheckFunc {
   361  	return func(s *terraform.State) error {
   362  		rs, _ := s.RootModule().Resources[n]
   363  		conn := testAccProvider.Meta().(*AWSClient).s3conn
   364  
   365  		out, err := conn.GetBucketWebsite(&s3.GetBucketWebsiteInput{
   366  			Bucket: aws.String(rs.Primary.ID),
   367  		})
   368  
   369  		if err != nil {
   370  			if indexDoc == "" {
   371  				// If we want to assert that the website is not there, than
   372  				// this error is expected
   373  				return nil
   374  			} else {
   375  				return fmt.Errorf("S3BucketWebsite error: %v", err)
   376  			}
   377  		}
   378  
   379  		if v := out.IndexDocument; v == nil {
   380  			if indexDoc != "" {
   381  				return fmt.Errorf("bad index doc, found nil, expected: %s", indexDoc)
   382  			}
   383  		} else {
   384  			if *v.Suffix != indexDoc {
   385  				return fmt.Errorf("bad index doc, expected: %s, got %#v", indexDoc, out.IndexDocument)
   386  			}
   387  		}
   388  
   389  		if v := out.ErrorDocument; v == nil {
   390  			if errorDoc != "" {
   391  				return fmt.Errorf("bad error doc, found nil, expected: %s", errorDoc)
   392  			}
   393  		} else {
   394  			if *v.Key != errorDoc {
   395  				return fmt.Errorf("bad error doc, expected: %s, got %#v", errorDoc, out.ErrorDocument)
   396  			}
   397  		}
   398  
   399  		if v := out.RedirectAllRequestsTo; v == nil {
   400  			if redirectTo != "" {
   401  				return fmt.Errorf("bad redirect to, found nil, expected: %s", redirectTo)
   402  			}
   403  		} else {
   404  			if *v.HostName != redirectTo {
   405  				return fmt.Errorf("bad redirect to, expected: %s, got %#v", redirectTo, out.RedirectAllRequestsTo)
   406  			}
   407  		}
   408  
   409  		return nil
   410  	}
   411  }
   412  
   413  func testAccCheckAWSS3BucketVersioning(n string, versioningStatus string) resource.TestCheckFunc {
   414  	return func(s *terraform.State) error {
   415  		rs, _ := s.RootModule().Resources[n]
   416  		conn := testAccProvider.Meta().(*AWSClient).s3conn
   417  
   418  		out, err := conn.GetBucketVersioning(&s3.GetBucketVersioningInput{
   419  			Bucket: aws.String(rs.Primary.ID),
   420  		})
   421  
   422  		if err != nil {
   423  			return fmt.Errorf("GetBucketVersioning error: %v", err)
   424  		}
   425  
   426  		if v := out.Status; v == nil {
   427  			if versioningStatus != "" {
   428  				return fmt.Errorf("bad error versioning status, found nil, expected: %s", versioningStatus)
   429  			}
   430  		} else {
   431  			if *v != versioningStatus {
   432  				return fmt.Errorf("bad error versioning status, expected: %s, got %s", versioningStatus, *v)
   433  			}
   434  		}
   435  
   436  		return nil
   437  	}
   438  }
   439  func testAccCheckAWSS3BucketCors(n string, corsRules []*s3.CORSRule) resource.TestCheckFunc {
   440  	return func(s *terraform.State) error {
   441  		rs, _ := s.RootModule().Resources[n]
   442  		conn := testAccProvider.Meta().(*AWSClient).s3conn
   443  
   444  		out, err := conn.GetBucketCors(&s3.GetBucketCorsInput{
   445  			Bucket: aws.String(rs.Primary.ID),
   446  		})
   447  
   448  		if err != nil {
   449  			return fmt.Errorf("GetBucketCors error: %v", err)
   450  		}
   451  
   452  		if !reflect.DeepEqual(out.CORSRules, corsRules) {
   453  			return fmt.Errorf("bad error cors rule, expected: %v, got %v", corsRules, out.CORSRules)
   454  		}
   455  
   456  		return nil
   457  	}
   458  }
   459  
   460  // These need a bit of randomness as the name can only be used once globally
   461  // within AWS
   462  var randInt = rand.New(rand.NewSource(time.Now().UnixNano())).Int()
   463  var testAccWebsiteEndpoint = fmt.Sprintf("tf-test-bucket-%d.s3-website-us-west-2.amazonaws.com", randInt)
   464  var testAccAWSS3BucketPolicy = fmt.Sprintf(`{ "Version": "2012-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "AWS": "*" }, "Action": "s3:GetObject", "Resource": "arn:aws:s3:::tf-test-bucket-%d/*" } ] }`, randInt)
   465  
   466  var testAccAWSS3BucketConfig = fmt.Sprintf(`
   467  resource "aws_s3_bucket" "bucket" {
   468  	bucket = "tf-test-bucket-%d"
   469  	acl = "public-read"
   470  }
   471  `, randInt)
   472  
   473  var testAccAWSS3BucketWebsiteConfig = fmt.Sprintf(`
   474  resource "aws_s3_bucket" "bucket" {
   475  	bucket = "tf-test-bucket-%d"
   476  	acl = "public-read"
   477  
   478  	website {
   479  		index_document = "index.html"
   480  	}
   481  }
   482  `, randInt)
   483  
   484  var testAccAWSS3BucketWebsiteConfigWithError = fmt.Sprintf(`
   485  resource "aws_s3_bucket" "bucket" {
   486  	bucket = "tf-test-bucket-%d"
   487  	acl = "public-read"
   488  
   489  	website {
   490  		index_document = "index.html"
   491  		error_document = "error.html"
   492  	}
   493  }
   494  `, randInt)
   495  
   496  var testAccAWSS3BucketWebsiteConfigWithRedirect = fmt.Sprintf(`
   497  resource "aws_s3_bucket" "bucket" {
   498  	bucket = "tf-test-bucket-%d"
   499  	acl = "public-read"
   500  
   501  	website {
   502  		redirect_all_requests_to = "hashicorp.com"
   503  	}
   504  }
   505  `, randInt)
   506  
   507  var testAccAWSS3BucketConfigWithPolicy = fmt.Sprintf(`
   508  resource "aws_s3_bucket" "bucket" {
   509  	bucket = "tf-test-bucket-%d"
   510  	acl = "public-read"
   511  	policy = %s
   512  }
   513  `, randInt, strconv.Quote(testAccAWSS3BucketPolicy))
   514  
   515  var destroyedName = fmt.Sprintf("tf-test-bucket-%d", randInt)
   516  var testAccAWSS3BucketDestroyedConfig = fmt.Sprintf(`
   517  resource "aws_s3_bucket" "bucket" {
   518  	bucket = "%s"
   519  	acl = "public-read"
   520  }
   521  `, destroyedName)
   522  var testAccAWSS3BucketConfigWithVersioning = fmt.Sprintf(`
   523  resource "aws_s3_bucket" "bucket" {
   524  	bucket = "tf-test-bucket-%d"
   525  	acl = "public-read"
   526  	versioning {
   527  	  enabled = true
   528  	}
   529  }
   530  `, randInt)
   531  
   532  var testAccAWSS3BucketConfigWithDisableVersioning = fmt.Sprintf(`
   533  resource "aws_s3_bucket" "bucket" {
   534  	bucket = "tf-test-bucket-%d"
   535  	acl = "public-read"
   536  	versioning {
   537  	  enabled = false
   538  	}
   539  }
   540  `, randInt)
   541  
   542  var testAccAWSS3BucketConfigWithCORS = fmt.Sprintf(`
   543  resource "aws_s3_bucket" "bucket" {
   544  	bucket = "tf-test-bucket-%d"
   545  	acl = "public-read"
   546  	cors_rule {
   547  			allowed_headers = ["*"]
   548  			allowed_methods = ["PUT","POST"]
   549  			allowed_origins = ["https://www.example.com"]
   550  			expose_headers = ["x-amz-server-side-encryption","ETag"]
   551  			max_age_seconds = 3000
   552  	}
   553  }
   554  `, randInt)
   555  
   556  var testAccAWSS3BucketConfigWithAcl = `
   557  resource "aws_s3_bucket" "bucket" {
   558  	bucket = "tf-test-bucket-%d"
   559  	acl = "public-read"
   560  }
   561  `
   562  
   563  var testAccAWSS3BucketConfigWithAclUpdate = `
   564  resource "aws_s3_bucket" "bucket" {
   565  	bucket = "tf-test-bucket-%d"
   566  	acl = "private"
   567  }
   568  `