diff --git a/LICENSE b/LICENSE index a6e3b3e1..c844c705 100644 --- a/LICENSE +++ b/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright 2017-2019 Cloud Posse, LLC + Copyright 2017-2020 Cloud Posse, LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/README.md b/README.md index 05e99c9d..7300703c 100644 --- a/README.md +++ b/README.md @@ -86,6 +86,11 @@ We literally have [*hundreds of terraform modules*][terraform_modules] that are Instead pin to the release tag (e.g. `?ref=tags/x.y.z`) of one of our [latest releases](https://github.com/cloudposse/terraform-aws-cloudfront-s3-cdn/releases). + +For a complete example, see [examples/complete](examples/complete). + +For automated tests of the complete example using [bats](https://github.com/bats-core/bats-core) and [Terratest](https://github.com/gruntwork-io/terratest) (which tests and deploys the example on AWS), see [test](test). + ```hcl module "cdn" { source = "git::https://github.com/cloudposse/terraform-aws-cloudfront-s3-cdn.git?ref=master" @@ -97,8 +102,6 @@ module "cdn" { } ``` -Full working example can be found in [examples](./examples) folder. - ### Generating ACM Certificate Use the AWS cli to [request new ACM certifiates](http://docs.aws.amazon.com/acm/latest/userguide/gs-acm-request.html) (requires email validation) @@ -156,10 +159,10 @@ Available targets: | cors_allowed_methods | List of allowed methods (e.g. GET, PUT, POST, DELETE, HEAD) for S3 bucket | list(string) | `` | no | | cors_allowed_origins | List of allowed origins (e.g. example.com, test.com) for S3 bucket | list(string) | `` | no | | cors_expose_headers | List of expose header in the response for S3 bucket | list(string) | `` | no | -| cors_max_age_seconds | Time in seconds that browser can cache the response for S3 bucket | string | `3600` | no | +| cors_max_age_seconds | Time in seconds that browser can cache the response for S3 bucket | number | `3600` | no | | custom_error_response | List of one or more custom error response element maps | object | `` | no | | default_root_object | Object that CloudFront return when requests the root URL | string | `index.html` | no | -| default_ttl | Default amount of time (in seconds) that an object is in a CloudFront cache | string | `60` | no | +| default_ttl | Default amount of time (in seconds) that an object is in a CloudFront cache | number | `60` | no | | delimiter | Delimiter to be used between `namespace`, `stage`, `name` and `attributes` | string | `-` | no | | enabled | Select Enabled if you want CloudFront to begin processing requests as soon as the distribution is created, or select Disabled if you do not want CloudFront to begin processing requests after the distribution is created. | bool | `true` | no | | encryption_enabled | When set to 'true' the resource will have aes256 encryption enabled by default | bool | `false` | no | @@ -172,20 +175,18 @@ Available targets: | geo_restriction_locations | List of country codes for which CloudFront either to distribute content (whitelist) or not distribute your content (blacklist) | list(string) | `` | no | | geo_restriction_type | Method that use to restrict distribution of your content by country: `none`, `whitelist`, or `blacklist` | string | `none` | no | | index_document | Amazon S3 returns this index document when requests are made to the root domain or any of the subfolders | string | `` | no | -| ipv6_enabled | Set to true to enable an AAAA DNS record to be set as well as the A record | bool | `false` | no | -| is_ipv6_enabled | State of CloudFront IPv6 | bool | `true` | no | +| ipv6_enabled | Set to true to enable an AAAA DNS record to be set as well as the A record | bool | `true` | no | | lambda_function_association | A config block that triggers a lambda function with specific actions | object | `` | no | -| log_expiration_days | Number of days after which to expunge the objects | string | `90` | no | -| log_glacier_transition_days | Number of days after which to move the data to the glacier storage tier | string | `60` | no | +| log_expiration_days | Number of days after which to expunge the objects | number | `90` | no | +| log_glacier_transition_days | Number of days after which to move the data to the glacier storage tier | number | `60` | no | | log_include_cookies | Include cookies in access logs | bool | `false` | no | | log_prefix | Path of logs in S3 bucket | string | `` | no | -| log_standard_transition_days | Number of days to persist in the standard storage tier before moving to the glacier tier | string | `30` | no | -| max_ttl | Maximum amount of time (in seconds) that an object is in a CloudFront cache | string | `31536000` | no | -| min_ttl | Minimum amount of time that you want objects to stay in CloudFront caches | string | `0` | no | +| log_standard_transition_days | Number of days to persist in the standard storage tier before moving to the glacier tier | number | `30` | no | +| max_ttl | Maximum amount of time (in seconds) that an object is in a CloudFront cache | number | `31536000` | no | +| min_ttl | Minimum amount of time that you want objects to stay in CloudFront caches | number | `0` | no | | minimum_protocol_version | Cloudfront TLS minimum protocol version | string | `TLSv1` | no | | name | Name (e.g. `bastion` or `app`) | string | - | yes | | namespace | Namespace (e.g. `eg` or `cp`) | string | `` | no | -| null | an empty string | string | `` | no | | origin_bucket | Origin S3 bucket name | string | `` | no | | origin_force_destroy | Delete all objects from the bucket so that the bucket can be destroyed without error (e.g. `true` or `false`) | bool | `false` | no | | origin_path | An optional element that causes CloudFront to request your content from a directory in your Amazon S3 bucket or your custom origin. It must begin with a /. Do not add a / at the end of the path. | string | `` | no | diff --git a/README.yaml b/README.yaml index 0474478d..ce9815f5 100644 --- a/README.yaml +++ b/README.yaml @@ -56,6 +56,11 @@ description: |- # How to use this project usage: |- + + For a complete example, see [examples/complete](examples/complete). + + For automated tests of the complete example using [bats](https://github.com/bats-core/bats-core) and [Terratest](https://github.com/gruntwork-io/terratest) (which tests and deploys the example on AWS), see [test](test). + ```hcl module "cdn" { source = "git::https://github.com/cloudposse/terraform-aws-cloudfront-s3-cdn.git?ref=master" @@ -67,8 +72,6 @@ usage: |- } ``` - Full working example can be found in [examples](./examples) folder. - ### Generating ACM Certificate Use the AWS cli to [request new ACM certifiates](http://docs.aws.amazon.com/acm/latest/userguide/gs-acm-request.html) (requires email validation) diff --git a/docs/terraform.md b/docs/terraform.md index a36d0c4b..ef58539b 100644 --- a/docs/terraform.md +++ b/docs/terraform.md @@ -15,10 +15,10 @@ | cors_allowed_methods | List of allowed methods (e.g. GET, PUT, POST, DELETE, HEAD) for S3 bucket | list(string) | `` | no | | cors_allowed_origins | List of allowed origins (e.g. example.com, test.com) for S3 bucket | list(string) | `` | no | | cors_expose_headers | List of expose header in the response for S3 bucket | list(string) | `` | no | -| cors_max_age_seconds | Time in seconds that browser can cache the response for S3 bucket | string | `3600` | no | +| cors_max_age_seconds | Time in seconds that browser can cache the response for S3 bucket | number | `3600` | no | | custom_error_response | List of one or more custom error response element maps | object | `` | no | | default_root_object | Object that CloudFront return when requests the root URL | string | `index.html` | no | -| default_ttl | Default amount of time (in seconds) that an object is in a CloudFront cache | string | `60` | no | +| default_ttl | Default amount of time (in seconds) that an object is in a CloudFront cache | number | `60` | no | | delimiter | Delimiter to be used between `namespace`, `stage`, `name` and `attributes` | string | `-` | no | | enabled | Select Enabled if you want CloudFront to begin processing requests as soon as the distribution is created, or select Disabled if you do not want CloudFront to begin processing requests after the distribution is created. | bool | `true` | no | | encryption_enabled | When set to 'true' the resource will have aes256 encryption enabled by default | bool | `false` | no | @@ -31,20 +31,18 @@ | geo_restriction_locations | List of country codes for which CloudFront either to distribute content (whitelist) or not distribute your content (blacklist) | list(string) | `` | no | | geo_restriction_type | Method that use to restrict distribution of your content by country: `none`, `whitelist`, or `blacklist` | string | `none` | no | | index_document | Amazon S3 returns this index document when requests are made to the root domain or any of the subfolders | string | `` | no | -| ipv6_enabled | Set to true to enable an AAAA DNS record to be set as well as the A record | bool | `false` | no | -| is_ipv6_enabled | State of CloudFront IPv6 | bool | `true` | no | +| ipv6_enabled | Set to true to enable an AAAA DNS record to be set as well as the A record | bool | `true` | no | | lambda_function_association | A config block that triggers a lambda function with specific actions | object | `` | no | -| log_expiration_days | Number of days after which to expunge the objects | string | `90` | no | -| log_glacier_transition_days | Number of days after which to move the data to the glacier storage tier | string | `60` | no | +| log_expiration_days | Number of days after which to expunge the objects | number | `90` | no | +| log_glacier_transition_days | Number of days after which to move the data to the glacier storage tier | number | `60` | no | | log_include_cookies | Include cookies in access logs | bool | `false` | no | | log_prefix | Path of logs in S3 bucket | string | `` | no | -| log_standard_transition_days | Number of days to persist in the standard storage tier before moving to the glacier tier | string | `30` | no | -| max_ttl | Maximum amount of time (in seconds) that an object is in a CloudFront cache | string | `31536000` | no | -| min_ttl | Minimum amount of time that you want objects to stay in CloudFront caches | string | `0` | no | +| log_standard_transition_days | Number of days to persist in the standard storage tier before moving to the glacier tier | number | `30` | no | +| max_ttl | Maximum amount of time (in seconds) that an object is in a CloudFront cache | number | `31536000` | no | +| min_ttl | Minimum amount of time that you want objects to stay in CloudFront caches | number | `0` | no | | minimum_protocol_version | Cloudfront TLS minimum protocol version | string | `TLSv1` | no | | name | Name (e.g. `bastion` or `app`) | string | - | yes | | namespace | Namespace (e.g. `eg` or `cp`) | string | `` | no | -| null | an empty string | string | `` | no | | origin_bucket | Origin S3 bucket name | string | `` | no | | origin_force_destroy | Delete all objects from the bucket so that the bucket can be destroyed without error (e.g. `true` or `false`) | bool | `false` | no | | origin_path | An optional element that causes CloudFront to request your content from a directory in your Amazon S3 bucket or your custom origin. It must begin with a /. Do not add a / at the end of the path. | string | `` | no | diff --git a/examples/complete/fixtures.us-west-1.tfvars b/examples/complete/fixtures.us-east-2.tfvars similarity index 83% rename from examples/complete/fixtures.us-west-1.tfvars rename to examples/complete/fixtures.us-east-2.tfvars index 072d33ad..f1eb2cdd 100644 --- a/examples/complete/fixtures.us-west-1.tfvars +++ b/examples/complete/fixtures.us-east-2.tfvars @@ -1,4 +1,4 @@ -region = "us-west-1" +region = "us-east-2" namespace = "eg" diff --git a/main.tf b/main.tf index 5ea6521b..a3603642 100644 --- a/main.tf +++ b/main.tf @@ -17,7 +17,7 @@ locals { } module "origin_label" { - source = "git::https://github.com/cloudposse/terraform-terraform-label.git?ref=tags/0.4.0" + source = "git::https://github.com/cloudposse/terraform-null-label.git?ref=tags/0.16.0" namespace = var.namespace stage = var.stage name = var.name @@ -110,7 +110,7 @@ resource "aws_s3_bucket" "origin" { allowed_headers = var.cors_allowed_headers allowed_methods = var.cors_allowed_methods allowed_origins = sort( - distinct(compact(concat(var.cors_allowed_origins, var.aliases))), + distinct(compact(concat(var.cors_allowed_origins, var.aliases))) ) expose_headers = var.cors_expose_headers max_age_seconds = var.cors_max_age_seconds @@ -118,7 +118,7 @@ resource "aws_s3_bucket" "origin" { } module "logs" { - source = "git::https://github.com/cloudposse/terraform-aws-s3-log-storage.git?ref=tags/0.5.0" + source = "git::https://github.com/cloudposse/terraform-aws-s3-log-storage.git?ref=tags/0.7.0" namespace = var.namespace stage = var.stage name = var.name @@ -133,7 +133,7 @@ module "logs" { } module "distribution_label" { - source = "git::https://github.com/cloudposse/terraform-terraform-label.git?ref=tags/0.4.0" + source = "git::https://github.com/cloudposse/terraform-null-label.git?ref=tags/0.16.0" namespace = var.namespace stage = var.stage name = var.name @@ -147,11 +147,10 @@ data "aws_s3_bucket" "selected" { } locals { - bucket = join( - "", + bucket = join("", compact( - concat([var.origin_bucket], concat([""], aws_s3_bucket.origin.*.id)), - ), + concat([var.origin_bucket], concat([""], aws_s3_bucket.origin.*.id)) + ) ) bucket_domain_name = var.use_regional_s3_endpoint ? format( @@ -163,7 +162,7 @@ locals { resource "aws_cloudfront_distribution" "default" { enabled = var.enabled - is_ipv6_enabled = var.is_ipv6_enabled + is_ipv6_enabled = var.ipv6_enabled comment = var.comment default_root_object = var.default_root_object price_class = var.price_class @@ -250,7 +249,7 @@ resource "aws_cloudfront_distribution" "default" { module "dns" { source = "git::https://github.com/cloudposse/terraform-aws-route53-alias.git?ref=tags/0.4.0" - enabled = var.enabled && length(var.parent_zone_id) > 0 || length(var.parent_zone_name) > 0 ? true : false + enabled = var.enabled && (var.parent_zone_id != "" || var.parent_zone_name != "") ? true : false aliases = var.aliases parent_zone_id = var.parent_zone_id parent_zone_name = var.parent_zone_name diff --git a/test/src/examples_complete_test.go b/test/src/examples_complete_test.go index b1ebc473..16ec4f76 100644 --- a/test/src/examples_complete_test.go +++ b/test/src/examples_complete_test.go @@ -16,7 +16,7 @@ func TestExamplesComplete(t *testing.T) { TerraformDir: "../../examples/complete", Upgrade: true, // Variables to pass to our Terraform code using -var-file options - VarFiles: []string{"fixtures.us-west-1.tfvars"}, + VarFiles: []string{"fixtures.us-east-2.tfvars"}, } // At the end of the test, run `terraform destroy` to clean up any resources that were created @@ -27,13 +27,11 @@ func TestExamplesComplete(t *testing.T) { // Run `terraform output` to get the value of an output variable cfArn := terraform.Output(t, terraformOptions, "cf_arn") - // Verify we're getting back the outputs we expect - assert.Contains(t, cfArn, "arn:aws:cloudfront::126450723953:distribution/") + assert.Contains(t, cfArn, "arn:aws:cloudfront::") // Run `terraform output` to get the value of an output variable s3BucketName := terraform.Output(t, terraformOptions, "s3_bucket") - expectedS3BucketName := "eg-test-cloudfront-s3-cdn-origin" // Verify we're getting back the outputs we expect assert.Equal(t, expectedS3BucketName, s3BucketName) diff --git a/variables.tf b/variables.tf index 4e9affe3..6cd53eea 100644 --- a/variables.tf +++ b/variables.tf @@ -1,18 +1,18 @@ variable "namespace" { - description = "Namespace (e.g. `eg` or `cp`)" type = string + description = "Namespace (e.g. `eg` or `cp`)" default = "" } variable "stage" { - description = "Stage (e.g. `prod`, `dev`, `staging`)" type = string + description = "Stage (e.g. `prod`, `dev`, `staging`)" default = "" } variable "name" { - description = "Name (e.g. `bastion` or `app`)" type = string + description = "Name (e.g. `bastion` or `app`)" } variable "delimiter" { @@ -112,12 +112,6 @@ variable "compress" { description = "Compress content for web requests that include Accept-Encoding: gzip in the request header" } -variable "is_ipv6_enabled" { - type = bool - default = true - description = "State of CloudFront IPv6" -} - variable "default_root_object" { type = string default = "index.html" @@ -143,16 +137,19 @@ variable "log_prefix" { } variable "log_standard_transition_days" { + type = number description = "Number of days to persist in the standard storage tier before moving to the glacier tier" default = 30 } variable "log_glacier_transition_days" { + type = number description = "Number of days after which to move the data to the glacier storage tier" default = 60 } variable "log_expiration_days" { + type = number description = "Number of days after which to expunge the objects" default = 90 } @@ -188,6 +185,7 @@ variable "cors_expose_headers" { } variable "cors_max_age_seconds" { + type = number default = 3600 description = "Time in seconds that browser can cache the response for S3 bucket" } @@ -229,16 +227,19 @@ variable "cached_methods" { } variable "default_ttl" { + type = number default = 60 description = "Default amount of time (in seconds) that an object is in a CloudFront cache" } variable "min_ttl" { + type = number default = 0 description = "Minimum amount of time that you want objects to stay in CloudFront caches" } variable "max_ttl" { + type = number default = 31536000 description = "Maximum amount of time (in seconds) that an object is in a CloudFront cache" } @@ -250,10 +251,11 @@ variable "trusted_signers" { } variable "geo_restriction_type" { + type = string + # e.g. "whitelist" default = "none" description = "Method that use to restrict distribution of your content by country: `none`, `whitelist`, or `blacklist`" - type = string } variable "geo_restriction_locations" { @@ -276,11 +278,6 @@ variable "parent_zone_name" { description = "Name of the hosted zone to contain this record (or specify `parent_zone_id`)" } -variable "null" { - description = "an empty string" - default = "" -} - variable "static_s3_bucket" { type = string default = "aws-cli" @@ -365,6 +362,6 @@ variable "routing_rules" { variable "ipv6_enabled" { type = bool - default = false + default = true description = "Set to true to enable an AAAA DNS record to be set as well as the A record" -} \ No newline at end of file +}