From 122667ee4ea8a9237ed1c6aece833fb22f0e2f2b Mon Sep 17 00:00:00 2001 From: Andriy Knysh Date: Mon, 28 Oct 2019 21:43:28 -0400 Subject: [PATCH] Convert to TF 0.12. Add tests. Add Codefresh test pipeline (#30) * Convert to TF 0.12. Add tests. Add Codefresh test pipeline * Update tests --- .travis.yml | 16 -- README.md | 146 ++++++++++++------ README.yaml | 82 ++++++++-- codefresh/test.yml | 74 +++++++++ docs/terraform.md | 66 ++++---- examples/complete/fixtures.us-east-2.tfvars | 49 ++++++ examples/complete/main.tf | 62 ++++++++ examples/complete/outputs.tf | 64 ++++++++ examples/complete/variables.tf | 142 ++++++++++++++++++ examples/complete/versions.tf | 10 ++ main.tf | 157 ++++++++++---------- outputs.tf | 24 +-- test/.gitignore | 1 + test/Makefile | 43 ++++++ test/Makefile.alpine | 5 + test/src/.gitignore | 2 + test/src/Gopkg.lock | 92 ++++++++++++ test/src/Gopkg.toml | 7 + test/src/Makefile | 50 +++++++ test/src/examples_complete_test.go | 62 ++++++++ variables.tf | 131 ++++++++-------- versions.tf | 10 ++ 22 files changed, 1035 insertions(+), 260 deletions(-) delete mode 100644 .travis.yml create mode 100644 codefresh/test.yml create mode 100644 examples/complete/fixtures.us-east-2.tfvars create mode 100644 examples/complete/main.tf create mode 100644 examples/complete/outputs.tf create mode 100644 examples/complete/variables.tf create mode 100644 examples/complete/versions.tf create mode 100644 test/.gitignore create mode 100644 test/Makefile create mode 100644 test/Makefile.alpine create mode 100644 test/src/.gitignore create mode 100644 test/src/Gopkg.lock create mode 100644 test/src/Gopkg.toml create mode 100644 test/src/Makefile create mode 100644 test/src/examples_complete_test.go create mode 100644 versions.tf diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 241026e..0000000 --- a/.travis.yml +++ /dev/null @@ -1,16 +0,0 @@ -addons: - apt: - packages: - - git - - make - - curl - -install: - - make init - -script: - - make terraform/install - - make terraform/get-plugins - - make terraform/get-modules - - make terraform/lint - - make terraform/validate diff --git a/README.md b/README.md index c0a1a21..7c8bc6a 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![Cloud Posse][logo]](https://cpco.io/homepage) -# terraform-aws-alb [![Build Status](https://travis-ci.org/cloudposse/terraform-aws-alb.svg?branch=master)](https://travis-ci.org/cloudposse/terraform-aws-alb) [![Latest Release](https://img.shields.io/github/release/cloudposse/terraform-aws-alb.svg)](https://github.com/cloudposse/terraform-aws-alb/releases/latest) [![Slack Community](https://slack.cloudposse.com/badge.svg)](https://slack.cloudposse.com) +# terraform-aws-alb [![Codefresh Build Status](https://g.codefresh.io/api/badges/pipeline/cloudposse/terraform-modules%2Fterraform-aws-alb?type=cf-1)](https://g.codefresh.io/public/accounts/cloudposse/pipelines/5db7391dfe309d4a2ed304fa) [![Latest Release](https://img.shields.io/github/release/cloudposse/terraform-aws-alb.svg)](https://github.com/cloudposse/terraform-aws-alb/releases/latest) [![Slack Community](https://slack.cloudposse.com/badge.svg)](https://slack.cloudposse.com) Terraform module to create an ALB, default ALB listener(s), and a default ALB target and related security groups. @@ -47,21 +47,73 @@ 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-alb/releases). -Include this module in your existing terraform code: +For a complete example, see [examples/complete](examples/complete). + +For automated test of the complete example using `bats` and `Terratest`, see [test](test). ```hcl -module "alb" { - source = "git::https://github.com/cloudposse/terraform-aws-alb.git?ref=tags/0.2.0" - namespace = "eg" - name = "app" - stage = "dev" - - vpc_id = "xxxxxxxxx" - ip_address_type = "ipv4" - - subnet_ids = ["xxxxxxxx", "xxxxxxxx"] - access_logs_region = "us-west-2" -} + provider "aws" { + region = var.region + } + + module "vpc" { + source = "git::https://github.com/cloudposse/terraform-aws-vpc.git?ref=tags/0.8.1" + namespace = var.namespace + stage = var.stage + name = var.name + delimiter = var.delimiter + attributes = var.attributes + cidr_block = var.vpc_cidr_block + tags = var.tags + } + + module "subnets" { + source = "git::https://github.com/cloudposse/terraform-aws-dynamic-subnets.git?ref=tags/0.16.1" + availability_zones = var.availability_zones + namespace = var.namespace + stage = var.stage + name = var.name + attributes = var.attributes + delimiter = var.delimiter + vpc_id = module.vpc.vpc_id + igw_id = module.vpc.igw_id + cidr_block = module.vpc.vpc_cidr_block + nat_gateway_enabled = false + nat_instance_enabled = false + tags = var.tags + } + + module "alb" { + source = "git::https://github.com/cloudposse/terraform-aws-alb.git?ref=master" + namespace = var.namespace + stage = var.stage + name = var.name + attributes = var.attributes + delimiter = var.delimiter + vpc_id = module.vpc.vpc_id + security_group_ids = [module.vpc.vpc_default_security_group_id] + subnet_ids = module.subnets.public_subnet_ids + internal = var.internal + http_enabled = var.http_enabled + access_logs_enabled = var.access_logs_enabled + alb_access_logs_s3_bucket_force_destroy = var.alb_access_logs_s3_bucket_force_destroy + access_logs_region = var.access_logs_region + cross_zone_load_balancing_enabled = var.cross_zone_load_balancing_enabled + http2_enabled = var.http2_enabled + idle_timeout = var.idle_timeout + ip_address_type = var.ip_address_type + deletion_protection_enabled = var.deletion_protection_enabled + deregistration_delay = var.deregistration_delay + health_check_path = var.health_check_path + health_check_timeout = var.health_check_timeout + health_check_healthy_threshold = var.health_check_healthy_threshold + health_check_unhealthy_threshold = var.health_check_unhealthy_threshold + health_check_interval = var.health_check_interval + health_check_matcher = var.health_check_matcher + target_group_port = var.target_group_port + target_group_target_type = var.target_group_target_type + tags = var.tags + } ``` @@ -83,45 +135,45 @@ Available targets: | Name | Description | Type | Default | Required | |------|-------------|:----:|:-----:|:-----:| -| access_logs_enabled | A boolean flag to enable/disable access_logs | string | `true` | no | -| access_logs_prefix | The S3 bucket prefix | string | `` | no | +| access_logs_enabled | A boolean flag to enable/disable access_logs | bool | `true` | no | +| access_logs_prefix | The S3 log bucket prefix | string | `` | no | | access_logs_region | The region for the access_logs S3 bucket | string | `us-east-1` | no | -| alb_access_logs_s3_bucket_force_destroy | A boolean that indicates all objects should be deleted from the ALB access logs S3 bucket so that the bucket can be destroyed without error | string | `false` | no | -| attributes | Additional attributes, e.g. `1` | list | `` | no | +| alb_access_logs_s3_bucket_force_destroy | A boolean that indicates all objects should be deleted from the ALB access logs S3 bucket so that the bucket can be destroyed without error | bool | `false` | no | +| attributes | Additional attributes (_e.g._ "1") | list(string) | `` | no | | certificate_arn | The ARN of the default SSL certificate for HTTPS listener | string | `` | no | -| cross_zone_load_balancing_enabled | A boolean flag to enable/disable cross zone load balancing | string | `true` | no | -| deletion_protection_enabled | A boolean flag to enable/disable deletion protection for ALB | string | `false` | no | -| delimiter | Delimiter to be used between `namespace`, `name`, `stage` and `attributes` | string | `-` | no | -| deregistration_delay | The amount of time to wait in seconds before changing the state of a deregistering target to unused | string | `15` | no | -| health_check_healthy_threshold | The number of consecutive health checks successes required before considering an unhealthy target healthy | string | `2` | no | -| health_check_interval | The duration in seconds in between health checks | string | `15` | no | +| cross_zone_load_balancing_enabled | A boolean flag to enable/disable cross zone load balancing | bool | `true` | no | +| deletion_protection_enabled | A boolean flag to enable/disable deletion protection for ALB | bool | `false` | no | +| delimiter | Delimiter between `namespace`, `stage`, `name` and `attributes` | string | `-` | no | +| deregistration_delay | The amount of time to wait in seconds before changing the state of a deregistering target to unused | number | `15` | no | +| health_check_healthy_threshold | The number of consecutive health checks successes required before considering an unhealthy target healthy | number | `2` | no | +| health_check_interval | The duration in seconds in between health checks | number | `15` | no | | health_check_matcher | The HTTP response codes to indicate a healthy check | string | `200-399` | no | | health_check_path | The destination for the health check request | string | `/` | no | -| health_check_timeout | The amount of time to wait in seconds before failing a health check request | string | `10` | no | -| health_check_unhealthy_threshold | The number of consecutive health check failures required before considering the target unhealthy | string | `2` | no | -| http2_enabled | A boolean flag to enable/disable HTTP/2 | string | `true` | no | -| http_enabled | A boolean flag to enable/disable HTTP listener | string | `true` | no | -| http_ingress_cidr_blocks | List of CIDR blocks to allow in HTTP security group | list | `` | no | -| http_ingress_prefix_list_ids | List of prefix list IDs for allowing access to HTTP ingress security group | list | `` | no | -| http_port | The port for the HTTP listener | string | `80` | no | -| https_enabled | A boolean flag to enable/disable HTTPS listener | string | `false` | no | -| https_ingress_cidr_blocks | List of CIDR blocks to allow in HTTPS security group | list | `` | no | -| https_ingress_prefix_list_ids | List of prefix list IDs for allowing access to HTTPS ingress security group | list | `` | no | -| https_port | The port for the HTTPS listener | string | `443` | no | -| https_ssl_policy | The name of the SSL Policy for the listener. | string | `ELBSecurityPolicy-2015-05` | no | -| idle_timeout | The time in seconds that the connection is allowed to be idle | string | `60` | no | -| internal | A boolean flag to determine whether the ALB should be internal | string | `false` | no | +| health_check_timeout | The amount of time to wait in seconds before failing a health check request | number | `10` | no | +| health_check_unhealthy_threshold | The number of consecutive health check failures required before considering the target unhealthy | number | `2` | no | +| http2_enabled | A boolean flag to enable/disable HTTP/2 | bool | `true` | no | +| http_enabled | A boolean flag to enable/disable HTTP listener | bool | `true` | no | +| http_ingress_cidr_blocks | List of CIDR blocks to allow in HTTP security group | list(string) | `` | no | +| http_ingress_prefix_list_ids | List of prefix list IDs for allowing access to HTTP ingress security group | list(string) | `` | no | +| http_port | The port for the HTTP listener | number | `80` | no | +| https_enabled | A boolean flag to enable/disable HTTPS listener | bool | `false` | no | +| https_ingress_cidr_blocks | List of CIDR blocks to allow in HTTPS security group | list(string) | `` | no | +| https_ingress_prefix_list_ids | List of prefix list IDs for allowing access to HTTPS ingress security group | list(string) | `` | no | +| https_port | The port for the HTTPS listener | number | `443` | no | +| https_ssl_policy | The name of the SSL Policy for the listener | string | `ELBSecurityPolicy-2015-05` | no | +| idle_timeout | The time in seconds that the connection is allowed to be idle | number | `60` | no | +| internal | A boolean flag to determine whether the ALB should be internal | bool | `false` | no | | ip_address_type | The type of IP addresses used by the subnets for your load balancer. The possible values are `ipv4` and `dualstack`. | string | `ipv4` | no | -| name | Solution name, e.g. `app` | string | - | yes | -| namespace | Namespace, which could be your organization name, e.g. `cp` or `cloudposse` | string | - | yes | -| security_group_ids | A list of additional security group IDs to allow access to ALB | list | `` | no | -| stage | Stage, e.g. `prod`, `staging`, `dev`, or `test` | string | - | yes | -| subnet_ids | A list of subnet IDs to associate with ALB | list | - | yes | -| tags | Additional tags (e.g. `map(`BusinessUnit`,`XYZ`) | map | `` | no | -| target_group_additional_tags | The additional tags to apply to the target group | map | `` | no | +| name | Name of the application | string | - | yes | +| namespace | Namespace (e.g. `eg` or `cp`) | string | `` | no | +| security_group_ids | A list of additional security group IDs to allow access to ALB | list(string) | `` | no | +| stage | Stage (e.g. `prod`, `dev`, `staging`) | string | `` | no | +| subnet_ids | A list of subnet IDs to associate with ALB | list(string) | - | yes | +| tags | Additional tags (_e.g._ { BusinessUnit : ABC }) | map(string) | `` | no | +| target_group_additional_tags | The additional tags to apply to the target group | map(string) | `` | no | | target_group_name | The name for the default target group, uses a module label name if left empty | string | `` | no | -| target_group_port | The port for the default target group | string | `80` | no | -| target_group_target_type | The type (instance, ip or lambda) of targets that can be registered with the target group | string | `ip` | no | +| target_group_port | The port for the default target group | number | `80` | no | +| target_group_target_type | The type (`instance`, `ip` or `lambda`) of targets that can be registered with the target group | string | `ip` | no | | vpc_id | VPC ID to associate with ALB | string | - | yes | ## Outputs diff --git a/README.yaml b/README.yaml index 9a09c6c..46151ec 100644 --- a/README.yaml +++ b/README.yaml @@ -18,9 +18,9 @@ github_repo: cloudposse/terraform-aws-alb # Badges to display badges: - - name: "Build Status" - image: "https://travis-ci.org/cloudposse/terraform-aws-alb.svg?branch=master" - url: "https://travis-ci.org/cloudposse/terraform-aws-alb" + - name: "Codefresh Build Status" + image: "https://g.codefresh.io/api/badges/pipeline/cloudposse/terraform-modules%2Fterraform-aws-alb?type=cf-1" + url: "https://g.codefresh.io/public/accounts/cloudposse/pipelines/5db7391dfe309d4a2ed304fa" - name: "Latest Release" image: "https://img.shields.io/github/release/cloudposse/terraform-aws-alb.svg" url: "https://github.com/cloudposse/terraform-aws-alb/releases/latest" @@ -39,21 +39,73 @@ description: |- # How to use this project usage: |- - Include this module in your existing terraform code: + For a complete example, see [examples/complete](examples/complete). + + For automated test of the complete example using `bats` and `Terratest`, see [test](test). ```hcl - module "alb" { - source = "git::https://github.com/cloudposse/terraform-aws-alb.git?ref=tags/0.2.0" - namespace = "eg" - name = "app" - stage = "dev" + provider "aws" { + region = var.region + } + + module "vpc" { + source = "git::https://github.com/cloudposse/terraform-aws-vpc.git?ref=tags/0.8.1" + namespace = var.namespace + stage = var.stage + name = var.name + delimiter = var.delimiter + attributes = var.attributes + cidr_block = var.vpc_cidr_block + tags = var.tags + } - vpc_id = "xxxxxxxxx" - ip_address_type = "ipv4" + module "subnets" { + source = "git::https://github.com/cloudposse/terraform-aws-dynamic-subnets.git?ref=tags/0.16.1" + availability_zones = var.availability_zones + namespace = var.namespace + stage = var.stage + name = var.name + attributes = var.attributes + delimiter = var.delimiter + vpc_id = module.vpc.vpc_id + igw_id = module.vpc.igw_id + cidr_block = module.vpc.vpc_cidr_block + nat_gateway_enabled = false + nat_instance_enabled = false + tags = var.tags + } - subnet_ids = ["xxxxxxxx", "xxxxxxxx"] - access_logs_region = "us-west-2" - } + module "alb" { + source = "git::https://github.com/cloudposse/terraform-aws-alb.git?ref=master" + namespace = var.namespace + stage = var.stage + name = var.name + attributes = var.attributes + delimiter = var.delimiter + vpc_id = module.vpc.vpc_id + security_group_ids = [module.vpc.vpc_default_security_group_id] + subnet_ids = module.subnets.public_subnet_ids + internal = var.internal + http_enabled = var.http_enabled + access_logs_enabled = var.access_logs_enabled + alb_access_logs_s3_bucket_force_destroy = var.alb_access_logs_s3_bucket_force_destroy + access_logs_region = var.access_logs_region + cross_zone_load_balancing_enabled = var.cross_zone_load_balancing_enabled + http2_enabled = var.http2_enabled + idle_timeout = var.idle_timeout + ip_address_type = var.ip_address_type + deletion_protection_enabled = var.deletion_protection_enabled + deregistration_delay = var.deregistration_delay + health_check_path = var.health_check_path + health_check_timeout = var.health_check_timeout + health_check_healthy_threshold = var.health_check_healthy_threshold + health_check_unhealthy_threshold = var.health_check_unhealthy_threshold + health_check_interval = var.health_check_interval + health_check_matcher = var.health_check_matcher + target_group_port = var.target_group_port + target_group_target_type = var.target_group_target_type + tags = var.tags + } ``` # Other files to include in this README from the project folder @@ -70,4 +122,4 @@ contributors: - name: "Andriy Knysh" github: "aknysh" - name: "Sarkis Varozian" - github: "sarkis" \ No newline at end of file + github: "sarkis" diff --git a/codefresh/test.yml b/codefresh/test.yml new file mode 100644 index 0000000..ddd07f9 --- /dev/null +++ b/codefresh/test.yml @@ -0,0 +1,74 @@ +version: '1.0' + +stages: + - Prepare + - Test + +steps: + wait: + title: Wait + stage: Prepare + image: codefresh/cli:latest + commands: + - codefresh get builds --pipeline=${{CF_REPO_NAME}} --status running --limit 1000 -o json | jq --arg id ${{CF_BUILD_ID}} -ser 'flatten|.[-1].id==$id' + retry: + maxAttempts: 10 + delay: 20 + exponentialFactor: 1.1 + + main_clone: + title: "Clone repository" + type: git-clone + stage: Prepare + description: "Initialize" + repo: ${{CF_REPO_OWNER}}/${{CF_REPO_NAME}} + git: CF-default + revision: ${{CF_REVISION}} + + clean_init: + title: Prepare build-harness and test-harness + image: ${{TEST_IMAGE}} + stage: Prepare + commands: + - cf_export PATH="/usr/local/terraform/0.12/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" + - make init + - git -C build-harness checkout master + - make -C test/ clean init TEST_HARNESS_BRANCH=master + - make -C test/src clean init + - find . -type d -name '.terraform' | xargs rm -rf + - find . -type f -name 'terraform.tfstate*' -exec rm -f {} \; + + test: + type: "parallel" + title: "Run tests" + description: "Run all tests in parallel" + stage: Test + steps: + test_readme_lint: + title: "Test README.md updated" + stage: "Test" + image: ${{TEST_IMAGE}} + description: Test "readme/lint" + commands: + - make readme/lint + + test_module: + title: Test module with bats + image: ${{TEST_IMAGE}} + stage: Test + commands: + - make -C test/ module + + test_examples_complete: + title: Test "examples/complete" with bats + image: ${{TEST_IMAGE}} + stage: Test + commands: + - make -C test/ examples/complete + + test_examples_complete_terratest: + title: Test "examples/complete" with terratest + image: ${{TEST_IMAGE}} + stage: Test + commands: + - make -C test/src diff --git a/docs/terraform.md b/docs/terraform.md index 8c4112d..59d6b30 100644 --- a/docs/terraform.md +++ b/docs/terraform.md @@ -2,45 +2,45 @@ | Name | Description | Type | Default | Required | |------|-------------|:----:|:-----:|:-----:| -| access_logs_enabled | A boolean flag to enable/disable access_logs | string | `true` | no | -| access_logs_prefix | The S3 bucket prefix | string | `` | no | +| access_logs_enabled | A boolean flag to enable/disable access_logs | bool | `true` | no | +| access_logs_prefix | The S3 log bucket prefix | string | `` | no | | access_logs_region | The region for the access_logs S3 bucket | string | `us-east-1` | no | -| alb_access_logs_s3_bucket_force_destroy | A boolean that indicates all objects should be deleted from the ALB access logs S3 bucket so that the bucket can be destroyed without error | string | `false` | no | -| attributes | Additional attributes, e.g. `1` | list | `` | no | +| alb_access_logs_s3_bucket_force_destroy | A boolean that indicates all objects should be deleted from the ALB access logs S3 bucket so that the bucket can be destroyed without error | bool | `false` | no | +| attributes | Additional attributes (_e.g._ "1") | list(string) | `` | no | | certificate_arn | The ARN of the default SSL certificate for HTTPS listener | string | `` | no | -| cross_zone_load_balancing_enabled | A boolean flag to enable/disable cross zone load balancing | string | `true` | no | -| deletion_protection_enabled | A boolean flag to enable/disable deletion protection for ALB | string | `false` | no | -| delimiter | Delimiter to be used between `namespace`, `name`, `stage` and `attributes` | string | `-` | no | -| deregistration_delay | The amount of time to wait in seconds before changing the state of a deregistering target to unused | string | `15` | no | -| health_check_healthy_threshold | The number of consecutive health checks successes required before considering an unhealthy target healthy | string | `2` | no | -| health_check_interval | The duration in seconds in between health checks | string | `15` | no | +| cross_zone_load_balancing_enabled | A boolean flag to enable/disable cross zone load balancing | bool | `true` | no | +| deletion_protection_enabled | A boolean flag to enable/disable deletion protection for ALB | bool | `false` | no | +| delimiter | Delimiter between `namespace`, `stage`, `name` and `attributes` | string | `-` | no | +| deregistration_delay | The amount of time to wait in seconds before changing the state of a deregistering target to unused | number | `15` | no | +| health_check_healthy_threshold | The number of consecutive health checks successes required before considering an unhealthy target healthy | number | `2` | no | +| health_check_interval | The duration in seconds in between health checks | number | `15` | no | | health_check_matcher | The HTTP response codes to indicate a healthy check | string | `200-399` | no | | health_check_path | The destination for the health check request | string | `/` | no | -| health_check_timeout | The amount of time to wait in seconds before failing a health check request | string | `10` | no | -| health_check_unhealthy_threshold | The number of consecutive health check failures required before considering the target unhealthy | string | `2` | no | -| http2_enabled | A boolean flag to enable/disable HTTP/2 | string | `true` | no | -| http_enabled | A boolean flag to enable/disable HTTP listener | string | `true` | no | -| http_ingress_cidr_blocks | List of CIDR blocks to allow in HTTP security group | list | `` | no | -| http_ingress_prefix_list_ids | List of prefix list IDs for allowing access to HTTP ingress security group | list | `` | no | -| http_port | The port for the HTTP listener | string | `80` | no | -| https_enabled | A boolean flag to enable/disable HTTPS listener | string | `false` | no | -| https_ingress_cidr_blocks | List of CIDR blocks to allow in HTTPS security group | list | `` | no | -| https_ingress_prefix_list_ids | List of prefix list IDs for allowing access to HTTPS ingress security group | list | `` | no | -| https_port | The port for the HTTPS listener | string | `443` | no | -| https_ssl_policy | The name of the SSL Policy for the listener. | string | `ELBSecurityPolicy-2015-05` | no | -| idle_timeout | The time in seconds that the connection is allowed to be idle | string | `60` | no | -| internal | A boolean flag to determine whether the ALB should be internal | string | `false` | no | +| health_check_timeout | The amount of time to wait in seconds before failing a health check request | number | `10` | no | +| health_check_unhealthy_threshold | The number of consecutive health check failures required before considering the target unhealthy | number | `2` | no | +| http2_enabled | A boolean flag to enable/disable HTTP/2 | bool | `true` | no | +| http_enabled | A boolean flag to enable/disable HTTP listener | bool | `true` | no | +| http_ingress_cidr_blocks | List of CIDR blocks to allow in HTTP security group | list(string) | `` | no | +| http_ingress_prefix_list_ids | List of prefix list IDs for allowing access to HTTP ingress security group | list(string) | `` | no | +| http_port | The port for the HTTP listener | number | `80` | no | +| https_enabled | A boolean flag to enable/disable HTTPS listener | bool | `false` | no | +| https_ingress_cidr_blocks | List of CIDR blocks to allow in HTTPS security group | list(string) | `` | no | +| https_ingress_prefix_list_ids | List of prefix list IDs for allowing access to HTTPS ingress security group | list(string) | `` | no | +| https_port | The port for the HTTPS listener | number | `443` | no | +| https_ssl_policy | The name of the SSL Policy for the listener | string | `ELBSecurityPolicy-2015-05` | no | +| idle_timeout | The time in seconds that the connection is allowed to be idle | number | `60` | no | +| internal | A boolean flag to determine whether the ALB should be internal | bool | `false` | no | | ip_address_type | The type of IP addresses used by the subnets for your load balancer. The possible values are `ipv4` and `dualstack`. | string | `ipv4` | no | -| name | Solution name, e.g. `app` | string | - | yes | -| namespace | Namespace, which could be your organization name, e.g. `cp` or `cloudposse` | string | - | yes | -| security_group_ids | A list of additional security group IDs to allow access to ALB | list | `` | no | -| stage | Stage, e.g. `prod`, `staging`, `dev`, or `test` | string | - | yes | -| subnet_ids | A list of subnet IDs to associate with ALB | list | - | yes | -| tags | Additional tags (e.g. `map(`BusinessUnit`,`XYZ`) | map | `` | no | -| target_group_additional_tags | The additional tags to apply to the target group | map | `` | no | +| name | Name of the application | string | - | yes | +| namespace | Namespace (e.g. `eg` or `cp`) | string | `` | no | +| security_group_ids | A list of additional security group IDs to allow access to ALB | list(string) | `` | no | +| stage | Stage (e.g. `prod`, `dev`, `staging`) | string | `` | no | +| subnet_ids | A list of subnet IDs to associate with ALB | list(string) | - | yes | +| tags | Additional tags (_e.g._ { BusinessUnit : ABC }) | map(string) | `` | no | +| target_group_additional_tags | The additional tags to apply to the target group | map(string) | `` | no | | target_group_name | The name for the default target group, uses a module label name if left empty | string | `` | no | -| target_group_port | The port for the default target group | string | `80` | no | -| target_group_target_type | The type (instance, ip or lambda) of targets that can be registered with the target group | string | `ip` | no | +| target_group_port | The port for the default target group | number | `80` | no | +| target_group_target_type | The type (`instance`, `ip` or `lambda`) of targets that can be registered with the target group | string | `ip` | no | | vpc_id | VPC ID to associate with ALB | string | - | yes | ## Outputs diff --git a/examples/complete/fixtures.us-east-2.tfvars b/examples/complete/fixtures.us-east-2.tfvars new file mode 100644 index 0000000..a3e8df5 --- /dev/null +++ b/examples/complete/fixtures.us-east-2.tfvars @@ -0,0 +1,49 @@ +region = "us-east-2" + +availability_zones = ["us-east-2a", "us-east-2b"] + +namespace = "eg" + +stage = "test" + +name = "alb" + +vpc_cidr_block = "172.16.0.0/16" + +internal = false + +http_enabled = true + +access_logs_enabled = true + +alb_access_logs_s3_bucket_force_destroy = true + +access_logs_region = "us-east-2" + +cross_zone_load_balancing_enabled = false + +http2_enabled = true + +idle_timeout = 60 + +ip_address_type = "ipv4" + +deletion_protection_enabled = false + +deregistration_delay = 15 + +health_check_path = "/" + +health_check_timeout = 10 + +health_check_healthy_threshold = 2 + +health_check_unhealthy_threshold = 2 + +health_check_interval = 15 + +health_check_matcher = "200-399" + +target_group_port = 80 + +target_group_target_type = "ip" diff --git a/examples/complete/main.tf b/examples/complete/main.tf new file mode 100644 index 0000000..fe7d205 --- /dev/null +++ b/examples/complete/main.tf @@ -0,0 +1,62 @@ +provider "aws" { + region = var.region +} + +module "vpc" { + source = "git::https://github.com/cloudposse/terraform-aws-vpc.git?ref=tags/0.8.1" + namespace = var.namespace + stage = var.stage + name = var.name + delimiter = var.delimiter + attributes = var.attributes + cidr_block = var.vpc_cidr_block + tags = var.tags +} + +module "subnets" { + source = "git::https://github.com/cloudposse/terraform-aws-dynamic-subnets.git?ref=tags/0.16.1" + availability_zones = var.availability_zones + namespace = var.namespace + stage = var.stage + name = var.name + attributes = var.attributes + delimiter = var.delimiter + vpc_id = module.vpc.vpc_id + igw_id = module.vpc.igw_id + cidr_block = module.vpc.vpc_cidr_block + nat_gateway_enabled = false + nat_instance_enabled = false + tags = var.tags +} + +module "alb" { + source = "../.." + namespace = var.namespace + stage = var.stage + name = var.name + attributes = var.attributes + delimiter = var.delimiter + vpc_id = module.vpc.vpc_id + security_group_ids = [module.vpc.vpc_default_security_group_id] + subnet_ids = module.subnets.public_subnet_ids + internal = var.internal + http_enabled = var.http_enabled + access_logs_enabled = var.access_logs_enabled + alb_access_logs_s3_bucket_force_destroy = var.alb_access_logs_s3_bucket_force_destroy + access_logs_region = var.access_logs_region + cross_zone_load_balancing_enabled = var.cross_zone_load_balancing_enabled + http2_enabled = var.http2_enabled + idle_timeout = var.idle_timeout + ip_address_type = var.ip_address_type + deletion_protection_enabled = var.deletion_protection_enabled + deregistration_delay = var.deregistration_delay + health_check_path = var.health_check_path + health_check_timeout = var.health_check_timeout + health_check_healthy_threshold = var.health_check_healthy_threshold + health_check_unhealthy_threshold = var.health_check_unhealthy_threshold + health_check_interval = var.health_check_interval + health_check_matcher = var.health_check_matcher + target_group_port = var.target_group_port + target_group_target_type = var.target_group_target_type + tags = var.tags +} diff --git a/examples/complete/outputs.tf b/examples/complete/outputs.tf new file mode 100644 index 0000000..52683ba --- /dev/null +++ b/examples/complete/outputs.tf @@ -0,0 +1,64 @@ +output "public_subnet_cidrs" { + value = module.subnets.public_subnet_cidrs + description = "Public subnet CIDRs" +} + +output "private_subnet_cidrs" { + value = module.subnets.private_subnet_cidrs + description = "Private subnet CIDRs" +} + +output "vpc_cidr" { + value = module.vpc.vpc_cidr_block + description = "VPC ID" +} + +output "alb_name" { + description = "The ARN suffix of the ALB" + value = module.alb.alb_name +} + +output "alb_arn" { + description = "The ARN of the ALB" + value = module.alb.alb_arn +} + +output "alb_arn_suffix" { + description = "The ARN suffix of the ALB" + value = module.alb.alb_arn_suffix +} + +output "alb_dns_name" { + description = "DNS name of ALB" + value = module.alb.alb_dns_name +} + +output "alb_zone_id" { + description = "The ID of the zone which ALB is provisioned" + value = module.alb.alb_zone_id +} + +output "security_group_id" { + description = "The security group ID of the ALB" + value = module.alb.security_group_id +} + +output "default_target_group_arn" { + description = "The default target group ARN" + value = module.alb.default_target_group_arn +} + +output "http_listener_arn" { + description = "The ARN of the HTTP listener" + value = module.alb.http_listener_arn +} + +output "listener_arns" { + description = "A list of all the listener ARNs" + value = module.alb.listener_arns +} + +output "access_logs_bucket_id" { + description = "The S3 bucket ID for access logs" + value = module.alb.access_logs_bucket_id +} diff --git a/examples/complete/variables.tf b/examples/complete/variables.tf new file mode 100644 index 0000000..1a6177e --- /dev/null +++ b/examples/complete/variables.tf @@ -0,0 +1,142 @@ +variable "region" { + type = string + description = "AWS Region for S3 bucket" +} + +variable "availability_zones" { + type = list(string) + description = "List of availability zones" +} + +variable "vpc_cidr_block" { + type = string + description = "VPC CIDR block" +} + +variable "namespace" { + type = string + description = "Namespace (e.g. `eg` or `cp`)" +} + +variable "stage" { + type = string + description = "Stage (e.g. `prod`, `dev`, `staging`)" +} + +variable "name" { + type = string + description = "Name of the application" +} + +variable "delimiter" { + type = string + default = "-" + description = "Delimiter between `namespace`, `stage`, `name` and `attributes`" +} + +variable "attributes" { + type = list(string) + description = "Additional attributes (_e.g._ \"1\")" + default = [] +} + +variable "tags" { + type = map(string) + description = "Additional tags (_e.g._ { BusinessUnit : ABC })" + default = {} +} + +variable "internal" { + type = bool + description = "A boolean flag to determine whether the ALB should be internal" +} + +variable "http_enabled" { + type = bool + description = "A boolean flag to enable/disable HTTP listener" +} + +variable "access_logs_enabled" { + type = bool + description = "A boolean flag to enable/disable access_logs" +} + +variable "access_logs_region" { + type = string + description = "The region for the access_logs S3 bucket" +} + +variable "cross_zone_load_balancing_enabled" { + type = bool + description = "A boolean flag to enable/disable cross zone load balancing" +} + +variable "http2_enabled" { + type = bool + description = "A boolean flag to enable/disable HTTP/2" +} + +variable "idle_timeout" { + type = number + description = "The time in seconds that the connection is allowed to be idle" +} + +variable "ip_address_type" { + type = string + description = "The type of IP addresses used by the subnets for your load balancer. The possible values are `ipv4` and `dualstack`." +} + +variable "deletion_protection_enabled" { + type = bool + description = "A boolean flag to enable/disable deletion protection for ALB" +} + +variable "deregistration_delay" { + type = number + description = "The amount of time to wait in seconds before changing the state of a deregistering target to unused" +} + +variable "health_check_path" { + type = string + description = "The destination for the health check request" +} + +variable "health_check_timeout" { + type = number + description = "The amount of time to wait in seconds before failing a health check request" +} + +variable "health_check_healthy_threshold" { + type = number + description = "The number of consecutive health checks successes required before considering an unhealthy target healthy" +} + +variable "health_check_unhealthy_threshold" { + type = number + description = "The number of consecutive health check failures required before considering the target unhealthy" +} + +variable "health_check_interval" { + type = number + description = "The duration in seconds in between health checks" +} + +variable "health_check_matcher" { + type = string + description = "The HTTP response codes to indicate a healthy check" +} + +variable "alb_access_logs_s3_bucket_force_destroy" { + type = bool + description = "A boolean that indicates all objects should be deleted from the ALB access logs S3 bucket so that the bucket can be destroyed without error" +} + +variable "target_group_port" { + type = number + description = "The port for the default target group" +} + +variable "target_group_target_type" { + type = string + description = "The type (`instance`, `ip` or `lambda`) of targets that can be registered with the target group" +} diff --git a/examples/complete/versions.tf b/examples/complete/versions.tf new file mode 100644 index 0000000..9840ed7 --- /dev/null +++ b/examples/complete/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = "~> 0.12.0" + + required_providers { + aws = "~> 2.0" + template = "~> 2.0" + null = "~> 2.0" + local = "~> 1.3" + } +} diff --git a/main.tf b/main.tf index 9a38adf..001013b 100644 --- a/main.tf +++ b/main.tf @@ -1,18 +1,18 @@ module "default_label" { - source = "git::https://github.com/cloudposse/terraform-terraform-label.git?ref=tags/0.2.1" - attributes = "${var.attributes}" - delimiter = "${var.delimiter}" - name = "${var.name}" - namespace = "${var.namespace}" - stage = "${var.stage}" - tags = "${var.tags}" + source = "git::https://github.com/cloudposse/terraform-null-label.git?ref=tags/0.16.0" + attributes = var.attributes + delimiter = var.delimiter + name = var.name + namespace = var.namespace + stage = var.stage + tags = var.tags } resource "aws_security_group" "default" { description = "Controls access to the ALB (HTTP/HTTPS)" - vpc_id = "${var.vpc_id}" - name = "${module.default_label.id}" - tags = "${module.default_label.tags}" + vpc_id = var.vpc_id + name = module.default_label.id + tags = module.default_label.tags } resource "aws_security_group_rule" "egress" { @@ -21,120 +21,127 @@ resource "aws_security_group_rule" "egress" { to_port = "0" protocol = "-1" cidr_blocks = ["0.0.0.0/0"] - security_group_id = "${aws_security_group.default.id}" + security_group_id = aws_security_group.default.id } resource "aws_security_group_rule" "http_ingress" { - count = "${var.http_enabled == "true" ? 1 : 0}" + count = var.http_enabled ? 1 : 0 type = "ingress" - from_port = "${var.http_port}" - to_port = "${var.http_port}" + from_port = var.http_port + to_port = var.http_port protocol = "tcp" - cidr_blocks = ["${var.http_ingress_cidr_blocks}"] - prefix_list_ids = ["${var.http_ingress_prefix_list_ids}"] - security_group_id = "${aws_security_group.default.id}" + cidr_blocks = var.http_ingress_cidr_blocks + prefix_list_ids = var.http_ingress_prefix_list_ids + security_group_id = aws_security_group.default.id } resource "aws_security_group_rule" "https_ingress" { - count = "${var.https_enabled == "true" ? 1 : 0}" + count = var.https_enabled ? 1 : 0 type = "ingress" - from_port = "${var.https_port}" - to_port = "${var.https_port}" + from_port = var.https_port + to_port = var.https_port protocol = "tcp" - cidr_blocks = ["${var.https_ingress_cidr_blocks}"] - prefix_list_ids = ["${var.https_ingress_prefix_list_ids}"] - security_group_id = "${aws_security_group.default.id}" + cidr_blocks = var.https_ingress_cidr_blocks + prefix_list_ids = var.https_ingress_prefix_list_ids + security_group_id = aws_security_group.default.id } module "access_logs" { - source = "git::https://github.com/cloudposse/terraform-aws-lb-s3-bucket.git?ref=tags/0.1.4" - attributes = "${compact(concat(var.attributes, list("alb", "access", "logs")))}" - delimiter = "${var.delimiter}" - name = "${var.name}" - namespace = "${var.namespace}" - stage = "${var.stage}" - tags = "${var.tags}" - region = "${var.access_logs_region}" - force_destroy = "${var.alb_access_logs_s3_bucket_force_destroy}" + source = "git::https://github.com/cloudposse/terraform-aws-lb-s3-bucket.git?ref=tags/0.2.0" + name = var.name + namespace = var.namespace + stage = var.stage + attributes = compact(concat(var.attributes, ["alb", "access", "logs"])) + delimiter = var.delimiter + tags = var.tags + region = var.access_logs_region + force_destroy = var.alb_access_logs_s3_bucket_force_destroy } resource "aws_lb" "default" { - name = "${module.default_label.id}" - tags = "${module.default_label.tags}" - internal = "${var.internal}" - load_balancer_type = "application" - security_groups = ["${compact(concat(var.security_group_ids, list(aws_security_group.default.id)))}"] - subnets = ["${var.subnet_ids}"] - enable_cross_zone_load_balancing = "${var.cross_zone_load_balancing_enabled}" - enable_http2 = "${var.http2_enabled}" - idle_timeout = "${var.idle_timeout}" - ip_address_type = "${var.ip_address_type}" - enable_deletion_protection = "${var.deletion_protection_enabled}" + name = module.default_label.id + tags = module.default_label.tags + internal = var.internal + load_balancer_type = "application" + + security_groups = compact( + concat(var.security_group_ids, [aws_security_group.default.id]), + ) + + subnets = var.subnet_ids + enable_cross_zone_load_balancing = var.cross_zone_load_balancing_enabled + enable_http2 = var.http2_enabled + idle_timeout = var.idle_timeout + ip_address_type = var.ip_address_type + enable_deletion_protection = var.deletion_protection_enabled access_logs { - bucket = "${module.access_logs.bucket_id}" - prefix = "${var.access_logs_prefix}" - enabled = "${var.access_logs_enabled}" + bucket = module.access_logs.bucket_id + prefix = var.access_logs_prefix + enabled = var.access_logs_enabled } } module "default_target_group_label" { - source = "git::https://github.com/cloudposse/terraform-terraform-label.git?ref=tags/0.2.1" - attributes = "${concat(var.attributes, list("default"))}" - delimiter = "${var.delimiter}" - name = "${var.name}" - namespace = "${var.namespace}" - stage = "${var.stage}" - tags = "${var.tags}" + source = "git::https://github.com/cloudposse/terraform-null-label.git?ref=tags/0.16.0" + attributes = concat(var.attributes, ["default"]) + delimiter = var.delimiter + name = var.name + namespace = var.namespace + stage = var.stage + tags = var.tags } resource "aws_lb_target_group" "default" { - name = "${var.target_group_name == "" ? module.default_target_group_label.id : var.target_group_name}" - port = "${var.target_group_port}" + name = var.target_group_name == "" ? module.default_target_group_label.id : var.target_group_name + port = var.target_group_port protocol = "HTTP" - vpc_id = "${var.vpc_id}" - target_type = "${var.target_group_target_type}" - deregistration_delay = "${var.deregistration_delay}" + vpc_id = var.vpc_id + target_type = var.target_group_target_type + deregistration_delay = var.deregistration_delay health_check { - path = "${var.health_check_path}" - timeout = "${var.health_check_timeout}" - healthy_threshold = "${var.health_check_healthy_threshold}" - unhealthy_threshold = "${var.health_check_unhealthy_threshold}" - interval = "${var.health_check_interval}" - matcher = "${var.health_check_matcher}" + path = var.health_check_path + timeout = var.health_check_timeout + healthy_threshold = var.health_check_healthy_threshold + unhealthy_threshold = var.health_check_unhealthy_threshold + interval = var.health_check_interval + matcher = var.health_check_matcher } lifecycle { create_before_destroy = true } - tags = "${merge(module.default_target_group_label.tags, var.target_group_additional_tags)}" + tags = merge( + module.default_target_group_label.tags, + var.target_group_additional_tags + ) } resource "aws_lb_listener" "http" { - count = "${var.http_enabled == "true" ? 1 : 0}" - load_balancer_arn = "${aws_lb.default.arn}" - port = "${var.http_port}" + count = var.http_enabled ? 1 : 0 + load_balancer_arn = aws_lb.default.arn + port = var.http_port protocol = "HTTP" default_action { - target_group_arn = "${aws_lb_target_group.default.arn}" + target_group_arn = aws_lb_target_group.default.arn type = "forward" } } resource "aws_lb_listener" "https" { - count = "${var.https_enabled == "true" ? 1 : 0}" - load_balancer_arn = "${aws_lb.default.arn}" + count = var.https_enabled ? 1 : 0 + load_balancer_arn = aws_lb.default.arn - port = "${var.https_port}" + port = var.https_port protocol = "HTTPS" - ssl_policy = "${var.https_ssl_policy}" - certificate_arn = "${var.certificate_arn}" + ssl_policy = var.https_ssl_policy + certificate_arn = var.certificate_arn default_action { - target_group_arn = "${aws_lb_target_group.default.arn}" + target_group_arn = aws_lb_target_group.default.arn type = "forward" } } diff --git a/outputs.tf b/outputs.tf index 0ab948d..6d16c86 100644 --- a/outputs.tf +++ b/outputs.tf @@ -1,54 +1,56 @@ output "alb_name" { description = "The ARN suffix of the ALB" - value = "${aws_lb.default.name}" + value = aws_lb.default.name } output "alb_arn" { description = "The ARN of the ALB" - value = "${aws_lb.default.arn}" + value = aws_lb.default.arn } output "alb_arn_suffix" { description = "The ARN suffix of the ALB" - value = "${aws_lb.default.arn_suffix}" + value = aws_lb.default.arn_suffix } output "alb_dns_name" { description = "DNS name of ALB" - value = "${aws_lb.default.dns_name}" + value = aws_lb.default.dns_name } output "alb_zone_id" { description = "The ID of the zone which ALB is provisioned" - value = "${aws_lb.default.zone_id}" + value = aws_lb.default.zone_id } output "security_group_id" { description = "The security group ID of the ALB" - value = "${aws_security_group.default.id}" + value = aws_security_group.default.id } output "default_target_group_arn" { description = "The default target group ARN" - value = "${aws_lb_target_group.default.arn}" + value = aws_lb_target_group.default.arn } output "http_listener_arn" { description = "The ARN of the HTTP listener" - value = "${join("", aws_lb_listener.http.*.arn)}" + value = join("", aws_lb_listener.http.*.arn) } output "https_listener_arn" { description = "The ARN of the HTTPS listener" - value = "${join("", aws_lb_listener.https.*.arn)}" + value = join("", aws_lb_listener.https.*.arn) } output "listener_arns" { description = "A list of all the listener ARNs" - value = "${compact(concat(aws_lb_listener.http.*.arn, aws_lb_listener.https.*.arn))}" + value = compact( + concat(aws_lb_listener.http.*.arn, aws_lb_listener.https.*.arn) + ) } output "access_logs_bucket_id" { description = "The S3 bucket ID for access logs" - value = "${module.access_logs.bucket_id}" + value = module.access_logs.bucket_id } diff --git a/test/.gitignore b/test/.gitignore new file mode 100644 index 0000000..442804a --- /dev/null +++ b/test/.gitignore @@ -0,0 +1 @@ +.test-harness diff --git a/test/Makefile b/test/Makefile new file mode 100644 index 0000000..17b2fe7 --- /dev/null +++ b/test/Makefile @@ -0,0 +1,43 @@ +TEST_HARNESS ?= https://github.com/cloudposse/test-harness.git +TEST_HARNESS_BRANCH ?= master +TEST_HARNESS_PATH = $(realpath .test-harness) +BATS_ARGS ?= --tap +BATS_LOG ?= test.log + +# Define a macro to run the tests +define RUN_TESTS +@echo "Running tests in $(1)" +@cd $(1) && bats $(BATS_ARGS) $(addsuffix .bats,$(addprefix $(TEST_HARNESS_PATH)/test/terraform/,$(TESTS))) +endef + +default: all + +-include Makefile.* + +## Provision the test-harnesss +.test-harness: + [ -d $@ ] || git clone --depth=1 -b $(TEST_HARNESS_BRANCH) $(TEST_HARNESS) $@ + +## Initialize the tests +init: .test-harness + +## Install all dependencies (OS specific) +deps:: + @exit 0 + +## Clean up the test harness +clean: + [ "$(TEST_HARNESS_PATH)" == "/" ] || rm -rf $(TEST_HARNESS_PATH) + +## Run all tests +all: module examples/complete + +## Run basic sanity checks against the module itself +module: export TESTS ?= installed lint get-modules module-pinning get-plugins provider-pinning validate terraform-docs input-descriptions output-descriptions +module: deps + $(call RUN_TESTS, ../) + +## Run tests against example +examples/complete: export TESTS ?= installed lint get-modules get-plugins validate +examples/complete: deps + $(call RUN_TESTS, ../$@) diff --git a/test/Makefile.alpine b/test/Makefile.alpine new file mode 100644 index 0000000..7925b18 --- /dev/null +++ b/test/Makefile.alpine @@ -0,0 +1,5 @@ +ifneq (,$(wildcard /sbin/apk)) +## Install all dependencies for alpine +deps:: init + @apk add --update terraform-docs@cloudposse json2hcl@cloudposse +endif diff --git a/test/src/.gitignore b/test/src/.gitignore new file mode 100644 index 0000000..31b0219 --- /dev/null +++ b/test/src/.gitignore @@ -0,0 +1,2 @@ +.gopath +vendor/ diff --git a/test/src/Gopkg.lock b/test/src/Gopkg.lock new file mode 100644 index 0000000..87bb6bd --- /dev/null +++ b/test/src/Gopkg.lock @@ -0,0 +1,92 @@ +# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. + + +[[projects]] + digest = "1:ffe9824d294da03b391f44e1ae8281281b4afc1bdaa9588c9097785e3af10cec" + name = "github.com/davecgh/go-spew" + packages = ["spew"] + pruneopts = "UT" + revision = "8991bc29aa16c548c550c7ff78260e27b9ab7c73" + version = "v1.1.1" + +[[projects]] + digest = "1:75d6042fc66aebc974cc49b0c6c7cc3b9adb5f8130fbfa0dbec0820d990afa25" + name = "github.com/gruntwork-io/terratest" + packages = [ + "modules/collections", + "modules/customerrors", + "modules/files", + "modules/logger", + "modules/retry", + "modules/shell", + "modules/ssh", + "modules/terraform", + ] + pruneopts = "UT" + revision = "892abb2c35878d0808101bbfe6559e931dc2d354" + version = "v0.16.0" + +[[projects]] + digest = "1:0028cb19b2e4c3112225cd871870f2d9cf49b9b4276531f03438a88e94be86fe" + name = "github.com/pmezard/go-difflib" + packages = ["difflib"] + pruneopts = "UT" + revision = "792786c7400a136282c1664665ae0a8db921c6c2" + version = "v1.0.0" + +[[projects]] + digest = "1:5da8ce674952566deae4dbc23d07c85caafc6cfa815b0b3e03e41979cedb8750" + name = "github.com/stretchr/testify" + packages = [ + "assert", + "require", + ] + pruneopts = "UT" + revision = "ffdc059bfe9ce6a4e144ba849dbedead332c6053" + version = "v1.3.0" + +[[projects]] + branch = "master" + digest = "1:831470c2758c8b733941144f2803a0ccad0632c5a767415b777ebd296b5f463e" + name = "golang.org/x/crypto" + packages = [ + "curve25519", + "ed25519", + "ed25519/internal/edwards25519", + "internal/chacha20", + "internal/subtle", + "poly1305", + "ssh", + "ssh/agent", + ] + pruneopts = "UT" + revision = "22d7a77e9e5f409e934ed268692e56707cd169e5" + +[[projects]] + branch = "master" + digest = "1:76ee51c3f468493aff39dbacc401e8831fbb765104cbf613b89bef01cf4bad70" + name = "golang.org/x/net" + packages = ["context"] + pruneopts = "UT" + revision = "f3200d17e092c607f615320ecaad13d87ad9a2b3" + +[[projects]] + branch = "master" + digest = "1:181f3fd33e620b958b5ab77da177cf775cdcccd7db82963607875fbd09ae995e" + name = "golang.org/x/sys" + packages = [ + "cpu", + "unix", + ] + pruneopts = "UT" + revision = "9cd6430ef91e39e1a0ec0470cf1321a33ef1b887" + +[solve-meta] + analyzer-name = "dep" + analyzer-version = 1 + input-imports = [ + "github.com/gruntwork-io/terratest/modules/terraform", + "github.com/stretchr/testify/assert", + ] + solver-name = "gps-cdcl" + solver-version = 1 diff --git a/test/src/Gopkg.toml b/test/src/Gopkg.toml new file mode 100644 index 0000000..995bac5 --- /dev/null +++ b/test/src/Gopkg.toml @@ -0,0 +1,7 @@ +[[constraint]] + name = "github.com/stretchr/testify" + version = "1.2.2" + +[prune] + go-tests = true + unused-packages = true diff --git a/test/src/Makefile b/test/src/Makefile new file mode 100644 index 0000000..ccc62df --- /dev/null +++ b/test/src/Makefile @@ -0,0 +1,50 @@ +PACKAGE = terraform-aws-alb +GOEXE ?= /usr/bin/go +GOPATH = $(CURDIR)/.gopath +GOBIN = $(GOPATH)/bin +BASE = $(GOPATH)/src/$(PACKAGE) +PATH := $(PATH):$(GOBIN) + +export TF_DATA_DIR ?= $(CURDIR)/.terraform +export TF_CLI_ARGS_init ?= -get-plugins=true +export GOPATH + +.PHONY: all +## Default target +all: test + +ifneq (,$(wildcard /sbin/apk)) +## Install go, if not installed +$(GOEXE): + apk add --update go +endif + +ifeq ($(shell uname -s),Linux) +## Install all `dep`, if not installed +$(GOBIN)/dep: + @mkdir -p $(GOBIN) + @curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh +endif + +## Prepare the GOPATH +$(BASE): $(GOEXE) + @mkdir -p $(dir $@) + @ln -sf $(CURDIR) $@ + +## Download vendor dependencies to vendor/ +$(BASE)/vendor: $(BASE) $(GOBIN)/dep + cd $(BASE) && dep ensure + +.PHONY : init +## Initialize tests +init: $(BASE)/vendor + +.PHONY : test +## Run tests +test: init + cd $(BASE) && go test -v -timeout 30m -run TestExamplesComplete + +.PHONY : clean +## Clean up files +clean: + rm -rf .gopath/ vendor/ $(TF_DATA_DIR) diff --git a/test/src/examples_complete_test.go b/test/src/examples_complete_test.go new file mode 100644 index 0000000..adb21c6 --- /dev/null +++ b/test/src/examples_complete_test.go @@ -0,0 +1,62 @@ +package test + +import ( + "testing" + + "github.com/gruntwork-io/terratest/modules/terraform" + "github.com/stretchr/testify/assert" +) + +// Test the Terraform module in examples/complete using Terratest. +func TestExamplesComplete(t *testing.T) { + t.Parallel() + + terraformOptions := &terraform.Options{ + // The path to where our Terraform code is located + TerraformDir: "../../examples/complete", + Upgrade: true, + // Variables to pass to our Terraform code using -var-file options + VarFiles: []string{"fixtures.us-east-2.tfvars"}, + } + + // At the end of the test, run `terraform destroy` to clean up any resources that were created + defer terraform.Destroy(t, terraformOptions) + + // This will run `terraform init` and `terraform apply` and fail the test if there are any errors + terraform.InitAndApply(t, terraformOptions) + + // Run `terraform output` to get the value of an output variable + vpcCidr := terraform.Output(t, terraformOptions, "vpc_cidr") + // Verify we're getting back the outputs we expect + assert.Equal(t, "172.16.0.0/16", vpcCidr) + + // Run `terraform output` to get the value of an output variable + privateSubnetCidrs := terraform.OutputList(t, terraformOptions, "private_subnet_cidrs") + // Verify we're getting back the outputs we expect + assert.Equal(t, []string{"172.16.0.0/19", "172.16.32.0/19"}, privateSubnetCidrs) + + // Run `terraform output` to get the value of an output variable + publicSubnetCidrs := terraform.OutputList(t, terraformOptions, "public_subnet_cidrs") + // Verify we're getting back the outputs we expect + assert.Equal(t, []string{"172.16.96.0/19", "172.16.128.0/19"}, publicSubnetCidrs) + + // Run `terraform output` to get the value of an output variable + accessLogsBucketId := terraform.Output(t, terraformOptions, "access_logs_bucket_id") + // Verify we're getting back the outputs we expect + assert.Equal(t, "eg-test-alb-alb-access-logs", accessLogsBucketId) + + // Run `terraform output` to get the value of an output variable + albName := terraform.Output(t, terraformOptions, "alb_name") + // Verify we're getting back the outputs we expect + assert.Equal(t, "eg-test-alb", albName) + + // Run `terraform output` to get the value of an output variable + defaultTargetGroupArn := terraform.Output(t, terraformOptions, "default_target_group_arn") + // Verify we're getting back the outputs we expect + assert.Contains(t, defaultTargetGroupArn, "arn:aws:elasticloadbalancing:us-east-2:126450723953:targetgroup/eg-test-alb-default") + + // Run `terraform output` to get the value of an output variable + httpListenerArn := terraform.Output(t, terraformOptions, "http_listener_arn") + // Verify we're getting back the outputs we expect + assert.Contains(t, httpListenerArn, "arn:aws:elasticloadbalancing:us-east-2:126450723953:listener/app/eg-test-alb") +} diff --git a/variables.tf b/variables.tf index 610266c..8d9ad30 100644 --- a/variables.tf +++ b/variables.tf @@ -1,231 +1,236 @@ variable "namespace" { - type = "string" - description = "Namespace, which could be your organization name, e.g. `cp` or `cloudposse`" + type = string + description = "Namespace (e.g. `eg` or `cp`)" + default = "" } variable "stage" { - type = "string" - description = "Stage, e.g. `prod`, `staging`, `dev`, or `test`" + type = string + description = "Stage (e.g. `prod`, `dev`, `staging`)" + default = "" } variable "name" { - type = "string" - description = "Solution name, e.g. `app`" + type = string + description = "Name of the application" } variable "delimiter" { - type = "string" + type = string default = "-" - description = "Delimiter to be used between `namespace`, `name`, `stage` and `attributes`" + description = "Delimiter between `namespace`, `stage`, `name` and `attributes`" } variable "attributes" { - type = "list" + type = list(string) + description = "Additional attributes (_e.g._ \"1\")" default = [] - description = "Additional attributes, e.g. `1`" } variable "tags" { - type = "map" + type = map(string) + description = "Additional tags (_e.g._ { BusinessUnit : ABC })" default = {} - description = "Additional tags (e.g. `map(`BusinessUnit`,`XYZ`)" } variable "vpc_id" { - type = "string" + type = string description = "VPC ID to associate with ALB" } variable "subnet_ids" { - type = "list" + type = list(string) description = "A list of subnet IDs to associate with ALB" } variable "security_group_ids" { - type = "list" + type = list(string) default = [] description = "A list of additional security group IDs to allow access to ALB" } variable "internal" { - type = "string" - default = "false" + type = bool + default = false description = "A boolean flag to determine whether the ALB should be internal" } variable "http_port" { - type = "string" - default = "80" + type = number + default = 80 description = "The port for the HTTP listener" } variable "http_enabled" { - type = "string" - default = "true" + type = bool + default = true description = "A boolean flag to enable/disable HTTP listener" } variable "http_ingress_cidr_blocks" { - type = "list" + type = list(string) default = ["0.0.0.0/0"] description = "List of CIDR blocks to allow in HTTP security group" } variable "http_ingress_prefix_list_ids" { - type = "list" + type = list(string) default = [] description = "List of prefix list IDs for allowing access to HTTP ingress security group" } variable "certificate_arn" { - type = "string" + type = string default = "" description = "The ARN of the default SSL certificate for HTTPS listener" } variable "https_port" { - type = "string" - default = "443" + type = number + default = 443 description = "The port for the HTTPS listener" } variable "https_enabled" { - type = "string" - default = "false" + type = bool + default = false description = "A boolean flag to enable/disable HTTPS listener" } variable "https_ingress_cidr_blocks" { - type = "list" + type = list(string) default = ["0.0.0.0/0"] description = "List of CIDR blocks to allow in HTTPS security group" } variable "https_ingress_prefix_list_ids" { - type = "list" + type = list(string) default = [] description = "List of prefix list IDs for allowing access to HTTPS ingress security group" } variable "https_ssl_policy" { - description = "The name of the SSL Policy for the listener." + type = string + description = "The name of the SSL Policy for the listener" default = "ELBSecurityPolicy-2015-05" } variable "access_logs_prefix" { - type = "string" + type = string default = "" - description = "The S3 bucket prefix" + description = "The S3 log bucket prefix" } variable "access_logs_enabled" { - type = "string" - default = "true" + type = bool + default = true description = "A boolean flag to enable/disable access_logs" } variable "access_logs_region" { - type = "string" + type = string default = "us-east-1" description = "The region for the access_logs S3 bucket" } variable "cross_zone_load_balancing_enabled" { - type = "string" - default = "true" + type = bool + default = true description = "A boolean flag to enable/disable cross zone load balancing" } variable "http2_enabled" { - type = "string" - default = "true" + type = bool + default = true description = "A boolean flag to enable/disable HTTP/2" } variable "idle_timeout" { - type = "string" - default = "60" + type = number + default = 60 description = "The time in seconds that the connection is allowed to be idle" } variable "ip_address_type" { - type = "string" + type = string default = "ipv4" description = "The type of IP addresses used by the subnets for your load balancer. The possible values are `ipv4` and `dualstack`." } variable "deletion_protection_enabled" { - type = "string" - default = "false" + type = bool + default = false description = "A boolean flag to enable/disable deletion protection for ALB" } variable "deregistration_delay" { - type = "string" - default = "15" + type = number + default = 15 description = "The amount of time to wait in seconds before changing the state of a deregistering target to unused" } variable "health_check_path" { - type = "string" + type = string default = "/" description = "The destination for the health check request" } variable "health_check_timeout" { - type = "string" - default = "10" + type = number + default = 10 description = "The amount of time to wait in seconds before failing a health check request" } variable "health_check_healthy_threshold" { - type = "string" - default = "2" + type = number + default = 2 description = "The number of consecutive health checks successes required before considering an unhealthy target healthy" } variable "health_check_unhealthy_threshold" { - type = "string" - default = "2" + type = number + default = 2 description = "The number of consecutive health check failures required before considering the target unhealthy" } variable "health_check_interval" { - type = "string" - default = "15" + type = number + default = 15 description = "The duration in seconds in between health checks" } variable "health_check_matcher" { - type = "string" + type = string default = "200-399" description = "The HTTP response codes to indicate a healthy check" } variable "alb_access_logs_s3_bucket_force_destroy" { - description = "A boolean that indicates all objects should be deleted from the ALB access logs S3 bucket so that the bucket can be destroyed without error" + type = bool default = false + description = "A boolean that indicates all objects should be deleted from the ALB access logs S3 bucket so that the bucket can be destroyed without error" } variable "target_group_port" { + type = number + default = 80 description = "The port for the default target group" - default = "80" } variable "target_group_name" { - type = "string" + type = string default = "" description = "The name for the default target group, uses a module label name if left empty" } variable "target_group_target_type" { - type = "string" + type = string default = "ip" - description = "The type (instance, ip or lambda) of targets that can be registered with the target group" + description = "The type (`instance`, `ip` or `lambda`) of targets that can be registered with the target group" } variable "target_group_additional_tags" { - type = "map" + type = map(string) default = {} description = "The additional tags to apply to the target group" } diff --git a/versions.tf b/versions.tf new file mode 100644 index 0000000..9840ed7 --- /dev/null +++ b/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = "~> 0.12.0" + + required_providers { + aws = "~> 2.0" + template = "~> 2.0" + null = "~> 2.0" + local = "~> 1.3" + } +}