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