diff --git a/.travis.yml b/.travis.yml index 698518b..4e386c8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,9 +4,6 @@ dist: trusty rvm: - 2.4.2 -services: - - docker - before_install: - echo "before_install" @@ -20,18 +17,20 @@ before_script: # Get a random region from the awscli and use it through the remainder of the test cycle. - export AWS_REGION=$(docker run --env AWS_DEFAULT_REGION=us-east-2 --env AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY} --env AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID} garland/aws-cli-docker aws ec2 describe-regions --query 'Regions[].{Name:RegionName}' --output text | shuf | head -n1) - export TF_VAR_region=${AWS_REGION} + - export TF_WARN_OUTPUT_ERRORS=1 - echo "using AWS_REGION=${AWS_REGION}" - - curl --silent --output terraform.zip https://releases.hashicorp.com/terraform/0.11.3/terraform_0.11.3_linux_amd64.zip - - sha256sum terraform.zip | grep "6b8a7b83954597d36bbed23913dd51bc253906c612a070a21db373eab71b277b" -q + - curl --silent --output terraform.zip https://releases.hashicorp.com/terraform/0.11.5/terraform_0.11.5_linux_amd64.zip + - sha256sum terraform.zip | grep "131c440263382c79c7f783b70ff35cd1d03eb31c44f7738d153d95a0b8436ac9" -q - unzip terraform.zip ; rm -f terraform.zip; chmod +x terraform - mkdir -p ${HOME}/bin ; export PATH=${PATH}:${HOME}/bin; mv terraform ${HOME}/bin/ - terraform -v script: - echo 'script' + - - terraform init - terraform fmt -check=true - - terraform validate -var "region=${AWS_REGION}" -var "subnets=[]" -var "vpc_id=vpc-abcde012" -var "load_balancer_name=my-lb" -var "log_bucket_name=my-log-bucket" -var "load_balancer_security_groups=[]" + - terraform validate -var "region=${AWS_REGION}" -var "subnets=[]" -var "vpc_id=vpc-abcde012" -var "load_balancer_name=my-lb" -var "log_bucket_name=my-log-bucket" -var "security_groups=[]" - docker run --rm -v $(pwd):/app/ --workdir=/app/ -t wata727/tflint --error-with-issues - cd examples/alb_test_fixture - terraform init diff --git a/CHANGELOG.md b/CHANGELOG.md index a6af835..02089a8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,20 +5,32 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). -## [v3.0.0] - 2018-03- +## [v3.1.0] - 2018-03-22 + +### Added + +* extra certs can now be applied to HTTPS listeners via the `extra_ssl_certs` list variable and corresponding `extra_ssl_certs_count`. + +### Changed + +* `load_balancer_security_groups` moved to simpler `security_groups`. +* `name_prefix` changed back to `name` as the inflexibility of a 6 character prefix is overly restricting. Name conflicts must be dealt with by the developer. (cheers, @michaelmoussa 🎉) +* upgraded terraform and kitchen terraform. terraform 0.11.4 and above errors out on warnings but has been mitigated with `TF_WARN_OUTPUT_ERRORS=1` per [this issue](https://github.com/hashicorp/terraform/issues/17655). + +## [v3.0.0] - 2018-03-20 ### Added * default values added for most target group and listener attributes. * new application load balancer attributes added as variables with defaults. -* tests now covering listeners. +* tests now cover listeners. ### Changed * listeners and target groups now defined by lists of maps allowing many-to-many relationships of those resources. * listeners and target groups creation is now data driven through variables giving greater flexibility. * `name_prefix` used where possible to avoid naming conflicts in resource testing. -* logging to S3 now made manditory and done outside the module as this is better practice. +* logging to S3 now made manditory and done outside the module as this is better practice. (thanks, @alexjurkiewicz 🥂) * terraform 0.11.3 now used in CI. 0.11.4 seems to have warnings on plan that become errors in CI. ## [v2.5.0] - 2018-03-07 diff --git a/Gemfile b/Gemfile index bd954d0..4252e7c 100644 --- a/Gemfile +++ b/Gemfile @@ -3,8 +3,7 @@ ruby '2.4.2' source 'https://rubygems.org/' do - gem 'awspec', '~> 1.0.0' - gem 'kitchen-terraform', '~> 3.1' + gem 'awspec', '~> 1.4.2' + gem 'kitchen-terraform', '~> 3.2' gem 'kitchen-verifier-awspec', '~> 0.1.1' - gem 'rhcl', '~> 0.1.0' end diff --git a/examples/alb_test_fixture/locals.tf b/examples/alb_test_fixture/locals.tf index a9f814f..91443a4 100644 --- a/examples/alb_test_fixture/locals.tf +++ b/examples/alb_test_fixture/locals.tf @@ -1,19 +1,25 @@ locals { - tags = "${map("Environment", "test", "GithubRepo", "tf-aws-alb", "GithubOrg", "terraform-aws-modules", "Workspace", "${terraform.workspace}")}" - log_bucket_name = "${var.log_bucket_name}-${data.aws_caller_identity.current.account_id}-${data.aws_region.current.name}" + tags = "${map("Environment", "test", + "GithubRepo", "tf-aws-alb", + "GithubOrg", "terraform-aws-modules", + "Workspace", "${terraform.workspace}", + )}" + + log_bucket_name = "${var.log_bucket_name}-${data.aws_caller_identity.current.account_id}-${data.aws_region.current.name}" + https_listeners_count = 2 https_listeners = "${list( - map( - "certificate_arn", aws_iam_server_certificate.fixture_cert.arn, - "port", 443 - ), - map( - "certificate_arn", aws_iam_server_certificate.fixture_cert.arn, - "port", 8443, - "ssl_policy", "ELBSecurityPolicy-TLS-1-2-2017-01", - "target_group_index", 1 - ) + map( + "certificate_arn", aws_iam_server_certificate.fixture_cert.0.arn, + "port", 443, + ), + map( + "certificate_arn", aws_iam_server_certificate.fixture_cert.1.arn, + "port", 8443, + "ssl_policy", "ELBSecurityPolicy-TLS-1-2-2017-01", + "target_group_index", 1, + ), )}" http_tcp_listeners_count = 3 @@ -21,30 +27,57 @@ locals { http_tcp_listeners = "${list( map( "port", 80, - "protocol", "HTTP" + "protocol", "HTTP", ), map( "port", 8080, "protocol", "HTTP", - "target_group_index", 0 + "target_group_index", 0, ), map( "port", 8081, "protocol", "HTTP", - "target_group_index", 1 - ) - )}" + "target_group_index", 1, + ), + )}" target_groups_count = 2 target_groups = "${list( map("name", "foo", "backend_protocol", "HTTP", - "backend_port", 80 + "backend_port", 80, ), map("name", "bar", "backend_protocol", "HTTP", - "backend_port", 8080 - ) + "backend_port", 8080, + ), + )}" + + extra_ssl_certs_count = 4 + + extra_ssl_certs = "${list( + map("certificate_arn", aws_iam_server_certificate.fixture_cert.0.arn, + "https_listener_index","1", + ), + map("certificate_arn", aws_iam_server_certificate.fixture_cert.1.arn, + "https_listener_index","0", + ), + map("certificate_arn", aws_iam_server_certificate.fixture_cert.2.arn, + "https_listener_index","0", + ), + map("certificate_arn", aws_iam_server_certificate.fixture_cert.3.arn, + "https_listener_index","0", + ), )}" + + # helpful for debugging + # https_listeners_count = 0 + # https_listeners = "${list()}" + # http_tcp_listeners_count = 0 + # http_tcp_listeners = "${list()}" + # target_groups_count = 0 + # target_groups = "${list()}" + # extra_ssl_certs_count = 0 + # extra_ssl_certs = "${list()}" } diff --git a/examples/alb_test_fixture/main.tf b/examples/alb_test_fixture/main.tf index de8dc60..76e21d3 100644 --- a/examples/alb_test_fixture/main.tf +++ b/examples/alb_test_fixture/main.tf @@ -1,5 +1,5 @@ terraform { - required_version = ">= 0.11.3" + required_version = "= 0.11.5" } provider "aws" { @@ -7,18 +7,25 @@ provider "aws" { region = "${var.region}" } -resource "random_id" "alb_name_suffix" { - byte_length = 16 +provider "random" { + version = "= 1.1.0" +} + +resource "random_string" "suffix" { + length = 8 + special = false } resource "aws_iam_server_certificate" "fixture_cert" { - name = "test_cert-${data.aws_caller_identity.current.account_id}-${data.aws_region.current.name}" + name_prefix = "test_cert-${data.aws_caller_identity.current.account_id}-${data.aws_region.current.name}" certificate_body = "${file("${path.module}/../../examples/alb_test_fixture/certs/example.crt.pem")}" private_key = "${file("${path.module}/../../examples/alb_test_fixture/certs/example.key.pem")}" lifecycle { create_before_destroy = true } + + count = 4 } resource "aws_s3_bucket" "log_bucket" { @@ -59,18 +66,20 @@ module "security_group" { } module "alb" { - source = "../.." - load_balancer_name = "test-alb-${random_id.alb_name_suffix.hex}" - load_balancer_security_groups = ["${module.security_group.this_security_group_id}"] - log_bucket_name = "${aws_s3_bucket.log_bucket.id}" - log_location_prefix = "${var.log_location_prefix}" - subnets = "${module.vpc.public_subnets}" - tags = "${local.tags}" - vpc_id = "${module.vpc.vpc_id}" - https_listeners = "${local.https_listeners}" - https_listeners_count = "${local.https_listeners_count}" - http_tcp_listeners = "${local.http_tcp_listeners}" - http_tcp_listeners_count = "${local.http_tcp_listeners_count}" - target_groups = "${local.target_groups}" - target_groups_count = "${local.target_groups_count}" + source = "../.." + load_balancer_name = "test-alb-${random_string.suffix.result}" + security_groups = ["${module.security_group.this_security_group_id}"] + log_bucket_name = "${aws_s3_bucket.log_bucket.id}" + log_location_prefix = "${var.log_location_prefix}" + subnets = "${module.vpc.public_subnets}" + tags = "${local.tags}" + vpc_id = "${module.vpc.vpc_id}" + https_listeners = "${local.https_listeners}" + https_listeners_count = "${local.https_listeners_count}" + http_tcp_listeners = "${local.http_tcp_listeners}" + http_tcp_listeners_count = "${local.http_tcp_listeners_count}" + target_groups = "${local.target_groups}" + target_groups_count = "${local.target_groups_count}" + extra_ssl_certs = "${local.extra_ssl_certs}" + extra_ssl_certs_count = "${local.extra_ssl_certs_count}" } diff --git a/main.tf b/main.tf index d9cd656..e4dd5ba 100644 --- a/main.tf +++ b/main.tf @@ -2,7 +2,7 @@ resource "aws_lb" "application" { load_balancer_type = "application" name = "${var.load_balancer_name}" internal = "${var.load_balancer_is_internal}" - security_groups = ["${var.load_balancer_security_groups}"] + security_groups = ["${var.security_groups}"] subnets = ["${var.subnets}"] idle_timeout = "${var.idle_timeout}" enable_deletion_protection = "${var.enable_deletion_protection}" @@ -79,3 +79,9 @@ resource "aws_lb_listener" "frontend_https" { type = "forward" } } + +resource "aws_lb_listener_certificate" "https_listener" { + listener_arn = "${aws_lb_listener.frontend_https.*.arn[lookup(var.extra_ssl_certs[count.index], "https_listener_index")]}" + certificate_arn = "${lookup(var.extra_ssl_certs[count.index], "certificate_arn")}" + count = "${var.extra_ssl_certs_count}" +} diff --git a/test/integration/default/test_alb.rb b/test/integration/default/test_alb.rb index d551c4f..d3308d2 100755 --- a/test/integration/default/test_alb.rb +++ b/test/integration/default/test_alb.rb @@ -1,10 +1,6 @@ # frozen_string_literal: true require 'awspec' -require 'rhcl' - -module_vars = Rhcl.parse(File.open('examples/alb_test_fixture/variables.tf')) -log_location_prefix = module_vars['variable']['log_location_prefix']['default'] # rubocop:disable LineLength state_file = 'terraform.tfstate.d/kitchen-terraform-default-aws/terraform.tfstate' @@ -15,7 +11,6 @@ # rubocop:enable LineLength alb_arn = tf_state['modules'][0]['outputs']['alb_id']['value'] alb_name = alb_arn.split('/')[-2] -account_id = tf_state['modules'][0]['outputs']['account_id']['value'] region = tf_state['modules'][0]['outputs']['region']['value'] ENV['AWS_REGION'] = region vpc_id = tf_state['modules'][0]['outputs']['vpc_id']['value'] diff --git a/variables.tf b/variables.tf index 828c989..a901c43 100644 --- a/variables.tf +++ b/variables.tf @@ -8,8 +8,19 @@ variable "enable_http2" { default = true } +variable "extra_ssl_certs" { + description = "A list of maps describing any extra SSL certificates to apply to the HTTPS listeners. Required key/values: certificate_arn, https_listener_index (the index of the listener within https_listeners which the cert applies toward)." + type = "list" + default = [] +} + +variable "extra_ssl_certs_count" { + description = "A manually provided count/length of the extra_ssl_certs list of maps since the list cannot be computed." + default = 0 +} + variable "https_listeners" { - description = "A list of maps describing the HTTPS listeners for this ALB. Required keys: port, certificate_arn. Optional keys: ssl_policy (defaults to ELBSecurityPolicy-2016-08), target_group_index (defaults to 0)" + description = "A list of maps describing the HTTPS listeners for this ALB. Required key/values: port, certificate_arn. Optional key/values: ssl_policy (defaults to ELBSecurityPolicy-2016-08), target_group_index (defaults to 0)" type = "list" default = [] } @@ -20,7 +31,7 @@ variable "https_listeners_count" { } variable "http_tcp_listeners" { - description = "A list of maps describing the HTTPS listeners for this ALB. Required keys: port, protocol. Optional keys: target_group_index (defaults to 0)" + description = "A list of maps describing the HTTPS listeners for this ALB. Required key/values: port, protocol. Optional key/values: target_group_index (defaults to 0)" type = "list" default = [] } @@ -61,7 +72,7 @@ variable "load_balancer_delete_timeout" { } variable "load_balancer_name" { - description = "The name prefix and name tag of the load balancer." + description = "The resource name and Name tag of the load balancer." } variable "load_balancer_update_timeout" { @@ -69,11 +80,6 @@ variable "load_balancer_update_timeout" { default = "10m" } -variable "load_balancer_security_groups" { - description = "The security groups to attach to the load balancer. e.g. [\"sg-edcd9784\",\"sg-edcd9785\"]" - type = "list" -} - variable "log_bucket_name" { description = "S3 bucket (externally created) for storing load balancer access logs." } @@ -93,8 +99,13 @@ variable "tags" { default = {} } +variable "security_groups" { + description = "The security groups to attach to the load balancer. e.g. [\"sg-edcd9784\",\"sg-edcd9785\"]" + type = "list" +} + variable "target_groups" { - description = "A list of maps containing key/value pairs that define the target groups to be created. Order of these maps is important and the index of these are to be referenced in listener definitions. Required map values: name, backend_protocol, backend_port. Optional key/values found in the target_groups_defaults variable." + description = "A list of maps containing key/value pairs that define the target groups to be created. Order of these maps is important and the index of these are to be referenced in listener definitions. Required key/values: name, backend_protocol, backend_port. Optional key/values are in the target_groups_defaults variable." type = "list" default = [] } diff --git a/version b/version index ad55eb8..6c8dc7e 100644 --- a/version +++ b/version @@ -1 +1 @@ -v3.0.0 +v3.1.0