opentofu/builtin/providers/aws/resource_aws_cloudfront_distribution_test.go
Krzysztof Wilczynski 70a90cc1f4 Handle EC2 tags related errors in CloudFront Distribution resource. (#9298)
This commits changes the behaviour in a case there was an error while
interacting with EC2 tags related to the CloudFormation Distribution
resource, fixing the issue with nil pointer dereference when despite
an error being present code path to handle tags was executed.

Also, a small re-factor of the `validateHTTP` helper method,
and a unit test added for it.

Signed-off-by: Krzysztof Wilczynski <krzysztof.wilczynski@linux.com>
2016-10-09 20:51:16 +02:00

749 lines
19 KiB
Go

package aws
import (
"fmt"
"math/rand"
"os"
"testing"
"time"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/cloudfront"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
)
// TestAccAWSCloudFrontDistribution_S3Origin runs an
// aws_cloudfront_distribution acceptance test with a single S3 origin.
//
// If you are testing manually and can't wait for deletion, set the
// TF_TEST_CLOUDFRONT_RETAIN environment variable.
func TestAccAWSCloudFrontDistribution_S3Origin(t *testing.T) {
ri := acctest.RandInt()
testConfig := fmt.Sprintf(testAccAWSCloudFrontDistributionS3Config, ri, originBucket, logBucket, testAccAWSCloudFrontDistributionRetainConfig())
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckCloudFrontDistributionDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testConfig,
Check: resource.ComposeTestCheckFunc(
testAccCheckCloudFrontDistributionExistence(
"aws_cloudfront_distribution.s3_distribution",
),
resource.TestCheckResourceAttr(
"aws_cloudfront_distribution.s3_distribution",
"hosted_zone_id",
"Z2FDTNDATAQYW2",
),
),
},
},
})
}
func TestAccAWSCloudFrontDistribution_S3OriginWithTags(t *testing.T) {
ri := acctest.RandInt()
preConfig := fmt.Sprintf(testAccAWSCloudFrontDistributionS3ConfigWithTags, ri, originBucket, logBucket, testAccAWSCloudFrontDistributionRetainConfig())
postConfig := fmt.Sprintf(testAccAWSCloudFrontDistributionS3ConfigWithTagsUpdated, ri, originBucket, logBucket, testAccAWSCloudFrontDistributionRetainConfig())
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckCloudFrontDistributionDestroy,
Steps: []resource.TestStep{
{
Config: preConfig,
Check: resource.ComposeTestCheckFunc(
testAccCheckCloudFrontDistributionExistence(
"aws_cloudfront_distribution.s3_distribution",
),
resource.TestCheckResourceAttr(
"aws_cloudfront_distribution.s3_distribution", "tags.%", "2"),
resource.TestCheckResourceAttr(
"aws_cloudfront_distribution.s3_distribution", "tags.environment", "production"),
resource.TestCheckResourceAttr(
"aws_cloudfront_distribution.s3_distribution", "tags.account", "main"),
),
},
{
Config: postConfig,
Check: resource.ComposeTestCheckFunc(
testAccCheckCloudFrontDistributionExistence(
"aws_cloudfront_distribution.s3_distribution",
),
resource.TestCheckResourceAttr(
"aws_cloudfront_distribution.s3_distribution", "tags.%", "1"),
resource.TestCheckResourceAttr(
"aws_cloudfront_distribution.s3_distribution", "tags.environment", "dev"),
),
},
},
})
}
// TestAccAWSCloudFrontDistribution_customOriginruns an
// aws_cloudfront_distribution acceptance test with a single custom origin.
//
// If you are testing manually and can't wait for deletion, set the
// TF_TEST_CLOUDFRONT_RETAIN environment variable.
func TestAccAWSCloudFrontDistribution_customOrigin(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckCloudFrontDistributionDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccAWSCloudFrontDistributionCustomConfig,
Check: resource.ComposeTestCheckFunc(
testAccCheckCloudFrontDistributionExistence(
"aws_cloudfront_distribution.custom_distribution",
),
),
},
},
})
}
// TestAccAWSCloudFrontDistribution_multiOrigin runs an
// aws_cloudfront_distribution acceptance test with multiple origins.
//
// If you are testing manually and can't wait for deletion, set the
// TF_TEST_CLOUDFRONT_RETAIN environment variable.
func TestAccAWSCloudFrontDistribution_multiOrigin(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckCloudFrontDistributionDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccAWSCloudFrontDistributionMultiOriginConfig,
Check: resource.ComposeTestCheckFunc(
testAccCheckCloudFrontDistributionExistence(
"aws_cloudfront_distribution.multi_origin_distribution",
),
),
},
},
})
}
// TestAccAWSCloudFrontDistribution_noOptionalItemsConfig runs an
// aws_cloudfront_distribution acceptance test with no optional items set.
//
// If you are testing manually and can't wait for deletion, set the
// TF_TEST_CLOUDFRONT_RETAIN environment variable.
func TestAccAWSCloudFrontDistribution_noOptionalItemsConfig(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckCloudFrontDistributionDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccAWSCloudFrontDistributionNoOptionalItemsConfig,
Check: resource.ComposeTestCheckFunc(
testAccCheckCloudFrontDistributionExistence(
"aws_cloudfront_distribution.no_optional_items",
),
),
},
},
})
}
// TestAccAWSCloudFrontDistribution_HTTP11Config runs an
// aws_cloudfront_distribution acceptance test with the HTTP version set to
// 1.1.
//
// If you are testing manually and can't wait for deletion, set the
// TF_TEST_CLOUDFRONT_RETAIN environment variable.
func TestAccAWSCloudFrontDistribution_HTTP11Config(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckCloudFrontDistributionDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccAWSCloudFrontDistributionHTTP11Config,
Check: resource.ComposeTestCheckFunc(
testAccCheckCloudFrontDistributionExistence(
"aws_cloudfront_distribution.http_1_1",
),
),
},
},
})
}
func TestAccAWSCloudFrontDistribution_noCustomErrorResponseConfig(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckCloudFrontDistributionDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccAWSCloudFrontDistributionNoCustomErroResponseInfo,
Check: resource.ComposeTestCheckFunc(
testAccCheckCloudFrontDistributionExistence(
"aws_cloudfront_distribution.no_custom_error_responses",
),
),
},
},
})
}
func TestResourceAWSCloudFrontDistribution_validateHTTP(t *testing.T) {
var value string
var errors []error
value = "incorrect"
_, errors = validateHTTP(value, "http_version")
if len(errors) == 0 {
t.Fatalf("Expected %q to trigger a validation error", value)
}
value = "http1.1"
_, errors = validateHTTP(value, "http_version")
if len(errors) != 0 {
t.Fatalf("Expected %q not to trigger a validation error", value)
}
}
func testAccCheckCloudFrontDistributionDestroy(s *terraform.State) error {
for k, rs := range s.RootModule().Resources {
if rs.Type != "aws_cloudfront_distribution" {
continue
}
dist, err := testAccAuxCloudFrontGetDistributionConfig(s, k)
if err == nil {
if _, ok := os.LookupEnv("TF_TEST_CLOUDFRONT_RETAIN"); ok {
if *dist.DistributionConfig.Enabled != false {
return fmt.Errorf("CloudFront distribution should be disabled")
}
return nil
}
return fmt.Errorf("CloudFront distribution did not destroy")
}
}
return nil
}
func testAccCheckCloudFrontDistributionExistence(cloudFrontResource string) resource.TestCheckFunc {
return func(s *terraform.State) error {
_, err := testAccAuxCloudFrontGetDistributionConfig(s, cloudFrontResource)
return err
}
}
func testAccAuxCloudFrontGetDistributionConfig(s *terraform.State, cloudFrontResource string) (*cloudfront.Distribution, error) {
cf, ok := s.RootModule().Resources[cloudFrontResource]
if !ok {
return nil, fmt.Errorf("Not found: %s", cloudFrontResource)
}
if cf.Primary.ID == "" {
return nil, fmt.Errorf("No Id is set")
}
cloudfrontconn := testAccProvider.Meta().(*AWSClient).cloudfrontconn
req := &cloudfront.GetDistributionInput{
Id: aws.String(cf.Primary.ID),
}
res, err := cloudfrontconn.GetDistribution(req)
if err != nil {
return nil, fmt.Errorf("Error retrieving CloudFront distribution: %s", err)
}
return res.Distribution, nil
}
func testAccAWSCloudFrontDistributionRetainConfig() string {
if _, ok := os.LookupEnv("TF_TEST_CLOUDFRONT_RETAIN"); ok {
return "retain_on_delete = true"
}
return ""
}
var originBucket = fmt.Sprintf(`
resource "aws_s3_bucket" "s3_bucket_origin" {
bucket = "mybucket.${var.rand_id}"
acl = "public-read"
}
`)
var logBucket = fmt.Sprintf(`
resource "aws_s3_bucket" "s3_bucket_logs" {
bucket = "mylogs.${var.rand_id}"
acl = "public-read"
}
`)
var testAccAWSCloudFrontDistributionS3Config = `
variable rand_id {
default = %d
}
# origin bucket
%s
# log bucket
%s
resource "aws_cloudfront_distribution" "s3_distribution" {
origin {
domain_name = "${aws_s3_bucket.s3_bucket_origin.id}.s3.amazonaws.com"
origin_id = "myS3Origin"
}
enabled = true
default_root_object = "index.html"
logging_config {
include_cookies = false
bucket = "${aws_s3_bucket.s3_bucket_logs.id}.s3.amazonaws.com"
prefix = "myprefix"
}
aliases = [ "mysite.${var.rand_id}.example.com", "yoursite.${var.rand_id}.example.com" ]
default_cache_behavior {
allowed_methods = [ "DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT" ]
cached_methods = [ "GET", "HEAD" ]
target_origin_id = "myS3Origin"
forwarded_values {
query_string = false
cookies {
forward = "none"
}
}
viewer_protocol_policy = "allow-all"
min_ttl = 0
default_ttl = 3600
max_ttl = 86400
}
price_class = "PriceClass_200"
restrictions {
geo_restriction {
restriction_type = "whitelist"
locations = [ "US", "CA", "GB", "DE" ]
}
}
viewer_certificate {
cloudfront_default_certificate = true
}
%s
}
`
var testAccAWSCloudFrontDistributionS3ConfigWithTags = `
variable rand_id {
default = %d
}
# origin bucket
%s
# log bucket
%s
resource "aws_cloudfront_distribution" "s3_distribution" {
origin {
domain_name = "${aws_s3_bucket.s3_bucket_origin.id}.s3.amazonaws.com"
origin_id = "myS3Origin"
}
enabled = true
default_root_object = "index.html"
aliases = [ "mysite.${var.rand_id}.example.com", "yoursite.${var.rand_id}.example.com" ]
default_cache_behavior {
allowed_methods = [ "DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT" ]
cached_methods = [ "GET", "HEAD" ]
target_origin_id = "myS3Origin"
forwarded_values {
query_string = false
cookies {
forward = "none"
}
}
viewer_protocol_policy = "allow-all"
min_ttl = 0
default_ttl = 3600
max_ttl = 86400
}
price_class = "PriceClass_200"
restrictions {
geo_restriction {
restriction_type = "whitelist"
locations = [ "US", "CA", "GB", "DE" ]
}
}
viewer_certificate {
cloudfront_default_certificate = true
}
tags {
environment = "production"
account = "main"
}
%s
}
`
var testAccAWSCloudFrontDistributionS3ConfigWithTagsUpdated = `
variable rand_id {
default = %d
}
# origin bucket
%s
# log bucket
%s
resource "aws_cloudfront_distribution" "s3_distribution" {
origin {
domain_name = "${aws_s3_bucket.s3_bucket_origin.id}.s3.amazonaws.com"
origin_id = "myS3Origin"
}
enabled = true
default_root_object = "index.html"
aliases = [ "mysite.${var.rand_id}.example.com", "yoursite.${var.rand_id}.example.com" ]
default_cache_behavior {
allowed_methods = [ "DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT" ]
cached_methods = [ "GET", "HEAD" ]
target_origin_id = "myS3Origin"
forwarded_values {
query_string = false
cookies {
forward = "none"
}
}
viewer_protocol_policy = "allow-all"
min_ttl = 0
default_ttl = 3600
max_ttl = 86400
}
price_class = "PriceClass_200"
restrictions {
geo_restriction {
restriction_type = "whitelist"
locations = [ "US", "CA", "GB", "DE" ]
}
}
viewer_certificate {
cloudfront_default_certificate = true
}
tags {
environment = "dev"
}
%s
}
`
var testAccAWSCloudFrontDistributionCustomConfig = fmt.Sprintf(`
variable rand_id {
default = %d
}
# log bucket
%s
resource "aws_cloudfront_distribution" "custom_distribution" {
origin {
domain_name = "www.example.com"
origin_id = "myCustomOrigin"
custom_origin_config {
http_port = 80
https_port = 443
origin_protocol_policy = "http-only"
origin_ssl_protocols = [ "SSLv3", "TLSv1" ]
}
}
enabled = true
comment = "Some comment"
default_root_object = "index.html"
logging_config {
include_cookies = false
bucket = "${aws_s3_bucket.s3_bucket_logs.id}.s3.amazonaws.com"
prefix = "myprefix"
}
aliases = [ "mysite.${var.rand_id}.example.com", "*.yoursite.${var.rand_id}.example.com" ]
default_cache_behavior {
allowed_methods = [ "DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT" ]
cached_methods = [ "GET", "HEAD" ]
target_origin_id = "myCustomOrigin"
smooth_streaming = false
forwarded_values {
query_string = false
cookies {
forward = "all"
}
}
viewer_protocol_policy = "allow-all"
min_ttl = 0
default_ttl = 3600
max_ttl = 86400
}
price_class = "PriceClass_200"
restrictions {
geo_restriction {
restriction_type = "whitelist"
locations = [ "US", "CA", "GB", "DE" ]
}
}
viewer_certificate {
cloudfront_default_certificate = true
}
%s
}
`, rand.New(rand.NewSource(time.Now().UnixNano())).Int(), logBucket, testAccAWSCloudFrontDistributionRetainConfig())
var testAccAWSCloudFrontDistributionMultiOriginConfig = fmt.Sprintf(`
variable rand_id {
default = %d
}
# origin bucket
%s
# log bucket
%s
resource "aws_cloudfront_distribution" "multi_origin_distribution" {
origin {
domain_name = "${aws_s3_bucket.s3_bucket_origin.id}.s3.amazonaws.com"
origin_id = "myS3Origin"
}
origin {
domain_name = "www.example.com"
origin_id = "myCustomOrigin"
custom_origin_config {
http_port = 80
https_port = 443
origin_protocol_policy = "http-only"
origin_ssl_protocols = [ "SSLv3", "TLSv1" ]
}
}
enabled = true
comment = "Some comment"
default_root_object = "index.html"
logging_config {
include_cookies = false
bucket = "${aws_s3_bucket.s3_bucket_logs.id}.s3.amazonaws.com"
prefix = "myprefix"
}
aliases = [ "mysite.${var.rand_id}.example.com", "*.yoursite.${var.rand_id}.example.com" ]
default_cache_behavior {
allowed_methods = [ "DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT" ]
cached_methods = [ "GET", "HEAD" ]
target_origin_id = "myS3Origin"
smooth_streaming = true
forwarded_values {
query_string = false
cookies {
forward = "all"
}
}
min_ttl = 100
default_ttl = 100
max_ttl = 100
viewer_protocol_policy = "allow-all"
}
cache_behavior {
allowed_methods = [ "DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT" ]
cached_methods = [ "GET", "HEAD" ]
target_origin_id = "myS3Origin"
forwarded_values {
query_string = true
cookies {
forward = "none"
}
}
min_ttl = 50
default_ttl = 50
max_ttl = 50
viewer_protocol_policy = "allow-all"
path_pattern = "images1/*.jpg"
}
cache_behavior {
allowed_methods = [ "DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT" ]
cached_methods = [ "GET", "HEAD" ]
target_origin_id = "myCustomOrigin"
forwarded_values {
query_string = true
cookies {
forward = "none"
}
}
min_ttl = 50
default_ttl = 50
max_ttl = 50
viewer_protocol_policy = "allow-all"
path_pattern = "images2/*.jpg"
}
price_class = "PriceClass_All"
custom_error_response {
error_code = 404
response_page_path = "/error-pages/404.html"
response_code = 200
error_caching_min_ttl = 30
}
restrictions {
geo_restriction {
restriction_type = "none"
}
}
viewer_certificate {
cloudfront_default_certificate = true
}
%s
}
`, rand.New(rand.NewSource(time.Now().UnixNano())).Int(), originBucket, logBucket, testAccAWSCloudFrontDistributionRetainConfig())
var testAccAWSCloudFrontDistributionNoCustomErroResponseInfo = fmt.Sprintf(`
variable rand_id {
default = %d
}
resource "aws_cloudfront_distribution" "no_custom_error_responses" {
origin {
domain_name = "www.example.com"
origin_id = "myCustomOrigin"
custom_origin_config {
http_port = 80
https_port = 443
origin_protocol_policy = "http-only"
origin_ssl_protocols = [ "SSLv3", "TLSv1" ]
}
}
enabled = true
comment = "Some comment"
default_cache_behavior {
allowed_methods = [ "DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT" ]
cached_methods = [ "GET", "HEAD" ]
target_origin_id = "myCustomOrigin"
smooth_streaming = false
forwarded_values {
query_string = false
cookies {
forward = "all"
}
}
viewer_protocol_policy = "allow-all"
min_ttl = 0
default_ttl = 3600
max_ttl = 86400
}
custom_error_response {
error_code = 404
error_caching_min_ttl = 30
}
restrictions {
geo_restriction {
restriction_type = "whitelist"
locations = [ "US", "CA", "GB", "DE" ]
}
}
viewer_certificate {
cloudfront_default_certificate = true
}
%s
}
`, rand.New(rand.NewSource(time.Now().UnixNano())).Int(), testAccAWSCloudFrontDistributionRetainConfig())
var testAccAWSCloudFrontDistributionNoOptionalItemsConfig = fmt.Sprintf(`
variable rand_id {
default = %d
}
resource "aws_cloudfront_distribution" "no_optional_items" {
origin {
domain_name = "www.example.com"
origin_id = "myCustomOrigin"
custom_origin_config {
http_port = 80
https_port = 443
origin_protocol_policy = "http-only"
origin_ssl_protocols = [ "SSLv3", "TLSv1" ]
}
}
enabled = true
comment = "Some comment"
default_cache_behavior {
allowed_methods = [ "DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT" ]
cached_methods = [ "GET", "HEAD" ]
target_origin_id = "myCustomOrigin"
smooth_streaming = false
forwarded_values {
query_string = false
cookies {
forward = "all"
}
}
viewer_protocol_policy = "allow-all"
min_ttl = 0
default_ttl = 3600
max_ttl = 86400
}
restrictions {
geo_restriction {
restriction_type = "whitelist"
locations = [ "US", "CA", "GB", "DE" ]
}
}
viewer_certificate {
cloudfront_default_certificate = true
}
%s
}
`, rand.New(rand.NewSource(time.Now().UnixNano())).Int(), testAccAWSCloudFrontDistributionRetainConfig())
var testAccAWSCloudFrontDistributionHTTP11Config = fmt.Sprintf(`
variable rand_id {
default = %d
}
resource "aws_cloudfront_distribution" "http_1_1" {
origin {
domain_name = "www.example.com"
origin_id = "myCustomOrigin"
custom_origin_config {
http_port = 80
https_port = 443
origin_protocol_policy = "http-only"
origin_ssl_protocols = [ "SSLv3", "TLSv1" ]
}
}
enabled = true
comment = "Some comment"
default_cache_behavior {
allowed_methods = [ "DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT" ]
cached_methods = [ "GET", "HEAD" ]
target_origin_id = "myCustomOrigin"
smooth_streaming = false
forwarded_values {
query_string = false
cookies {
forward = "all"
}
}
viewer_protocol_policy = "allow-all"
min_ttl = 0
default_ttl = 3600
max_ttl = 86400
}
http_version = "http1.1"
restrictions {
geo_restriction {
restriction_type = "whitelist"
locations = [ "US", "CA", "GB", "DE" ]
}
}
viewer_certificate {
cloudfront_default_certificate = true
}
%s
}
`, rand.New(rand.NewSource(time.Now().UnixNano())).Int(), testAccAWSCloudFrontDistributionRetainConfig())