From f0cea5f0a2bd7370ee408622319fefb43030a779 Mon Sep 17 00:00:00 2001 From: Justice London Date: Wed, 27 Oct 2021 14:51:43 -0700 Subject: [PATCH 01/37] Added configuration for passing initial security baseline scanning. Allows module to pass Checkov scans. Will be adding additional Disney requirements next. --- .pre-commit-config.yaml | 23 ++++++++++ examples/existing-image/README.md | 2 +- main.tf | 8 +++- modules/application_load_balancer/main.tf | 29 ++++++++---- .../application_load_balancer/variables.tf | 13 ++++++ modules/database/main.tf | 46 +++++++++++-------- modules/database/variables.tf | 17 +++++++ modules/network_load_balancer/main.tf | 19 ++++++-- modules/network_load_balancer/variables.tf | 12 +++++ modules/object_storage/main.tf | 9 ++++ modules/object_storage/variables.tf | 12 +++++ modules/redis/main.tf | 7 +++ modules/redis/variables.tf | 6 +-- modules/service_accounts/outputs.tf | 2 +- modules/vm/main.tf | 9 +++- modules/vm/variables.tf | 2 +- tests/private-active-active/proxy.tf | 14 +++++- tests/private-tcp-active-active/proxy.tf | 14 +++++- variables.tf | 30 +++++++++++- 19 files changed, 229 insertions(+), 45 deletions(-) create mode 100644 .pre-commit-config.yaml diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 00000000..2ccbf512 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,23 @@ +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.0.1 + hooks: + - id: check-executables-have-shebangs + - id: check-merge-conflict + - id: check-symlinks + - id: check-yaml + - id: check-json + - id: check-xml + - id: detect-aws-credentials + - id: detect-private-key + - id: trailing-whitespace + + - repo: git://github.com/antonbabenko/pre-commit-terraform + rev: v1.52.0 + hooks: + - id: terraform_docs + args: ['--args=--indent 3'] + - id: terraform_fmt + - id: terraform_tflint + - id: checkov + args: ['--quiet'] diff --git a/examples/existing-image/README.md b/examples/existing-image/README.md index d88f9ab6..fd9ee837 100644 --- a/examples/existing-image/README.md +++ b/examples/existing-image/README.md @@ -2,7 +2,7 @@ ## About This Example -This example functions as a reference for how to use this module to install +This example functions as a reference for how to use this module to install Terraform Enterprise with a custom image (AMI) in AWS. ## Module Prerequisites diff --git a/main.tf b/main.tf index c6d6ac9e..2d963fe0 100644 --- a/main.tf +++ b/main.tf @@ -19,7 +19,7 @@ data "aws_ami" "ubuntu" { resource "aws_kms_key" "tfe_key" { deletion_window_in_days = var.kms_key_deletion_window description = "AWS KMS Customer-managed key to encrypt TFE and other resources" - enable_key_rotation = false + enable_key_rotation = true is_enabled = true key_usage = "ENCRYPT_DECRYPT" @@ -106,10 +106,12 @@ module "database" { db_backup_window = var.db_backup_window engine_version = var.postgres_engine_version friendly_name_prefix = var.friendly_name_prefix + monitoring_interval = var.db_monitoring_interval network_id = local.network_id network_private_subnet_cidrs = var.network_private_subnet_cidrs network_subnets_private = local.network_private_subnets tfe_instance_sg = module.vm.tfe_instance_sg + enabled_cloudwatch_logs = var.db_enabled_cloudwatch_logs } module "user_data" { @@ -152,6 +154,8 @@ module "load_balancer" { network_public_subnets = local.network_public_subnets network_private_subnets = local.network_private_subnets ssl_policy = var.ssl_policy + logging_bucket = var.logging_bucket + logging_prefix = var.logging_prefix } module "private_tcp_load_balancer" { @@ -166,6 +170,8 @@ module "private_tcp_load_balancer" { network_id = local.network_id network_private_subnets = local.network_private_subnets ssl_policy = var.ssl_policy + logging_bucket = var.logging_bucket + logging_prefix = var.logging_prefix } module "vm" { diff --git a/modules/application_load_balancer/main.tf b/modules/application_load_balancer/main.tf index 9a7c5301..8627fbb4 100644 --- a/modules/application_load_balancer/main.tf +++ b/modules/application_load_balancer/main.tf @@ -1,6 +1,7 @@ resource "aws_security_group" "tfe_lb_allow" { - name = "${var.friendly_name_prefix}-tfe-lb-allow" - vpc_id = var.network_id + name = "${var.friendly_name_prefix}-tfe-lb-allow" + description = "Load-balancer security group for TFE" + vpc_id = var.network_id } resource "aws_security_group_rule" "tfe_lb_allow_inbound_http" { @@ -35,8 +36,9 @@ resource "aws_security_group_rule" "tfe_lb_allow_inbound_dashboard" { } resource "aws_security_group" "tfe_outbound_allow" { - name = "${var.friendly_name_prefix}-tfe-outbound-allow" - vpc_id = var.network_id + name = "${var.friendly_name_prefix}-tfe-outbound-allow" + description = "Outbound security group for TFE environment" + vpc_id = var.network_id } resource "aws_security_group_rule" "tfe_outbound_allow_all" { @@ -51,10 +53,21 @@ resource "aws_security_group_rule" "tfe_outbound_allow_all" { } resource "aws_lb" "tfe_lb" { - name = "${var.friendly_name_prefix}-tfe-web-alb" - internal = (var.load_balancing_scheme == "PRIVATE") - load_balancer_type = "application" - subnets = var.load_balancing_scheme == "PRIVATE" ? var.network_private_subnets : var.network_public_subnets + #checkov:skip=CKV_AWS_150:We will expect that people might want to spin up/down infrastructure quickly. Skip checking for delete protection. + name = "${var.friendly_name_prefix}-tfe-web-alb" + internal = (var.load_balancing_scheme == "PRIVATE") + load_balancer_type = "application" + subnets = var.load_balancing_scheme == "PRIVATE" ? var.network_private_subnets : var.network_public_subnets + drop_invalid_header_fields = true + + dynamic "access_logs" { + for_each = var.logging_bucket != null ? [var.logging_bucket] : [] + content { + bucket = var.logging_bucket + prefix = var.logging_prefix + enabled = true + } + } security_groups = [ aws_security_group.tfe_lb_allow.id, diff --git a/modules/application_load_balancer/variables.tf b/modules/application_load_balancer/variables.tf index 5e0ddd89..0afac955 100644 --- a/modules/application_load_balancer/variables.tf +++ b/modules/application_load_balancer/variables.tf @@ -30,6 +30,7 @@ variable "load_balancing_scheme" { } variable "ssl_policy" { + default = "ELBSecurityPolicy-TLS-1-2-2017-01" description = "The name of the SSL policy to assign to the load balancer listeners." type = string } @@ -57,3 +58,15 @@ variable "friendly_name_prefix" { type = string description = "(Required) Friendly name prefix used for tagging and naming AWS resources." } + +variable "logging_bucket" { + type = string + description = "S3 bucket name for logging of resources to. Requires a bucket in the same region that TFE is in." + default = null +} + +variable "logging_prefix" { + type = string + description = "Optional prefix to prepend to TFE resource logs in S3 bucket" + default = null +} diff --git a/modules/database/main.tf b/modules/database/main.tf index 9ce695de..b6e87a4b 100644 --- a/modules/database/main.tf +++ b/modules/database/main.tf @@ -11,6 +11,7 @@ resource "aws_security_group" "postgresql" { resource "aws_security_group_rule" "postgresql_tfe_ingress" { security_group_id = aws_security_group.postgresql.id + description = "Inbound traffic to postgresql port from TFE" type = "ingress" from_port = 5432 to_port = 5432 @@ -20,6 +21,7 @@ resource "aws_security_group_rule" "postgresql_tfe_ingress" { resource "aws_security_group_rule" "postgresql_tfe_egress" { security_group_id = aws_security_group.postgresql.id + description = "Outbound ICMP traffic from RDS" type = "egress" from_port = 0 to_port = 0 @@ -29,6 +31,7 @@ resource "aws_security_group_rule" "postgresql_tfe_egress" { resource "aws_security_group_rule" "postgresql_ingress" { security_group_id = aws_security_group.postgresql.id + description = "Inbound traffic to postgresql port from VPC" type = "ingress" from_port = 5432 to_port = 5432 @@ -38,6 +41,7 @@ resource "aws_security_group_rule" "postgresql_ingress" { resource "aws_security_group_rule" "postgresql_egress" { security_group_id = aws_security_group.postgresql.id + description = "Outbound traffic from postgresql port to VPC" type = "egress" from_port = 5432 to_port = 5432 @@ -51,6 +55,7 @@ resource "aws_db_subnet_group" "tfe" { } resource "aws_db_instance" "postgresql" { + #checkov:skip=CKV_AWS_129:We allow enabling this, but it's not on by default so skip the check. allocated_storage = 20 engine = "postgres" instance_class = var.db_size @@ -58,24 +63,27 @@ resource "aws_db_instance" "postgresql" { # no special characters allowed username = "espdtfe" - allow_major_version_upgrade = false - apply_immediately = true - auto_minor_version_upgrade = true - backup_retention_period = var.db_backup_retention - backup_window = var.db_backup_window - db_subnet_group_name = aws_db_subnet_group.tfe.name - delete_automated_backups = true - deletion_protection = false - engine_version = var.engine_version - identifier_prefix = "${var.friendly_name_prefix}-tfe" - max_allocated_storage = 0 - multi_az = true + iam_database_authentication_enabled = true + allow_major_version_upgrade = false + apply_immediately = true + auto_minor_version_upgrade = true + backup_retention_period = var.db_backup_retention + backup_window = var.db_backup_window + db_subnet_group_name = aws_db_subnet_group.tfe.name + delete_automated_backups = true + deletion_protection = false + engine_version = var.engine_version + identifier_prefix = "${var.friendly_name_prefix}-tfe" + max_allocated_storage = 0 + multi_az = true + monitoring_interval = var.monitoring_interval # no special characters allowed - name = "espdtfe" - port = 5432 - publicly_accessible = false - skip_final_snapshot = true - storage_encrypted = true - storage_type = "gp2" - vpc_security_group_ids = [aws_security_group.postgresql.id] + name = "espdtfe" + port = 5432 + publicly_accessible = false + skip_final_snapshot = true + storage_encrypted = true + storage_type = "gp2" + vpc_security_group_ids = [aws_security_group.postgresql.id] + enabled_cloudwatch_logs_exports = var.enabled_cloudwatch_logs } diff --git a/modules/database/variables.tf b/modules/database/variables.tf index ba3e9ba0..039413ab 100644 --- a/modules/database/variables.tf +++ b/modules/database/variables.tf @@ -28,6 +28,12 @@ variable "engine_version" { description = "PostgreSQL version." } +variable "monitoring_interval" { + type = number + description = "Interval in seconds for monitoring of the RDS database. Any value other than null will enable enhanced monitoring." + default = null +} + variable "network_subnets_private" { description = <<-EOD A list of the identities of the private subnetworks in which the PostgreSQL RDS instance will be deployed. @@ -52,3 +58,14 @@ variable "network_private_subnet_cidrs" { description = "(Optional) List of private subnet CIDR ranges to create in VPC." default = ["10.0.32.0/20", "10.0.48.0/20"] } + + +variable "enabled_cloudwatch_logs" { + type = list(string) + description = "List of enabled cloudwatch log export types. From list here: https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_instance#enabled_cloudwatch_logs_exports" + default = null + validation { + condition = contains(["postgresql", "upgrade"], var.enabled_cloudwatch_logs) + error_message = "Allowed cloudwatch log export types don't match allowed. Must be postgresql, upgrade." + } +} diff --git a/modules/network_load_balancer/main.tf b/modules/network_load_balancer/main.tf index 5cd31dca..43d64b97 100644 --- a/modules/network_load_balancer/main.tf +++ b/modules/network_load_balancer/main.tf @@ -1,8 +1,19 @@ resource "aws_lb" "tfe_lb" { - name = "${var.friendly_name_prefix}-tfe-nlb" - internal = true - load_balancer_type = "network" - subnets = var.network_private_subnets + #checkov:skip=CKV_AWS_150:Given we are automating this for the most part we can recover from a deleted load-balancer. Okay for now. + name = "${var.friendly_name_prefix}-tfe-nlb" + internal = true + load_balancer_type = "network" + enable_cross_zone_load_balancing = true + subnets = var.network_private_subnets + + dynamic "access_logs" { + for_each = var.logging_bucket != null ? [var.logging_bucket] : [] + content { + bucket = var.logging_bucket + prefix = var.logging_prefix + enabled = true + } + } } resource "aws_lb_listener" "tfe_listener_443" { diff --git a/modules/network_load_balancer/variables.tf b/modules/network_load_balancer/variables.tf index 62f1d815..0162a074 100644 --- a/modules/network_load_balancer/variables.tf +++ b/modules/network_load_balancer/variables.tf @@ -37,3 +37,15 @@ variable "friendly_name_prefix" { type = string description = "(Required) Friendly name prefix used for tagging and naming AWS resources." } + +variable "logging_bucket" { + type = string + description = "S3 bucket name for logging of resources to. Requires a bucket in the same region that TFE is in." + default = null +} + +variable "logging_prefix" { + type = string + description = "Optional prefix to prepend to TFE resource logs in S3 bucket" + default = null +} diff --git a/modules/object_storage/main.tf b/modules/object_storage/main.tf index 9d908237..acabe639 100644 --- a/modules/object_storage/main.tf +++ b/modules/object_storage/main.tf @@ -1,4 +1,5 @@ resource "aws_s3_bucket" "tfe_data_bucket" { + #checkov:skip=CKV_AWS_144:While cross-region might make sense someday, right now it doesn't for TFE bucket = "${var.friendly_name_prefix}-tfe-data" acl = "private" @@ -15,6 +16,14 @@ resource "aws_s3_bucket" "tfe_data_bucket" { } } + dynamic "logging" { + for_each = var.logging_bucket == null ? [] : [var.logging_bucket] + content { + target_bucket = logging.value + target_prefix = var.logging_prefix + } + } + force_destroy = true } diff --git a/modules/object_storage/variables.tf b/modules/object_storage/variables.tf index 31f39bf0..05b9208d 100644 --- a/modules/object_storage/variables.tf +++ b/modules/object_storage/variables.tf @@ -7,3 +7,15 @@ variable "friendly_name_prefix" { type = string description = "(Required) Friendly name prefix used for tagging and naming AWS resources." } + +variable "logging_bucket" { + type = string + description = "S3 bucket name for logging of resources to. Requires a bucket in the same region that TFE is in." + default = null +} + +variable "logging_prefix" { + type = string + description = "Optional prefix to prepend to TFE resource logs in S3 bucket" + default = null +} diff --git a/modules/redis/main.tf b/modules/redis/main.tf index a0ecf2fe..1de68550 100644 --- a/modules/redis/main.tf +++ b/modules/redis/main.tf @@ -13,6 +13,7 @@ resource "aws_security_group" "redis" { resource "aws_security_group_rule" "redis_tfe_ingress" { count = var.active_active ? 1 : 0 security_group_id = aws_security_group.redis[0].id + description = "Allow inbound connection to the cluster from EC2/TFE" type = "ingress" from_port = var.redis_port to_port = var.redis_port @@ -23,6 +24,7 @@ resource "aws_security_group_rule" "redis_tfe_ingress" { resource "aws_security_group_rule" "redis_tfe_egress" { count = var.active_active ? 1 : 0 security_group_id = aws_security_group.redis[0].id + description = "Allow outbound ICMP for the redis cluster" type = "egress" from_port = 0 to_port = 0 @@ -33,6 +35,7 @@ resource "aws_security_group_rule" "redis_tfe_egress" { resource "aws_security_group_rule" "redis_ingress" { count = var.active_active ? 1 : 0 security_group_id = aws_security_group.redis[0].id + description = "Allow connections in to the redis port from VPC" type = "ingress" from_port = var.redis_port to_port = var.redis_port @@ -43,6 +46,7 @@ resource "aws_security_group_rule" "redis_ingress" { resource "aws_security_group_rule" "redis_egress" { count = var.active_active ? 1 : 0 security_group_id = aws_security_group.redis[0].id + description = "Egress rule for redis port communicating to the VPC" type = "egress" from_port = var.redis_port to_port = var.redis_port @@ -57,6 +61,9 @@ resource "aws_elasticache_subnet_group" "tfe" { } resource "aws_elasticache_replication_group" "redis" { + #checkov:skip=CKV_AWS_29:We allow this to be a feature flag. Don't error on it. + #checkov:skip=CKV_AWS_30:This is a feature that we're allowing the user(s) to disable or enable if they want. + #checkov:skip=CKV_AWS_31:Another feature flag that we allow the user to set. Don't error. count = var.active_active ? 1 : 0 node_type = var.cache_size number_cache_clusters = 1 diff --git a/modules/redis/variables.tf b/modules/redis/variables.tf index 2be3793b..00f2dcaf 100644 --- a/modules/redis/variables.tf +++ b/modules/redis/variables.tf @@ -5,7 +5,7 @@ variable "active_active" { variable "kms_key_arn" { description = <<-EOD - The Amazon Resource Name of the KMS key which will be used by the Redis Elasticache replication group to encrypt data + The Amazon Resource Name of the KMS key which will be used by the Redis Elasticache replication group to encrypt data at rest. EOD type = string @@ -13,7 +13,7 @@ variable "kms_key_arn" { variable "tfe_instance_sg" { description = <<-EOD - The identity of the security group attached to the TFE EC2 instance(s) which will be authorized to communicate with + The identity of the security group attached to the TFE EC2 instance(s) which will be authorized to communicate with the Redis Elasticache replication group. EOD type = string @@ -21,7 +21,7 @@ variable "tfe_instance_sg" { variable "network_id" { description = <<-EOD - The identity of the VPC in which the security group attached to the Redis Elasticache replication group will be + The identity of the VPC in which the security group attached to the Redis Elasticache replication group will be deployed. EOD type = string diff --git a/modules/service_accounts/outputs.tf b/modules/service_accounts/outputs.tf index 924cee4e..40e22442 100644 --- a/modules/service_accounts/outputs.tf +++ b/modules/service_accounts/outputs.tf @@ -2,7 +2,7 @@ output "aws_iam_instance_profile" { value = aws_iam_instance_profile.tfe.name description = <<-EOD - The name of the IAM instance profile to be attached to the TFE EC2 instance(s) which is authorized to access the S3 + The name of the IAM instance profile to be attached to the TFE EC2 instance(s) which is authorized to access the S3 storage buckets and EC2 autoscaling group. EOD } diff --git a/modules/vm/main.tf b/modules/vm/main.tf index 919c59c5..dc49858c 100644 --- a/modules/vm/main.tf +++ b/modules/vm/main.tf @@ -2,12 +2,14 @@ # TFE CLUSTER # ############### resource "aws_security_group" "tfe_instance" { - name = "${var.friendly_name_prefix}-tfe-ec2-sg" - vpc_id = var.network_id + name = "${var.friendly_name_prefix}-tfe-ec2-sg" + description = "Security group for access to the TFE EC2 instances" + vpc_id = var.network_id } resource "aws_security_group_rule" "tfe_ui" { security_group_id = aws_security_group.tfe_instance.id + description = "Allow ingress traffic to TFE from the load-balancers" type = "ingress" from_port = 443 to_port = 443 @@ -18,6 +20,7 @@ resource "aws_security_group_rule" "tfe_ui" { resource "aws_security_group_rule" "tfe_inbound" { security_group_id = aws_security_group.tfe_instance.id + description = "Allow ICMP ingress traffic to TFE" type = "ingress" from_port = 0 to_port = 0 @@ -27,6 +30,7 @@ resource "aws_security_group_rule" "tfe_inbound" { resource "aws_security_group_rule" "tfe_outbound" { security_group_id = aws_security_group.tfe_instance.id + description = "Allow egress traffic to all IPV4 addresses" type = "egress" from_port = 0 to_port = 0 @@ -37,6 +41,7 @@ resource "aws_security_group_rule" "tfe_outbound" { resource "aws_security_group_rule" "tfe_dashboard" { count = var.active_active ? 0 : 1 security_group_id = aws_security_group.tfe_instance.id + description = "Allow ingress traffic to dashboard service for TFE from the load-balancer(s)" type = "ingress" from_port = 8800 to_port = 8800 diff --git a/modules/vm/variables.tf b/modules/vm/variables.tf index a814c2dc..70557520 100644 --- a/modules/vm/variables.tf +++ b/modules/vm/variables.tf @@ -77,7 +77,7 @@ variable "node_count" { variable "asg_tags" { type = map(string) description = < Date: Wed, 27 Oct 2021 15:00:22 -0700 Subject: [PATCH 02/37] Test if null --- modules/database/variables.tf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/database/variables.tf b/modules/database/variables.tf index 039413ab..316f494c 100644 --- a/modules/database/variables.tf +++ b/modules/database/variables.tf @@ -65,7 +65,7 @@ variable "enabled_cloudwatch_logs" { description = "List of enabled cloudwatch log export types. From list here: https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_instance#enabled_cloudwatch_logs_exports" default = null validation { - condition = contains(["postgresql", "upgrade"], var.enabled_cloudwatch_logs) - error_message = "Allowed cloudwatch log export types don't match allowed. Must be postgresql, upgrade." + condition = var.enabled_cloudwatch_logs != null ? contains(["postgresql", "upgrade"], var.enabled_cloudwatch_logs) : true + error_message = "Allowed cloudwatch log export types don't match allowed. Must be: postgresql, upgrade." } } From 1f838ab8b4fa75382710ce6bb44cef65e6193b01 Mon Sep 17 00:00:00 2001 From: Justice London Date: Wed, 27 Oct 2021 15:03:53 -0700 Subject: [PATCH 03/37] Forgot validation at core module --- variables.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/variables.tf b/variables.tf index 35fcebe3..ef2d9d50 100644 --- a/variables.tf +++ b/variables.tf @@ -80,7 +80,7 @@ variable "db_enabled_cloudwatch_logs" { description = "List of enabled cloudwatch log export types. From list here: https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_instance#enabled_cloudwatch_logs_exports" default = null validation { - condition = contains(["postgresql", "upgrade"], var.db_enabled_cloudwatch_logs) + condition = var.db_enabled_cloudwatch_logs != null ? contains(["postgresql", "upgrade"], var.db_enabled_cloudwatch_logs) : true error_message = "Allowed cloudwatch log export types don't match allowed. Must be postgresql, upgrade." } } From 3ed11e8c7e80c3983775c0a7e22c293bdd5c0957 Mon Sep 17 00:00:00 2001 From: Justice London Date: Wed, 27 Oct 2021 15:12:24 -0700 Subject: [PATCH 04/37] Don't change description for existing SGs to avoid force recreates. --- modules/application_load_balancer/main.tf | 4 ++-- modules/vm/main.tf | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/application_load_balancer/main.tf b/modules/application_load_balancer/main.tf index 8627fbb4..4100369a 100644 --- a/modules/application_load_balancer/main.tf +++ b/modules/application_load_balancer/main.tf @@ -1,6 +1,6 @@ resource "aws_security_group" "tfe_lb_allow" { name = "${var.friendly_name_prefix}-tfe-lb-allow" - description = "Load-balancer security group for TFE" + description = "Managed by Terraform" vpc_id = var.network_id } @@ -37,7 +37,7 @@ resource "aws_security_group_rule" "tfe_lb_allow_inbound_dashboard" { resource "aws_security_group" "tfe_outbound_allow" { name = "${var.friendly_name_prefix}-tfe-outbound-allow" - description = "Outbound security group for TFE environment" + description = "Managed by Terraform" vpc_id = var.network_id } diff --git a/modules/vm/main.tf b/modules/vm/main.tf index dc49858c..472c861d 100644 --- a/modules/vm/main.tf +++ b/modules/vm/main.tf @@ -3,7 +3,7 @@ ############### resource "aws_security_group" "tfe_instance" { name = "${var.friendly_name_prefix}-tfe-ec2-sg" - description = "Security group for access to the TFE EC2 instances" + description = "Managed by Terraform" vpc_id = var.network_id } From ab3d7f2c5029c8b14513b39266c5b140da8ebfb1 Mon Sep 17 00:00:00 2001 From: Justice London Date: Thu, 28 Oct 2021 09:18:25 -0700 Subject: [PATCH 05/37] Added the ability to have encrypted images supported by ASG --- main.tf | 5 +++-- modules/vm/main.tf | 16 ++++++++++++++++ modules/vm/variables.tf | 6 ++++++ variables.tf | 19 +++++++++++++++++++ 4 files changed, 44 insertions(+), 2 deletions(-) diff --git a/main.tf b/main.tf index 2d963fe0..c96ecebd 100644 --- a/main.tf +++ b/main.tf @@ -5,7 +5,7 @@ data "aws_ami" "ubuntu" { filter { name = "name" - values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"] + values = [var.ami_name_filter] } filter { @@ -13,7 +13,7 @@ data "aws_ami" "ubuntu" { values = ["hvm"] } - owners = ["099720109477"] # Canonical + owners = [var.ami_owner] } resource "aws_kms_key" "tfe_key" { @@ -180,6 +180,7 @@ module "vm" { active_active = local.active_active aws_iam_instance_profile = module.service_accounts.aws_iam_instance_profile ami_id = local.ami_id + ami_kms_key_arn = var.ami_kms_key_arn aws_lb = var.load_balancing_scheme == "PRIVATE_TCP" ? null : module.load_balancer[0].aws_lb_security_group aws_lb_target_group_tfe_tg_443_arn = var.load_balancing_scheme == "PRIVATE_TCP" ? module.private_tcp_load_balancer[0].aws_lb_target_group_tfe_tg_443_arn : module.load_balancer[0].aws_lb_target_group_tfe_tg_443_arn aws_lb_target_group_tfe_tg_8800_arn = var.load_balancing_scheme == "PRIVATE_TCP" ? module.private_tcp_load_balancer[0].aws_lb_target_group_tfe_tg_8800_arn : module.load_balancer[0].aws_lb_target_group_tfe_tg_8800_arn diff --git a/modules/vm/main.tf b/modules/vm/main.tf index 472c861d..d7b6c030 100644 --- a/modules/vm/main.tf +++ b/modules/vm/main.tf @@ -79,6 +79,21 @@ resource "aws_launch_configuration" "tfe" { } } +# Add ability for ASG to access KMS keys for encrypted images +resource "aws_iam_service_linked_role" "tfe_asg" { + aws_service_name = "autoscaling.amazonaws.com" + custom_suffix = "${var.friendly_name_prefix}-tfe-asg" +} + +resource "aws_kms_grant" "kms_grant_autoscaling" { + count = var.ami_kms_key_arn != null ? 1 : 0 + name = "kms_grant_autoscaling" + key_id = var.ami_kms_key_arn + grantee_principal = aws_iam_service_linked_role.tfe_asg.arn + operations = ["Decrypt", "ReEncryptFrom"] + retire_on_delete = true +} + resource "aws_autoscaling_group" "tfe_asg" { name = "${var.friendly_name_prefix}-tfe-asg" min_size = var.node_count @@ -94,6 +109,7 @@ resource "aws_autoscaling_group" "tfe_asg" { health_check_grace_period = var.default_ami_id ? 900 : 1500 health_check_type = "ELB" launch_configuration = aws_launch_configuration.tfe.name + service_linked_role_arn = aws_iam_service_linked_role.tfe_asg.arn tags = concat( [ diff --git a/modules/vm/variables.tf b/modules/vm/variables.tf index 70557520..373449b8 100644 --- a/modules/vm/variables.tf +++ b/modules/vm/variables.tf @@ -64,6 +64,12 @@ variable "ami_id" { description = "AMI ID to use for TFE instances" } +variable "ami_kms_key_arn" { + type = string + description = "Optional KMS key ARN to use with the TFE ASG for encrypted AMIs" + default = null +} + variable "friendly_name_prefix" { type = string description = "(Required) Friendly name prefix used for tagging and naming AWS resources." diff --git a/variables.tf b/variables.tf index ef2d9d50..488c6651 100644 --- a/variables.tf +++ b/variables.tf @@ -6,6 +6,25 @@ variable "ami_id" { description = "AMI ID to use for TFE instances" } +variable "ami_name_filter" { + type = string + default = "ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*" + description = "AMI data filter to use for finding latest AMI for TFE instances" +} + +variable "ami_owner" { + # Note: This must be a string to avoid parsing errors if account ends with a zero + type = string + default = "099720109477" + description = "Owner of the AMI to use for TFE if not specifying an AMI ID. Defaults to Canonical." +} + +variable "ami_kms_key_arn" { + type = string + description = "Optional KMS key ARN to use with the TFE ASG for encrypted AMIs" + default = null +} + variable "acm_certificate_arn" { type = string description = "ACM certificate ARN to use with load balancer" From 559721b46460b0885c196d3cb5773765800b5d45 Mon Sep 17 00:00:00 2001 From: Justice London Date: Thu, 28 Oct 2021 09:32:13 -0700 Subject: [PATCH 06/37] Enforce kms grant before creating ASG --- modules/vm/main.tf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/vm/main.tf b/modules/vm/main.tf index d7b6c030..d942f84e 100644 --- a/modules/vm/main.tf +++ b/modules/vm/main.tf @@ -128,6 +128,8 @@ resource "aws_autoscaling_group" "tfe_asg" { ] ) + depends_on = [aws_iam_service_linked_role.tfe_asg, aws_kms_grant.kms_grant_autoscaling] + lifecycle { create_before_destroy = true } From 604aa98b8c2912f619b2bbf0493335f758e5f598 Mon Sep 17 00:00:00 2001 From: Justice London Date: Thu, 28 Oct 2021 09:39:10 -0700 Subject: [PATCH 07/37] Add aws provider to tflint and update aws provider version --- .tflint.hcl | 7 +++++++ versions.tf | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.tflint.hcl b/.tflint.hcl index 4c2685dc..07fcaad7 100644 --- a/.tflint.hcl +++ b/.tflint.hcl @@ -4,6 +4,13 @@ config { disabled_by_default = false } +plugin "aws" { + enabled = true + deep_check = false + source = "github.com/terraform-linters/tflint-ruleset-aws" + version = "0.8.0" +} + rule "terraform_deprecated_index" { enabled = true } diff --git a/versions.tf b/versions.tf index 241fbd9e..3933c4f1 100644 --- a/versions.tf +++ b/versions.tf @@ -3,7 +3,7 @@ terraform { required_providers { aws = { source = "hashicorp/aws" - version = "~> 3.38" + version = "~> 3.63.0" } } } From a697f40fecb9317cc3c90e1c4742d5a0a1ac348a Mon Sep 17 00:00:00 2001 From: Justice London Date: Thu, 28 Oct 2021 10:04:41 -0700 Subject: [PATCH 08/37] Need 'can' for the variable check for cloudwatch --- modules/database/variables.tf | 2 +- variables.tf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/database/variables.tf b/modules/database/variables.tf index 316f494c..5727289b 100644 --- a/modules/database/variables.tf +++ b/modules/database/variables.tf @@ -65,7 +65,7 @@ variable "enabled_cloudwatch_logs" { description = "List of enabled cloudwatch log export types. From list here: https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_instance#enabled_cloudwatch_logs_exports" default = null validation { - condition = var.enabled_cloudwatch_logs != null ? contains(["postgresql", "upgrade"], var.enabled_cloudwatch_logs) : true + condition = var.enabled_cloudwatch_logs != null ? can(contains(["postgresql", "upgrade"], var.enabled_cloudwatch_logs)) : true error_message = "Allowed cloudwatch log export types don't match allowed. Must be: postgresql, upgrade." } } diff --git a/variables.tf b/variables.tf index 488c6651..92eca16c 100644 --- a/variables.tf +++ b/variables.tf @@ -99,7 +99,7 @@ variable "db_enabled_cloudwatch_logs" { description = "List of enabled cloudwatch log export types. From list here: https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_instance#enabled_cloudwatch_logs_exports" default = null validation { - condition = var.db_enabled_cloudwatch_logs != null ? contains(["postgresql", "upgrade"], var.db_enabled_cloudwatch_logs) : true + condition = var.db_enabled_cloudwatch_logs != null ? can(contains(["postgresql", "upgrade"], var.db_enabled_cloudwatch_logs)) : true error_message = "Allowed cloudwatch log export types don't match allowed. Must be postgresql, upgrade." } } From 77be70ae5db1c40f76ebe5745f66a4dc1a53c875 Mon Sep 17 00:00:00 2001 From: Justice London Date: Thu, 28 Oct 2021 13:52:27 -0700 Subject: [PATCH 09/37] Allow updating an existing aws-cli install --- modules/user_data/templates/tfe_ec2.sh.tpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/user_data/templates/tfe_ec2.sh.tpl b/modules/user_data/templates/tfe_ec2.sh.tpl index 5e79750a..c2cc6ff7 100644 --- a/modules/user_data/templates/tfe_ec2.sh.tpl +++ b/modules/user_data/templates/tfe_ec2.sh.tpl @@ -9,7 +9,7 @@ install_jq() { install_awscli() { curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" unzip awscliv2.zip - ./aws/install + ./aws/install --update rm -f ./awscliv2.zip rm -rf ./aws } From 613eb7e056c2d7e6cd9c4066d853bde38cf47e9f Mon Sep 17 00:00:00 2001 From: Justice London Date: Thu, 28 Oct 2021 14:16:56 -0700 Subject: [PATCH 10/37] Use bash to run the installer --- modules/user_data/templates/tfe_ec2.sh.tpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/user_data/templates/tfe_ec2.sh.tpl b/modules/user_data/templates/tfe_ec2.sh.tpl index c2cc6ff7..f75f3858 100644 --- a/modules/user_data/templates/tfe_ec2.sh.tpl +++ b/modules/user_data/templates/tfe_ec2.sh.tpl @@ -142,7 +142,7 @@ install_tfe() { curl -o /tmp/install.sh https://get.replicated.com/docker/terraformenterprise/active-active chmod +x /tmp/install.sh - /tmp/install.sh "$${arguments[@]}" | tee -a /var/log/ptfe.log + bash /tmp/install.sh "$${arguments[@]}" | tee -a /var/log/ptfe.log } configure_tfe() { From df78eb9740b8534d7dc3fcd0d8c7efa9d950c69c Mon Sep 17 00:00:00 2001 From: Justice London Date: Thu, 28 Oct 2021 15:25:32 -0700 Subject: [PATCH 11/37] Add ami copy functionality --- main.tf | 15 ++++++++++++++- variables.tf | 6 ++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/main.tf b/main.tf index c96ecebd..75fbbd34 100644 --- a/main.tf +++ b/main.tf @@ -1,5 +1,6 @@ data "aws_region" "current" {} +# Seach for ubuntu AMI based on supplied AMI parameters data "aws_ami" "ubuntu" { most_recent = true @@ -16,6 +17,17 @@ data "aws_ami" "ubuntu" { owners = [var.ami_owner] } +# If the user has selected to do a copy-down of the AMI to their local account, do so and use it as the default. +# This prevents AMI lifecycle events (disappearing AMIs for instance) from affecting ASG +resource "aws_ami_copy" "tfe_copy" { + count = var.ami_copy ? 1 : 0 + name = "${var.friendly_name_prefix}-${data.aws_ami.ubuntu.name}-local-copy" + source_ami_id = data.aws_ami.ubuntu.id + source_ami_region = data.aws_region.current.name + encrypted = data.aws_ami.ubuntu.block_device_mappings[0].ebs.encrypted + tags = var.tags +} + resource "aws_kms_key" "tfe_key" { deletion_window_in_days = var.kms_key_deletion_window description = "AWS KMS Customer-managed key to encrypt TFE and other resources" @@ -37,7 +49,8 @@ resource "aws_kms_alias" "key_alias" { locals { active_active = var.node_count >= 2 - ami_id = local.default_ami_id ? data.aws_ami.ubuntu.id : var.ami_id + ami_id_fixup = coalesce(join("", aws_ami_copy.tfe_copy.*.id), data.aws_ami.ubuntu.id) + ami_id = local.default_ami_id ? local.ami_id_fixup : var.ami_id default_ami_id = var.ami_id == "" fqdn = "${var.tfe_subdomain}.${var.domain_name}" } diff --git a/variables.tf b/variables.tf index 92eca16c..817a4509 100644 --- a/variables.tf +++ b/variables.tf @@ -25,6 +25,12 @@ variable "ami_kms_key_arn" { default = null } +variable "ami_copy" { + type = bool + description = "Optional boolean to enable/disable copying of the found AMI to the local account/region. Useful for lifecycled AMIs." + default = false +} + variable "acm_certificate_arn" { type = string description = "ACM certificate ARN to use with load balancer" From fa9ffb29fc0151ab13696623d93ebb73f40be28d Mon Sep 17 00:00:00 2001 From: Justice London Date: Thu, 28 Oct 2021 15:43:35 -0700 Subject: [PATCH 12/37] Fix tags for ami copy --- main.tf | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/main.tf b/main.tf index 75fbbd34..bf738c7b 100644 --- a/main.tf +++ b/main.tf @@ -17,6 +17,13 @@ data "aws_ami" "ubuntu" { owners = [var.ami_owner] } +# Find encryption status of located image +locals { + block_device_mappings = { + for device in data.aws_ami.ubuntu.block_device_mappings : device.device_name => device + } +} + # If the user has selected to do a copy-down of the AMI to their local account, do so and use it as the default. # This prevents AMI lifecycle events (disappearing AMIs for instance) from affecting ASG resource "aws_ami_copy" "tfe_copy" { @@ -24,8 +31,10 @@ resource "aws_ami_copy" "tfe_copy" { name = "${var.friendly_name_prefix}-${data.aws_ami.ubuntu.name}-local-copy" source_ami_id = data.aws_ami.ubuntu.id source_ami_region = data.aws_region.current.name - encrypted = data.aws_ami.ubuntu.block_device_mappings[0].ebs.encrypted - tags = var.tags + encrypted = local.block_device_mappings["/dev/sda1"].encrypted + tags = { + Name = "${var.friendly_name_prefix}-${data.aws_ami.ubuntu.name}-local-copy" + } } resource "aws_kms_key" "tfe_key" { @@ -36,10 +45,10 @@ resource "aws_kms_key" "tfe_key" { key_usage = "ENCRYPT_DECRYPT" # Prefix removed until https://github.com/hashicorp/terraform-provider-aws/issues/19583 is resolved - tags = { + tags = merge({ # Name = "${var.friendly_name_prefix}-tfe-kms-key" Name = "tfe-kms-key" - } + }, var.default_tags) } resource "aws_kms_alias" "key_alias" { From 7323e43fd538b58be092786245af36913915357c Mon Sep 17 00:00:00 2001 From: Justice London Date: Thu, 28 Oct 2021 15:45:49 -0700 Subject: [PATCH 13/37] Remnant from testing. --- main.tf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.tf b/main.tf index bf738c7b..4b7904cb 100644 --- a/main.tf +++ b/main.tf @@ -45,10 +45,10 @@ resource "aws_kms_key" "tfe_key" { key_usage = "ENCRYPT_DECRYPT" # Prefix removed until https://github.com/hashicorp/terraform-provider-aws/issues/19583 is resolved - tags = merge({ + tags = { # Name = "${var.friendly_name_prefix}-tfe-kms-key" Name = "tfe-kms-key" - }, var.default_tags) + } } resource "aws_kms_alias" "key_alias" { From f1d0f22a6f36aa36a99a2201ebe79cbd6bfbd84c Mon Sep 17 00:00:00 2001 From: Justice London Date: Thu, 28 Oct 2021 15:52:25 -0700 Subject: [PATCH 14/37] Wrong key for the encrypted value set --- main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.tf b/main.tf index 4b7904cb..bf8176f1 100644 --- a/main.tf +++ b/main.tf @@ -31,7 +31,7 @@ resource "aws_ami_copy" "tfe_copy" { name = "${var.friendly_name_prefix}-${data.aws_ami.ubuntu.name}-local-copy" source_ami_id = data.aws_ami.ubuntu.id source_ami_region = data.aws_region.current.name - encrypted = local.block_device_mappings["/dev/sda1"].encrypted + encrypted = local.block_device_mappings["/dev/sda1"].ebs.encrypted tags = { Name = "${var.friendly_name_prefix}-${data.aws_ami.ubuntu.name}-local-copy" } From 71d8cfc92e10464e342815c8ca1dad4b0d5d93e9 Mon Sep 17 00:00:00 2001 From: Justice London Date: Mon, 1 Nov 2021 11:23:20 -0700 Subject: [PATCH 15/37] Made requested changes from main module developers. --- .pre-commit-config.yaml | 23 ----------------------- modules/vm/main.tf | 2 +- tests/private-active-active/proxy.tf | 3 --- tests/private-tcp-active-active/proxy.tf | 3 --- versions.tf | 2 +- 5 files changed, 2 insertions(+), 31 deletions(-) delete mode 100644 .pre-commit-config.yaml diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml deleted file mode 100644 index 2ccbf512..00000000 --- a/.pre-commit-config.yaml +++ /dev/null @@ -1,23 +0,0 @@ -repos: - - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.0.1 - hooks: - - id: check-executables-have-shebangs - - id: check-merge-conflict - - id: check-symlinks - - id: check-yaml - - id: check-json - - id: check-xml - - id: detect-aws-credentials - - id: detect-private-key - - id: trailing-whitespace - - - repo: git://github.com/antonbabenko/pre-commit-terraform - rev: v1.52.0 - hooks: - - id: terraform_docs - args: ['--args=--indent 3'] - - id: terraform_fmt - - id: terraform_tflint - - id: checkov - args: ['--quiet'] diff --git a/modules/vm/main.tf b/modules/vm/main.tf index d942f84e..06176296 100644 --- a/modules/vm/main.tf +++ b/modules/vm/main.tf @@ -128,7 +128,7 @@ resource "aws_autoscaling_group" "tfe_asg" { ] ) - depends_on = [aws_iam_service_linked_role.tfe_asg, aws_kms_grant.kms_grant_autoscaling] + depends_on = [aws_kms_grant.kms_grant_autoscaling] lifecycle { create_before_destroy = true diff --git a/tests/private-active-active/proxy.tf b/tests/private-active-active/proxy.tf index 874e9185..e9245bf0 100644 --- a/tests/private-active-active/proxy.tf +++ b/tests/private-active-active/proxy.tf @@ -10,8 +10,6 @@ resource "aws_instance" "proxy" { aws_security_group.proxy.id, ] - monitoring = true - metadata_options { http_endpoint = "enabled" http_tokens = "required" @@ -31,7 +29,6 @@ resource "aws_instance" "proxy" { volume_size = 20 encrypted = true } - ebs_optimized = true } resource "aws_security_group" "proxy" { diff --git a/tests/private-tcp-active-active/proxy.tf b/tests/private-tcp-active-active/proxy.tf index ee18ddd4..f2c2fe80 100644 --- a/tests/private-tcp-active-active/proxy.tf +++ b/tests/private-tcp-active-active/proxy.tf @@ -57,7 +57,6 @@ resource "aws_iam_role_policy" "secretsmanager" { resource "aws_instance" "proxy" { ami = data.aws_ami.ubuntu.id instance_type = "m4.xlarge" - monitoring = true metadata_options { http_endpoint = "enabled" @@ -83,8 +82,6 @@ resource "aws_instance" "proxy" { ) ) - ebs_optimized = true - root_block_device { encrypted = true volume_type = "gp2" diff --git a/versions.tf b/versions.tf index 3933c4f1..5733292f 100644 --- a/versions.tf +++ b/versions.tf @@ -3,7 +3,7 @@ terraform { required_providers { aws = { source = "hashicorp/aws" - version = "~> 3.63.0" + version = "~> 3.63" } } } From 75ba37d3a56a00f3d9569ec3e6dfc49ec08a5365 Mon Sep 17 00:00:00 2001 From: Justice London Date: Mon, 1 Nov 2021 12:50:36 -0700 Subject: [PATCH 16/37] Removed ami search as requested and replaced with ami_id only which is a user required input. --- main.tf | 48 +++--------------------------- modules/vm/main.tf | 2 +- modules/vm/variables.tf | 11 +++---- modules/vm/versions.tf | 2 +- tests/public-active-active/data.tf | 16 ++++++++++ tests/public-active-active/main.tf | 1 + variables.tf | 26 ++++------------ 7 files changed, 35 insertions(+), 71 deletions(-) diff --git a/main.tf b/main.tf index bf8176f1..15f86e4f 100644 --- a/main.tf +++ b/main.tf @@ -1,42 +1,5 @@ data "aws_region" "current" {} -# Seach for ubuntu AMI based on supplied AMI parameters -data "aws_ami" "ubuntu" { - most_recent = true - - filter { - name = "name" - values = [var.ami_name_filter] - } - - filter { - name = "virtualization-type" - values = ["hvm"] - } - - owners = [var.ami_owner] -} - -# Find encryption status of located image -locals { - block_device_mappings = { - for device in data.aws_ami.ubuntu.block_device_mappings : device.device_name => device - } -} - -# If the user has selected to do a copy-down of the AMI to their local account, do so and use it as the default. -# This prevents AMI lifecycle events (disappearing AMIs for instance) from affecting ASG -resource "aws_ami_copy" "tfe_copy" { - count = var.ami_copy ? 1 : 0 - name = "${var.friendly_name_prefix}-${data.aws_ami.ubuntu.name}-local-copy" - source_ami_id = data.aws_ami.ubuntu.id - source_ami_region = data.aws_region.current.name - encrypted = local.block_device_mappings["/dev/sda1"].ebs.encrypted - tags = { - Name = "${var.friendly_name_prefix}-${data.aws_ami.ubuntu.name}-local-copy" - } -} - resource "aws_kms_key" "tfe_key" { deletion_window_in_days = var.kms_key_deletion_window description = "AWS KMS Customer-managed key to encrypt TFE and other resources" @@ -57,11 +20,8 @@ resource "aws_kms_alias" "key_alias" { } locals { - active_active = var.node_count >= 2 - ami_id_fixup = coalesce(join("", aws_ami_copy.tfe_copy.*.id), data.aws_ami.ubuntu.id) - ami_id = local.default_ami_id ? local.ami_id_fixup : var.ami_id - default_ami_id = var.ami_id == "" - fqdn = "${var.tfe_subdomain}.${var.domain_name}" + active_active = var.node_count >= 2 + fqdn = "${var.tfe_subdomain}.${var.domain_name}" } module "object_storage" { @@ -201,13 +161,12 @@ module "vm" { active_active = local.active_active aws_iam_instance_profile = module.service_accounts.aws_iam_instance_profile - ami_id = local.ami_id + ami_id = var.ami_id ami_kms_key_arn = var.ami_kms_key_arn aws_lb = var.load_balancing_scheme == "PRIVATE_TCP" ? null : module.load_balancer[0].aws_lb_security_group aws_lb_target_group_tfe_tg_443_arn = var.load_balancing_scheme == "PRIVATE_TCP" ? module.private_tcp_load_balancer[0].aws_lb_target_group_tfe_tg_443_arn : module.load_balancer[0].aws_lb_target_group_tfe_tg_443_arn aws_lb_target_group_tfe_tg_8800_arn = var.load_balancing_scheme == "PRIVATE_TCP" ? module.private_tcp_load_balancer[0].aws_lb_target_group_tfe_tg_8800_arn : module.load_balancer[0].aws_lb_target_group_tfe_tg_8800_arn asg_tags = var.asg_tags - default_ami_id = local.default_ami_id friendly_name_prefix = var.friendly_name_prefix key_name = var.key_name instance_type = var.instance_type @@ -216,4 +175,5 @@ module "vm" { network_private_subnet_cidrs = local.network_private_subnet_cidrs node_count = var.node_count user_data_base64 = module.user_data.tfe_user_data_base64 + health_check_grace_period = var.health_check_grace_period } diff --git a/modules/vm/main.tf b/modules/vm/main.tf index 06176296..e6f1d06c 100644 --- a/modules/vm/main.tf +++ b/modules/vm/main.tf @@ -106,7 +106,7 @@ resource "aws_autoscaling_group" "tfe_asg" { ] # Increases grace period for any AMI that is not the default Ubuntu # since RHEL has longer startup time - health_check_grace_period = var.default_ami_id ? 900 : 1500 + health_check_grace_period = var.health_check_grace_period health_check_type = "ELB" launch_configuration = aws_launch_configuration.tfe.name service_linked_role_arn = aws_iam_service_linked_role.tfe_asg.arn diff --git a/modules/vm/variables.tf b/modules/vm/variables.tf index 373449b8..89e1a575 100644 --- a/modules/vm/variables.tf +++ b/modules/vm/variables.tf @@ -1,8 +1,3 @@ -variable "default_ami_id" { - description = "The identity of the AMI which will be used to provision the TFE EC2 instance(s)." - type = string -} - variable "user_data_base64" { description = "A Base64 encoded user data script to be executed when launching the TFE EC2 instance(s)." type = string @@ -101,3 +96,9 @@ variable "key_name" { description = "The name of the key pair to be used for SSH access to the EC2 instance(s)." type = string } + +variable "health_check_grace_period" { + default = 900 + description = "Number of seconds grace period before health-checks are run while spinning up TFE instances" + type = number +} diff --git a/modules/vm/versions.tf b/modules/vm/versions.tf index 241fbd9e..5733292f 100644 --- a/modules/vm/versions.tf +++ b/modules/vm/versions.tf @@ -3,7 +3,7 @@ terraform { required_providers { aws = { source = "hashicorp/aws" - version = "~> 3.38" + version = "~> 3.63" } } } diff --git a/tests/public-active-active/data.tf b/tests/public-active-active/data.tf index 22d23d80..e63fdae5 100644 --- a/tests/public-active-active/data.tf +++ b/tests/public-active-active/data.tf @@ -1,3 +1,19 @@ data "aws_secretsmanager_secret" "tfe_license" { name = var.tfe_license_secret_name } + +data "aws_ami" "ubuntu" { + most_recent = true + + filter { + name = "name" + values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"] + } + + filter { + name = "virtualization-type" + values = ["hvm"] + } + + owners = ["099720109477"] # Canonical +} diff --git a/tests/public-active-active/main.tf b/tests/public-active-active/main.tf index 6fb126ad..0ad8ad6e 100644 --- a/tests/public-active-active/main.tf +++ b/tests/public-active-active/main.tf @@ -18,6 +18,7 @@ resource "random_string" "friendly_name" { module "public_active_active" { source = "../../" + ami_id = data.aws_ami.ubuntu acm_certificate_arn = var.acm_certificate_arn domain_name = var.domain_name friendly_name_prefix = local.friendly_name_prefix diff --git a/variables.tf b/variables.tf index 817a4509..08144af2 100644 --- a/variables.tf +++ b/variables.tf @@ -2,35 +2,15 @@ variable "ami_id" { type = string - default = "" description = "AMI ID to use for TFE instances" } -variable "ami_name_filter" { - type = string - default = "ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*" - description = "AMI data filter to use for finding latest AMI for TFE instances" -} - -variable "ami_owner" { - # Note: This must be a string to avoid parsing errors if account ends with a zero - type = string - default = "099720109477" - description = "Owner of the AMI to use for TFE if not specifying an AMI ID. Defaults to Canonical." -} - variable "ami_kms_key_arn" { type = string description = "Optional KMS key ARN to use with the TFE ASG for encrypted AMIs" default = null } -variable "ami_copy" { - type = bool - description = "Optional boolean to enable/disable copying of the found AMI to the local account/region. Useful for lifecycled AMIs." - default = false -} - variable "acm_certificate_arn" { type = string description = "ACM certificate ARN to use with load balancer" @@ -46,6 +26,12 @@ variable "asg_tags" { default = {} } +variable "health_check_grace_period" { + default = 900 + description = "Number of seconds grace period before health-checks are run while spinning up TFE instances" + type = number +} + variable "logging_bucket" { type = string description = "S3 bucket name for logging of resources to. Requires a bucket in the same region that TFE is in." From 7fbbfba14d17ace225da63f8e1ea370cee3106da Mon Sep 17 00:00:00 2001 From: Justice London Date: Mon, 1 Nov 2021 12:54:27 -0700 Subject: [PATCH 17/37] Reverted all non-security related changes in tests folder --- tests/private-active-active/proxy.tf | 5 ----- tests/private-tcp-active-active/proxy.tf | 1 - 2 files changed, 6 deletions(-) diff --git a/tests/private-active-active/proxy.tf b/tests/private-active-active/proxy.tf index e9245bf0..ccf005d0 100644 --- a/tests/private-active-active/proxy.tf +++ b/tests/private-active-active/proxy.tf @@ -34,7 +34,6 @@ resource "aws_instance" "proxy" { resource "aws_security_group" "proxy" { name = "${local.friendly_name_prefix}-sg-proxy-allow" vpc_id = module.private_active_active.network_id - description = "Security group for allowing proxy connections to the created proxy EC2 instance(s)" # Prefix removed until https://github.com/hashicorp/terraform-provider-aws/issues/19583 is resolved tags = { @@ -49,8 +48,6 @@ resource "aws_security_group_rule" "proxy_ingress" { to_port = local.http_proxy_port protocol = "tcp" cidr_blocks = module.private_active_active.network_private_subnet_cidrs - description = "Allow internal traffic to proxy instance" - security_group_id = aws_security_group.proxy.id } @@ -60,8 +57,6 @@ resource "aws_security_group_rule" "proxy_egress" { to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] - description = "Allow all egress traffic from proxy instance" - security_group_id = aws_security_group.proxy.id } diff --git a/tests/private-tcp-active-active/proxy.tf b/tests/private-tcp-active-active/proxy.tf index f2c2fe80..04616a88 100644 --- a/tests/private-tcp-active-active/proxy.tf +++ b/tests/private-tcp-active-active/proxy.tf @@ -1,7 +1,6 @@ resource "aws_security_group" "proxy" { name = "${local.friendly_name_prefix}-sg-proxy-allow" vpc_id = module.private_tcp_active_active.network_id - description = "Security group for TFE TCP proxy" # Prefix removed until https://github.com/hashicorp/terraform-provider-aws/issues/19583 is resolved tags = { From 2c8451497aa71785c1d80ddfe74955908a26006a Mon Sep 17 00:00:00 2001 From: Justice London Date: Mon, 1 Nov 2021 12:55:48 -0700 Subject: [PATCH 18/37] Forgot to run fmt --- modules/vm/variables.tf | 4 ++-- tests/private-active-active/proxy.tf | 24 ++++++++++++------------ tests/private-tcp-active-active/proxy.tf | 4 ++-- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/modules/vm/variables.tf b/modules/vm/variables.tf index 89e1a575..90cbb3f1 100644 --- a/modules/vm/variables.tf +++ b/modules/vm/variables.tf @@ -98,7 +98,7 @@ variable "key_name" { } variable "health_check_grace_period" { - default = 900 + default = 900 description = "Number of seconds grace period before health-checks are run while spinning up TFE instances" - type = number + type = number } diff --git a/tests/private-active-active/proxy.tf b/tests/private-active-active/proxy.tf index ccf005d0..81ac4dec 100644 --- a/tests/private-active-active/proxy.tf +++ b/tests/private-active-active/proxy.tf @@ -32,8 +32,8 @@ resource "aws_instance" "proxy" { } resource "aws_security_group" "proxy" { - name = "${local.friendly_name_prefix}-sg-proxy-allow" - vpc_id = module.private_active_active.network_id + name = "${local.friendly_name_prefix}-sg-proxy-allow" + vpc_id = module.private_active_active.network_id # Prefix removed until https://github.com/hashicorp/terraform-provider-aws/issues/19583 is resolved tags = { @@ -43,20 +43,20 @@ resource "aws_security_group" "proxy" { } resource "aws_security_group_rule" "proxy_ingress" { - type = "ingress" - from_port = local.http_proxy_port - to_port = local.http_proxy_port - protocol = "tcp" - cidr_blocks = module.private_active_active.network_private_subnet_cidrs + type = "ingress" + from_port = local.http_proxy_port + to_port = local.http_proxy_port + protocol = "tcp" + cidr_blocks = module.private_active_active.network_private_subnet_cidrs security_group_id = aws_security_group.proxy.id } resource "aws_security_group_rule" "proxy_egress" { - type = "egress" - from_port = 0 - to_port = 0 - protocol = "-1" - cidr_blocks = ["0.0.0.0/0"] + type = "egress" + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] security_group_id = aws_security_group.proxy.id } diff --git a/tests/private-tcp-active-active/proxy.tf b/tests/private-tcp-active-active/proxy.tf index 04616a88..8f44b93f 100644 --- a/tests/private-tcp-active-active/proxy.tf +++ b/tests/private-tcp-active-active/proxy.tf @@ -1,6 +1,6 @@ resource "aws_security_group" "proxy" { - name = "${local.friendly_name_prefix}-sg-proxy-allow" - vpc_id = module.private_tcp_active_active.network_id + name = "${local.friendly_name_prefix}-sg-proxy-allow" + vpc_id = module.private_tcp_active_active.network_id # Prefix removed until https://github.com/hashicorp/terraform-provider-aws/issues/19583 is resolved tags = { From 054efb09d1a400dc1ffa2cfc9d14698a786d9870 Mon Sep 17 00:00:00 2001 From: Justice London Date: Mon, 1 Nov 2021 12:58:14 -0700 Subject: [PATCH 19/37] Added back random descriptions... --- tests/private-active-active/proxy.tf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/private-active-active/proxy.tf b/tests/private-active-active/proxy.tf index 81ac4dec..0ac16229 100644 --- a/tests/private-active-active/proxy.tf +++ b/tests/private-active-active/proxy.tf @@ -48,6 +48,7 @@ resource "aws_security_group_rule" "proxy_ingress" { to_port = local.http_proxy_port protocol = "tcp" cidr_blocks = module.private_active_active.network_private_subnet_cidrs + description = "Allow internal traffic to proxy instance" security_group_id = aws_security_group.proxy.id } @@ -57,6 +58,7 @@ resource "aws_security_group_rule" "proxy_egress" { to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] + description = "Allow all egress traffic from proxy instance" security_group_id = aws_security_group.proxy.id } From ad30fd9db5f9f042616368be6914670221514a98 Mon Sep 17 00:00:00 2001 From: Justice London Date: Mon, 1 Nov 2021 13:00:00 -0700 Subject: [PATCH 20/37] And added random blank lines back. --- tests/private-active-active/proxy.tf | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/tests/private-active-active/proxy.tf b/tests/private-active-active/proxy.tf index 0ac16229..afeb542e 100644 --- a/tests/private-active-active/proxy.tf +++ b/tests/private-active-active/proxy.tf @@ -43,22 +43,24 @@ resource "aws_security_group" "proxy" { } resource "aws_security_group_rule" "proxy_ingress" { - type = "ingress" - from_port = local.http_proxy_port - to_port = local.http_proxy_port - protocol = "tcp" - cidr_blocks = module.private_active_active.network_private_subnet_cidrs - description = "Allow internal traffic to proxy instance" + type = "ingress" + from_port = local.http_proxy_port + to_port = local.http_proxy_port + protocol = "tcp" + cidr_blocks = module.private_active_active.network_private_subnet_cidrs + description = "Allow internal traffic to proxy instance" + security_group_id = aws_security_group.proxy.id } resource "aws_security_group_rule" "proxy_egress" { - type = "egress" - from_port = 0 - to_port = 0 - protocol = "-1" - cidr_blocks = ["0.0.0.0/0"] - description = "Allow all egress traffic from proxy instance" + type = "egress" + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + description = "Allow all egress traffic from proxy instance" + security_group_id = aws_security_group.proxy.id } From 494015b9e8ccab35fd8ff23fe5d24c6066a07346 Mon Sep 17 00:00:00 2001 From: Justice London Date: Mon, 1 Nov 2021 13:04:02 -0700 Subject: [PATCH 21/37] Updating versions for the remaining aws provider versions --- examples/existing-image/versions.tf | 4 ++-- modules/application_load_balancer/versions.tf | 2 +- modules/database/versions.tf | 2 +- modules/network_load_balancer/versions.tf | 2 +- modules/networking/versions.tf | 2 +- modules/object_storage/versions.tf | 2 +- modules/redis/versions.tf | 2 +- modules/service_accounts/versions.tf | 2 +- tests/private-active-active/versions.tf | 2 +- tests/private-tcp-active-active/versions.tf | 2 +- tests/public-active-active/versions.tf | 2 +- 11 files changed, 12 insertions(+), 12 deletions(-) diff --git a/examples/existing-image/versions.tf b/examples/existing-image/versions.tf index e7c8bf52..5733292f 100644 --- a/examples/existing-image/versions.tf +++ b/examples/existing-image/versions.tf @@ -3,7 +3,7 @@ terraform { required_providers { aws = { source = "hashicorp/aws" - version = "~> 3.38" + version = "~> 3.63" } } -} \ No newline at end of file +} diff --git a/modules/application_load_balancer/versions.tf b/modules/application_load_balancer/versions.tf index 241fbd9e..5733292f 100644 --- a/modules/application_load_balancer/versions.tf +++ b/modules/application_load_balancer/versions.tf @@ -3,7 +3,7 @@ terraform { required_providers { aws = { source = "hashicorp/aws" - version = "~> 3.38" + version = "~> 3.63" } } } diff --git a/modules/database/versions.tf b/modules/database/versions.tf index 4c3fe642..f42f09c9 100644 --- a/modules/database/versions.tf +++ b/modules/database/versions.tf @@ -3,7 +3,7 @@ terraform { required_providers { aws = { source = "hashicorp/aws" - version = "~> 3.38" + version = "~> 3.63" } random = { source = "hashicorp/random" diff --git a/modules/network_load_balancer/versions.tf b/modules/network_load_balancer/versions.tf index 241fbd9e..5733292f 100644 --- a/modules/network_load_balancer/versions.tf +++ b/modules/network_load_balancer/versions.tf @@ -3,7 +3,7 @@ terraform { required_providers { aws = { source = "hashicorp/aws" - version = "~> 3.38" + version = "~> 3.63" } } } diff --git a/modules/networking/versions.tf b/modules/networking/versions.tf index 241fbd9e..5733292f 100644 --- a/modules/networking/versions.tf +++ b/modules/networking/versions.tf @@ -3,7 +3,7 @@ terraform { required_providers { aws = { source = "hashicorp/aws" - version = "~> 3.38" + version = "~> 3.63" } } } diff --git a/modules/object_storage/versions.tf b/modules/object_storage/versions.tf index 241fbd9e..5733292f 100644 --- a/modules/object_storage/versions.tf +++ b/modules/object_storage/versions.tf @@ -3,7 +3,7 @@ terraform { required_providers { aws = { source = "hashicorp/aws" - version = "~> 3.38" + version = "~> 3.63" } } } diff --git a/modules/redis/versions.tf b/modules/redis/versions.tf index 4c3fe642..f42f09c9 100644 --- a/modules/redis/versions.tf +++ b/modules/redis/versions.tf @@ -3,7 +3,7 @@ terraform { required_providers { aws = { source = "hashicorp/aws" - version = "~> 3.38" + version = "~> 3.63" } random = { source = "hashicorp/random" diff --git a/modules/service_accounts/versions.tf b/modules/service_accounts/versions.tf index 241fbd9e..5733292f 100644 --- a/modules/service_accounts/versions.tf +++ b/modules/service_accounts/versions.tf @@ -3,7 +3,7 @@ terraform { required_providers { aws = { source = "hashicorp/aws" - version = "~> 3.38" + version = "~> 3.63" } } } diff --git a/tests/private-active-active/versions.tf b/tests/private-active-active/versions.tf index 14b990a0..2fe6f74a 100644 --- a/tests/private-active-active/versions.tf +++ b/tests/private-active-active/versions.tf @@ -11,7 +11,7 @@ terraform { required_providers { aws = { source = "hashicorp/aws" - version = "~> 3.38" + version = "~> 3.63" } random = { source = "hashicorp/random" diff --git a/tests/private-tcp-active-active/versions.tf b/tests/private-tcp-active-active/versions.tf index 51865c25..b165eec3 100644 --- a/tests/private-tcp-active-active/versions.tf +++ b/tests/private-tcp-active-active/versions.tf @@ -11,7 +11,7 @@ terraform { required_providers { aws = { source = "hashicorp/aws" - version = "~> 3.38" + version = "~> 3.63" } random = { source = "hashicorp/random" diff --git a/tests/public-active-active/versions.tf b/tests/public-active-active/versions.tf index f5947b72..20213ce8 100644 --- a/tests/public-active-active/versions.tf +++ b/tests/public-active-active/versions.tf @@ -11,7 +11,7 @@ terraform { required_providers { aws = { source = "hashicorp/aws" - version = "~> 3.38" + version = "~> 3.63" } random = { source = "hashicorp/random" From c28145dd9774c21eb363bd4dc35dbb949665ca06 Mon Sep 17 00:00:00 2001 From: Justice London Date: Mon, 1 Nov 2021 14:30:09 -0700 Subject: [PATCH 22/37] Added custom_fqdn flag --- main.tf | 2 +- variables.tf | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/main.tf b/main.tf index 15f86e4f..273b1469 100644 --- a/main.tf +++ b/main.tf @@ -21,7 +21,7 @@ resource "aws_kms_alias" "key_alias" { locals { active_active = var.node_count >= 2 - fqdn = "${var.tfe_subdomain}.${var.domain_name}" + fqdn = var.custom_fqdn != null ? var.custom_fqdn : "${var.tfe_subdomain}.${var.domain_name}" } module "object_storage" { diff --git a/variables.tf b/variables.tf index 08144af2..7ad30323 100644 --- a/variables.tf +++ b/variables.tf @@ -107,6 +107,12 @@ variable "domain_name" { description = "Domain for creating the Terraform Enterprise subdomain on." } +variable "custom_fqdn" { + type = string + description = "(Optional) A custom FQDN name to use for the TFE install. Useful for instance if TFE is at the root of the zone." + default = null +} + variable "friendly_name_prefix" { type = string description = "(Required) Friendly name prefix used for tagging and naming AWS resources." From 5f2bdb6ad1f467ea10b53ca976be3695f0f8b7e5 Mon Sep 17 00:00:00 2001 From: Justice London Date: Tue, 2 Nov 2021 11:24:41 -0700 Subject: [PATCH 23/37] Add ACM cert which is missing on NLB https port --- modules/network_load_balancer/main.tf | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/network_load_balancer/main.tf b/modules/network_load_balancer/main.tf index 43d64b97..dc390f9e 100644 --- a/modules/network_load_balancer/main.tf +++ b/modules/network_load_balancer/main.tf @@ -20,6 +20,8 @@ resource "aws_lb_listener" "tfe_listener_443" { load_balancer_arn = aws_lb.tfe_lb.arn port = 443 protocol = "TCP" + ssl_policy = var.ssl_policy + certificate_arn = var.certificate_arn default_action { type = "forward" @@ -46,7 +48,6 @@ resource "aws_lb_listener" "tfe_listener_8800" { ssl_policy = var.ssl_policy certificate_arn = var.certificate_arn - default_action { type = "forward" target_group_arn = aws_lb_target_group.tfe_tg_8800[0].arn From f58e23ee0b57a03b8104d06d344ccb79927d1451 Mon Sep 17 00:00:00 2001 From: Justice London Date: Tue, 2 Nov 2021 11:29:55 -0700 Subject: [PATCH 24/37] Change to TLS type rather than TCP --- modules/network_load_balancer/main.tf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/network_load_balancer/main.tf b/modules/network_load_balancer/main.tf index dc390f9e..31a1e116 100644 --- a/modules/network_load_balancer/main.tf +++ b/modules/network_load_balancer/main.tf @@ -19,7 +19,7 @@ resource "aws_lb" "tfe_lb" { resource "aws_lb_listener" "tfe_listener_443" { load_balancer_arn = aws_lb.tfe_lb.arn port = 443 - protocol = "TCP" + protocol = "TLS" ssl_policy = var.ssl_policy certificate_arn = var.certificate_arn @@ -44,7 +44,7 @@ resource "aws_lb_listener" "tfe_listener_8800" { count = var.active_active ? 0 : 1 load_balancer_arn = aws_lb.tfe_lb.arn port = 8800 - protocol = "TCP" + protocol = "TLS" ssl_policy = var.ssl_policy certificate_arn = var.certificate_arn From bf094cdd960801c0bc91c577920b8349aaf8f89f Mon Sep 17 00:00:00 2001 From: Justice London Date: Tue, 2 Nov 2021 11:44:42 -0700 Subject: [PATCH 25/37] Try using same health-check for NLB as for ALB --- modules/network_load_balancer/main.tf | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/network_load_balancer/main.tf b/modules/network_load_balancer/main.tf index 31a1e116..39145660 100644 --- a/modules/network_load_balancer/main.tf +++ b/modules/network_load_balancer/main.tf @@ -32,11 +32,13 @@ resource "aws_lb_listener" "tfe_listener_443" { resource "aws_lb_target_group" "tfe_tg_443" { name = "${var.friendly_name_prefix}-tfe-alb-tg-443" port = 443 - protocol = "TCP" + protocol = "TLS" vpc_id = var.network_id health_check { - protocol = "TCP" + protocol = "HTTPS" + path = "/_health_check" + matcher = "200-399" } } From 547b81b24c9c3cc6077c34aea7ebfe21783c5dfd Mon Sep 17 00:00:00 2001 From: Justice London Date: Tue, 2 Nov 2021 11:50:07 -0700 Subject: [PATCH 26/37] Properly name target-groups for NLB --- modules/network_load_balancer/main.tf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/network_load_balancer/main.tf b/modules/network_load_balancer/main.tf index 39145660..67c28bd7 100644 --- a/modules/network_load_balancer/main.tf +++ b/modules/network_load_balancer/main.tf @@ -30,7 +30,7 @@ resource "aws_lb_listener" "tfe_listener_443" { } resource "aws_lb_target_group" "tfe_tg_443" { - name = "${var.friendly_name_prefix}-tfe-alb-tg-443" + name = "${var.friendly_name_prefix}-tfe-nlb-tg-443" port = 443 protocol = "TLS" vpc_id = var.network_id @@ -58,7 +58,7 @@ resource "aws_lb_listener" "tfe_listener_8800" { resource "aws_lb_target_group" "tfe_tg_8800" { count = var.active_active ? 0 : 1 - name = "${var.friendly_name_prefix}-tfe-alb-tg-8800" + name = "${var.friendly_name_prefix}-tfe-nlb-tg-8800" port = 8800 protocol = "TCP" vpc_id = var.network_id From ac1a985445d9388a157e6179cf3abd442e74fc53 Mon Sep 17 00:00:00 2001 From: Justice London Date: Tue, 2 Nov 2021 15:55:15 -0700 Subject: [PATCH 27/37] Missing ID of the ami_id for test --- tests/public-active-active/main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/public-active-active/main.tf b/tests/public-active-active/main.tf index 0ad8ad6e..d2517f5d 100644 --- a/tests/public-active-active/main.tf +++ b/tests/public-active-active/main.tf @@ -18,7 +18,7 @@ resource "random_string" "friendly_name" { module "public_active_active" { source = "../../" - ami_id = data.aws_ami.ubuntu + ami_id = data.aws_ami.ubuntu.id acm_certificate_arn = var.acm_certificate_arn domain_name = var.domain_name friendly_name_prefix = local.friendly_name_prefix From 81f766e2d334c2c54b467e0b5b8d1f145836b696 Mon Sep 17 00:00:00 2001 From: Justice London Date: Thu, 24 Feb 2022 15:08:48 -0800 Subject: [PATCH 28/37] Default to hairpin advertisements --- modules/user_data/main.tf | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/user_data/main.tf b/modules/user_data/main.tf index 512cfb37..e2467028 100644 --- a/modules/user_data/main.tf +++ b/modules/user_data/main.tf @@ -45,6 +45,10 @@ locals { value = "production" } + hairpin_addressing = { + value = true + } + production_type = { value = "external" } From 12528c68bfb68e376e2f3052b5af77346d939ea7 Mon Sep 17 00:00:00 2001 From: Justice London Date: Thu, 24 Feb 2022 15:39:46 -0800 Subject: [PATCH 29/37] User hairpin value of '1' --- modules/user_data/main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/user_data/main.tf b/modules/user_data/main.tf index e2467028..189d6a3e 100644 --- a/modules/user_data/main.tf +++ b/modules/user_data/main.tf @@ -46,7 +46,7 @@ locals { } hairpin_addressing = { - value = true + value = "1" } production_type = { From b8165cc7065edf4c85f4b49284091add483affd3 Mon Sep 17 00:00:00 2001 From: Justice London Date: Fri, 25 Feb 2022 13:32:56 -0800 Subject: [PATCH 30/37] Add database tags --- main.tf | 1 + modules/database/main.tf | 1 + modules/database/variables.tf | 6 ++++++ variables.tf | 6 ++++++ 4 files changed, 14 insertions(+) diff --git a/main.tf b/main.tf index 273b1469..1781070c 100644 --- a/main.tf +++ b/main.tf @@ -94,6 +94,7 @@ module "database" { network_subnets_private = local.network_private_subnets tfe_instance_sg = module.vm.tfe_instance_sg enabled_cloudwatch_logs = var.db_enabled_cloudwatch_logs + tags = var.db_tags } module "user_data" { diff --git a/modules/database/main.tf b/modules/database/main.tf index b6e87a4b..edd58b34 100644 --- a/modules/database/main.tf +++ b/modules/database/main.tf @@ -86,4 +86,5 @@ resource "aws_db_instance" "postgresql" { storage_type = "gp2" vpc_security_group_ids = [aws_security_group.postgresql.id] enabled_cloudwatch_logs_exports = var.enabled_cloudwatch_logs + tags = var.tags } diff --git a/modules/database/variables.tf b/modules/database/variables.tf index 5727289b..3d22c766 100644 --- a/modules/database/variables.tf +++ b/modules/database/variables.tf @@ -69,3 +69,9 @@ variable "enabled_cloudwatch_logs" { error_message = "Allowed cloudwatch log export types don't match allowed. Must be: postgresql, upgrade." } } + +variable "tags" { + type = map(string) + description = "(Optional) Map of tags used only for the database instance" + default = {} +} diff --git a/variables.tf b/variables.tf index 7ad30323..a3adcdef 100644 --- a/variables.tf +++ b/variables.tf @@ -26,6 +26,12 @@ variable "asg_tags" { default = {} } +variable "db_tags" { + type = map(string) + description = "(Optional) Map of tags used only for the database instance" + default = {} +} + variable "health_check_grace_period" { default = 900 description = "Number of seconds grace period before health-checks are run while spinning up TFE instances" From ed2c00dce66b3b8072184af4e28d95a591942132 Mon Sep 17 00:00:00 2001 From: Justice London Date: Wed, 9 Mar 2022 15:15:14 -0800 Subject: [PATCH 31/37] Accidentally missed adding logging bucket to object_storage --- main.tf | 4 +++- variables.tf | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/main.tf b/main.tf index 1781070c..5f2c1fb9 100644 --- a/main.tf +++ b/main.tf @@ -29,6 +29,8 @@ module "object_storage" { friendly_name_prefix = var.friendly_name_prefix kms_key_arn = aws_kms_key.tfe_key.arn + logging_bucket = var.logging_bucket + logging_prefix = var.logging_prefix } module "service_accounts" { @@ -94,7 +96,7 @@ module "database" { network_subnets_private = local.network_private_subnets tfe_instance_sg = module.vm.tfe_instance_sg enabled_cloudwatch_logs = var.db_enabled_cloudwatch_logs - tags = var.db_tags + tags = var.db_tags } module "user_data" { diff --git a/variables.tf b/variables.tf index a3adcdef..d35e61d2 100644 --- a/variables.tf +++ b/variables.tf @@ -27,9 +27,9 @@ variable "asg_tags" { } variable "db_tags" { - type = map(string) + type = map(string) description = "(Optional) Map of tags used only for the database instance" - default = {} + default = {} } variable "health_check_grace_period" { From 776e3e9b4825913bcf7415671766808edec3e0bd Mon Sep 17 00:00:00 2001 From: Justice London Date: Thu, 10 Mar 2022 10:42:37 -0800 Subject: [PATCH 32/37] Add tags to SG --- modules/database/main.tf | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/database/main.tf b/modules/database/main.tf index edd58b34..953e4a80 100644 --- a/modules/database/main.tf +++ b/modules/database/main.tf @@ -7,6 +7,7 @@ resource "aws_security_group" "postgresql" { description = "The security group of the PostgreSQL deployment for TFE." name = "${var.friendly_name_prefix}-tfe-postgresql" vpc_id = var.network_id + tags = var.tags } resource "aws_security_group_rule" "postgresql_tfe_ingress" { From dff326967589f60938b1176733e790c6f69162be Mon Sep 17 00:00:00 2001 From: Justice London Date: Mon, 4 Apr 2022 14:14:15 -0700 Subject: [PATCH 33/37] Added redirect http port for TFE --- main.tf | 1 + modules/network_load_balancer/main.tf | 24 ++++++++++++++++++++++++ modules/network_load_balancer/outputs.tf | 7 +++++++ modules/vm/main.tf | 13 ++++++++++++- modules/vm/variables.tf | 9 +++++++++ 5 files changed, 53 insertions(+), 1 deletion(-) diff --git a/main.tf b/main.tf index 5f2c1fb9..905cc599 100644 --- a/main.tf +++ b/main.tf @@ -167,6 +167,7 @@ module "vm" { ami_id = var.ami_id ami_kms_key_arn = var.ami_kms_key_arn aws_lb = var.load_balancing_scheme == "PRIVATE_TCP" ? null : module.load_balancer[0].aws_lb_security_group + aws_lb_target_group_tfe_tg_80_arn = var.load_balancing_scheme == "PRIVATE_TCP" ? module.private_tcp_load_balancer[0].aws_lb_target_group_tfe_tg_80_arn : null aws_lb_target_group_tfe_tg_443_arn = var.load_balancing_scheme == "PRIVATE_TCP" ? module.private_tcp_load_balancer[0].aws_lb_target_group_tfe_tg_443_arn : module.load_balancer[0].aws_lb_target_group_tfe_tg_443_arn aws_lb_target_group_tfe_tg_8800_arn = var.load_balancing_scheme == "PRIVATE_TCP" ? module.private_tcp_load_balancer[0].aws_lb_target_group_tfe_tg_8800_arn : module.load_balancer[0].aws_lb_target_group_tfe_tg_8800_arn asg_tags = var.asg_tags diff --git a/modules/network_load_balancer/main.tf b/modules/network_load_balancer/main.tf index 67c28bd7..3196a5a8 100644 --- a/modules/network_load_balancer/main.tf +++ b/modules/network_load_balancer/main.tf @@ -16,6 +16,17 @@ resource "aws_lb" "tfe_lb" { } } +resource "aws_lb_listener" "tfe_listener_80" { + load_balancer_arn = aws_lb.tfe_lb.arn + port = 80 + protocol = "TCP" + + default_action { + type = "forward" + target_group_arn = aws_lb_target_group.tfe_tg_80.arn + } +} + resource "aws_lb_listener" "tfe_listener_443" { load_balancer_arn = aws_lb.tfe_lb.arn port = 443 @@ -29,6 +40,19 @@ resource "aws_lb_listener" "tfe_listener_443" { } } +resource "aws_lb_target_group" "tfe_tg_80" { + name = "${var.friendly_name_prefix}-tfe-nlb-tg-80" + port = 80 + protocol = "TCP" + vpc_id = var.network_id + + health_check { + protocol = "HTTP" + path = "/_health_check" + matcher = "200-399" + } +} + resource "aws_lb_target_group" "tfe_tg_443" { name = "${var.friendly_name_prefix}-tfe-nlb-tg-443" port = 443 diff --git a/modules/network_load_balancer/outputs.tf b/modules/network_load_balancer/outputs.tf index f3cd06e7..d3f8e3b9 100644 --- a/modules/network_load_balancer/outputs.tf +++ b/modules/network_load_balancer/outputs.tf @@ -1,3 +1,10 @@ + +output "aws_lb_target_group_tfe_tg_80_arn" { + value = aws_lb_target_group.tfe_tg_80.arn + + description = "The Amazon Resource Name of the load balancer target group for traffic on port 80." +} + output "aws_lb_target_group_tfe_tg_443_arn" { value = aws_lb_target_group.tfe_tg_443.arn diff --git a/modules/vm/main.tf b/modules/vm/main.tf index e6f1d06c..fe96e305 100644 --- a/modules/vm/main.tf +++ b/modules/vm/main.tf @@ -7,6 +7,17 @@ resource "aws_security_group" "tfe_instance" { vpc_id = var.network_id } +resource "aws_security_group_rule" "tfe_redirect_port" { + security_group_id = aws_security_group.tfe_instance.id + description = "Allow ingress HTTP traffic to TFE from the load-balancers for redirect to HTTPS" + type = "ingress" + from_port = 80 + to_port = 80 + protocol = "tcp" + source_security_group_id = var.aws_lb + cidr_blocks = var.aws_lb == null ? var.network_private_subnet_cidrs : null +} + resource "aws_security_group_rule" "tfe_ui" { security_group_id = aws_security_group.tfe_instance.id description = "Allow ingress traffic to TFE from the load-balancers" @@ -100,7 +111,7 @@ resource "aws_autoscaling_group" "tfe_asg" { max_size = var.node_count desired_capacity = var.node_count vpc_zone_identifier = var.network_subnets_private - target_group_arns = var.active_active ? [var.aws_lb_target_group_tfe_tg_443_arn] : [ + target_group_arns = var.active_active ? compact([var.aws_lb_target_group_tfe_tg_80_arn, var.aws_lb_target_group_tfe_tg_443_arn]) : [ var.aws_lb_target_group_tfe_tg_8800_arn, var.aws_lb_target_group_tfe_tg_443_arn, ] diff --git a/modules/vm/variables.tf b/modules/vm/variables.tf index 90cbb3f1..c3fbd68c 100644 --- a/modules/vm/variables.tf +++ b/modules/vm/variables.tf @@ -11,6 +11,15 @@ variable "aws_lb" { type = string } +variable "aws_lb_target_group_tfe_tg_80_arn" { + description = <<-EOD + The Amazon Resource Name of the load balancer target group for traffic on port + 80 which will be backed by the TFE EC2 autoscaling group. + EOD + default = null + type = string +} + variable "aws_lb_target_group_tfe_tg_443_arn" { description = <<-EOD The Amazon Resource Name of the load balancer target group for traffic on port From 35d0b720bf8a134b1c6db14104a65583099db850 Mon Sep 17 00:00:00 2001 From: Justice London Date: Tue, 14 Mar 2023 11:23:04 -0700 Subject: [PATCH 34/37] Try flipping off hairpinning --- modules/user_data/main.tf | 4 - modules/user_data/main.tf.bak | 226 ++++++++++++++++++++++++++++++++++ 2 files changed, 226 insertions(+), 4 deletions(-) create mode 100644 modules/user_data/main.tf.bak diff --git a/modules/user_data/main.tf b/modules/user_data/main.tf index 189d6a3e..512cfb37 100644 --- a/modules/user_data/main.tf +++ b/modules/user_data/main.tf @@ -45,10 +45,6 @@ locals { value = "production" } - hairpin_addressing = { - value = "1" - } - production_type = { value = "external" } diff --git a/modules/user_data/main.tf.bak b/modules/user_data/main.tf.bak new file mode 100644 index 00000000..189d6a3e --- /dev/null +++ b/modules/user_data/main.tf.bak @@ -0,0 +1,226 @@ +resource "random_string" "password" { + length = 16 + special = false +} + +resource "random_id" "archivist_token" { + byte_length = 16 +} + +resource "random_id" "cookie_hash" { + byte_length = 16 +} + +resource "random_id" "enc_password" { + byte_length = 16 +} + +resource "random_id" "install_id" { + byte_length = 16 +} + +resource "random_id" "internal_api_token" { + byte_length = 16 +} + +resource "random_id" "root_secret" { + byte_length = 16 +} + +resource "random_id" "registry_session_secret_key" { + byte_length = 16 +} + +resource "random_id" "registry_session_encryption_key" { + byte_length = 16 +} + +resource "random_id" "user_token" { + byte_length = 16 +} + +locals { + base_configs = { + installation_type = { + value = "production" + } + + hairpin_addressing = { + value = "1" + } + + production_type = { + value = "external" + } + + hostname = { + value = var.fqdn + } + user_token = { + value = random_id.user_token.hex + } + + archivist_token = { + value = random_id.archivist_token.hex + } + + cookie_hash = { + value = random_id.cookie_hash.hex + } + + root_secret = { + value = random_id.root_secret.hex + } + + registry_session_secret_key = { + value = random_id.registry_session_secret_key.hex + } + + registry_session_encryption_key = { + value = random_id.registry_session_encryption_key.hex + } + + internal_api_token = { + value = random_id.internal_api_token.hex + } + + install_id = { + value = random_id.install_id.hex + } + + iact_subnet_list = { + value = join(",", var.iact_subnet_list) + } + + iact_subnet_time_limit = { + value = var.iact_subnet_time_limit != null ? tostring(var.iact_subnet_time_limit) : "" + } + } + + base_external_configs = { + enable_active_active = { + value = var.active_active ? "1" : "0" + } + + pg_dbname = { + value = var.pg_dbname + } + + pg_netloc = { + value = var.pg_netloc + } + + pg_password = { + value = var.pg_password + } + + pg_user = { + value = var.pg_user + } + + enc_password = { + value = random_id.enc_password.hex + } + } + + external_aws_configs = { + placement = { + value = "placement_s3" + } + + aws_instance_profile = { + value = "1" + } + + s3_bucket = { + value = var.aws_bucket_data + } + + s3_region = { + value = var.aws_region + } + + s3_sse = { + value = "aws:kms" + } + + s3_sse_kms_key_id = { + value = var.kms_key_arn + } + } + + redis_configs = { + redis_host = { + value = var.redis_host + } + + redis_pass = { + value = var.redis_pass + } + + redis_port = { + value = var.redis_port + } + + redis_use_password_auth = { + value = var.redis_use_password_auth + } + + redis_use_tls = { + value = var.redis_use_tls + } + } +} + +locals { + import_settings_from = "/etc/ptfe-settings.json" + license_file_location = "/etc/ptfe-license.rli" + replicated_base_config = { + BypassPreflightChecks = true + DaemonAuthenticationPassword = random_string.password.result + DaemonAuthenticationType = "password" + ImportSettingsFrom = local.import_settings_from + LicenseFileLocation = local.license_file_location + TlsBootstrapType = "self-signed" + TlsBootstrapHostname = var.fqdn + } +} + +## Build tfe config json +locals { + # take all the partials and merge them into the base configs, if false, merging empty map is noop + is_redis_configs = var.active_active ? local.redis_configs : {} + tfe_configs = jsonencode(merge(local.base_configs, local.base_external_configs, local.external_aws_configs, local.is_redis_configs)) +} + +## build replicated config json +locals { + repl_configs = jsonencode(merge(local.replicated_base_config)) +} + +locals { + tfe_user_data = templatefile( + "${path.module}/templates/tfe_ec2.sh.tpl", + { + import_settings_from = local.import_settings_from + tfe_license_secret = var.tfe_license_secret + license_file_location = local.license_file_location + replicated = base64encode(local.repl_configs) + settings = base64encode(local.tfe_configs) + active_active = var.active_active + ca_certificate_secret = var.ca_certificate_secret + proxy_ip = var.proxy_ip + no_proxy = join( + ",", + concat( + [ + "127.0.0.1", + "169.254.169.254", + ".aws.ce.redhat.com", + ], + var.no_proxy + ) + ) + } + ) +} From 0a2444de21a2086748728fd9b26a46b2bc2ec1b4 Mon Sep 17 00:00:00 2001 From: Justice London Date: Tue, 14 Mar 2023 11:28:55 -0700 Subject: [PATCH 35/37] Update postgres minor version --- variables.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/variables.tf b/variables.tf index d35e61d2..5f433634 100644 --- a/variables.tf +++ b/variables.tf @@ -104,7 +104,7 @@ variable "db_enabled_cloudwatch_logs" { variable "postgres_engine_version" { type = string - default = "12.8" + default = "12.11" description = "PostgreSQL version." } From 9030ea3c53e018f0604d54b35510aa482d69250d Mon Sep 17 00:00:00 2001 From: Justice London Date: Tue, 14 Mar 2023 11:57:37 -0700 Subject: [PATCH 36/37] Go back to hairpinning on --- modules/user_data/main.tf | 4 + modules/user_data/main.tf.bak | 226 ---------------------------------- 2 files changed, 4 insertions(+), 226 deletions(-) delete mode 100644 modules/user_data/main.tf.bak diff --git a/modules/user_data/main.tf b/modules/user_data/main.tf index 512cfb37..189d6a3e 100644 --- a/modules/user_data/main.tf +++ b/modules/user_data/main.tf @@ -45,6 +45,10 @@ locals { value = "production" } + hairpin_addressing = { + value = "1" + } + production_type = { value = "external" } diff --git a/modules/user_data/main.tf.bak b/modules/user_data/main.tf.bak deleted file mode 100644 index 189d6a3e..00000000 --- a/modules/user_data/main.tf.bak +++ /dev/null @@ -1,226 +0,0 @@ -resource "random_string" "password" { - length = 16 - special = false -} - -resource "random_id" "archivist_token" { - byte_length = 16 -} - -resource "random_id" "cookie_hash" { - byte_length = 16 -} - -resource "random_id" "enc_password" { - byte_length = 16 -} - -resource "random_id" "install_id" { - byte_length = 16 -} - -resource "random_id" "internal_api_token" { - byte_length = 16 -} - -resource "random_id" "root_secret" { - byte_length = 16 -} - -resource "random_id" "registry_session_secret_key" { - byte_length = 16 -} - -resource "random_id" "registry_session_encryption_key" { - byte_length = 16 -} - -resource "random_id" "user_token" { - byte_length = 16 -} - -locals { - base_configs = { - installation_type = { - value = "production" - } - - hairpin_addressing = { - value = "1" - } - - production_type = { - value = "external" - } - - hostname = { - value = var.fqdn - } - user_token = { - value = random_id.user_token.hex - } - - archivist_token = { - value = random_id.archivist_token.hex - } - - cookie_hash = { - value = random_id.cookie_hash.hex - } - - root_secret = { - value = random_id.root_secret.hex - } - - registry_session_secret_key = { - value = random_id.registry_session_secret_key.hex - } - - registry_session_encryption_key = { - value = random_id.registry_session_encryption_key.hex - } - - internal_api_token = { - value = random_id.internal_api_token.hex - } - - install_id = { - value = random_id.install_id.hex - } - - iact_subnet_list = { - value = join(",", var.iact_subnet_list) - } - - iact_subnet_time_limit = { - value = var.iact_subnet_time_limit != null ? tostring(var.iact_subnet_time_limit) : "" - } - } - - base_external_configs = { - enable_active_active = { - value = var.active_active ? "1" : "0" - } - - pg_dbname = { - value = var.pg_dbname - } - - pg_netloc = { - value = var.pg_netloc - } - - pg_password = { - value = var.pg_password - } - - pg_user = { - value = var.pg_user - } - - enc_password = { - value = random_id.enc_password.hex - } - } - - external_aws_configs = { - placement = { - value = "placement_s3" - } - - aws_instance_profile = { - value = "1" - } - - s3_bucket = { - value = var.aws_bucket_data - } - - s3_region = { - value = var.aws_region - } - - s3_sse = { - value = "aws:kms" - } - - s3_sse_kms_key_id = { - value = var.kms_key_arn - } - } - - redis_configs = { - redis_host = { - value = var.redis_host - } - - redis_pass = { - value = var.redis_pass - } - - redis_port = { - value = var.redis_port - } - - redis_use_password_auth = { - value = var.redis_use_password_auth - } - - redis_use_tls = { - value = var.redis_use_tls - } - } -} - -locals { - import_settings_from = "/etc/ptfe-settings.json" - license_file_location = "/etc/ptfe-license.rli" - replicated_base_config = { - BypassPreflightChecks = true - DaemonAuthenticationPassword = random_string.password.result - DaemonAuthenticationType = "password" - ImportSettingsFrom = local.import_settings_from - LicenseFileLocation = local.license_file_location - TlsBootstrapType = "self-signed" - TlsBootstrapHostname = var.fqdn - } -} - -## Build tfe config json -locals { - # take all the partials and merge them into the base configs, if false, merging empty map is noop - is_redis_configs = var.active_active ? local.redis_configs : {} - tfe_configs = jsonencode(merge(local.base_configs, local.base_external_configs, local.external_aws_configs, local.is_redis_configs)) -} - -## build replicated config json -locals { - repl_configs = jsonencode(merge(local.replicated_base_config)) -} - -locals { - tfe_user_data = templatefile( - "${path.module}/templates/tfe_ec2.sh.tpl", - { - import_settings_from = local.import_settings_from - tfe_license_secret = var.tfe_license_secret - license_file_location = local.license_file_location - replicated = base64encode(local.repl_configs) - settings = base64encode(local.tfe_configs) - active_active = var.active_active - ca_certificate_secret = var.ca_certificate_secret - proxy_ip = var.proxy_ip - no_proxy = join( - ",", - concat( - [ - "127.0.0.1", - "169.254.169.254", - ".aws.ce.redhat.com", - ], - var.no_proxy - ) - ) - } - ) -} From b63a294a198bd419de54edd2e444283379e4a091 Mon Sep 17 00:00:00 2001 From: Justice London Date: Tue, 14 Mar 2023 14:05:12 -0700 Subject: [PATCH 37/37] Switch build runner to 'legacy' --- modules/user_data/main.tf | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/user_data/main.tf b/modules/user_data/main.tf index 189d6a3e..48e02dc0 100644 --- a/modules/user_data/main.tf +++ b/modules/user_data/main.tf @@ -49,6 +49,10 @@ locals { value = "1" } + run_pipeline_mode = { + value = "legacy" + } + production_type = { value = "external" }