Skip to content

Commit

Permalink
allow optional extra ssl certs (#54)
Browse files Browse the repository at this point in the history
* added the option for extra SSL certs
* simplification of a variable name
* upgraded awspec, terraform, and kitchen terraform
  • Loading branch information
brandonjbjelland authored Mar 23, 2018
1 parent 9bcc0f2 commit af83c3a
Show file tree
Hide file tree
Showing 9 changed files with 130 additions and 66 deletions.
11 changes: 5 additions & 6 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@ dist: trusty
rvm:
- 2.4.2

services:
- docker

before_install:
- echo "before_install"

Expand All @@ -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
Expand Down
18 changes: 15 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 2 additions & 3 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -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
73 changes: 53 additions & 20 deletions examples/alb_test_fixture/locals.tf
Original file line number Diff line number Diff line change
@@ -1,50 +1,83 @@
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

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()}"
}
45 changes: 27 additions & 18 deletions examples/alb_test_fixture/main.tf
Original file line number Diff line number Diff line change
@@ -1,24 +1,31 @@
terraform {
required_version = ">= 0.11.3"
required_version = "= 0.11.5"
}

provider "aws" {
version = ">= 1.10.0"
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" {
Expand Down Expand Up @@ -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}"
}
8 changes: 7 additions & 1 deletion main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -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}"
Expand Down Expand Up @@ -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}"
}
5 changes: 0 additions & 5 deletions test/integration/default/test_alb.rb
Original file line number Diff line number Diff line change
@@ -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'
Expand All @@ -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']
Expand Down
29 changes: 20 additions & 9 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -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 = []
}
Expand All @@ -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 = []
}
Expand Down Expand Up @@ -61,19 +72,14 @@ 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" {
description = "Timeout value when updating the ALB."
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."
}
Expand All @@ -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 = []
}
Expand Down
2 changes: 1 addition & 1 deletion version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v3.0.0
v3.1.0

0 comments on commit af83c3a

Please sign in to comment.