Skip to content

Commit

Permalink
feat: add tcp lb support (#60)
Browse files Browse the repository at this point in the history
  • Loading branch information
xOtanix authored Dec 6, 2024
1 parent c39c472 commit 9fae278
Show file tree
Hide file tree
Showing 25 changed files with 365 additions and 45 deletions.
1 change: 1 addition & 0 deletions .github/workflows/terraform-CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ jobs:
role-to-assume: ${{ env.ROLE_ARN }}
role-session-name: "terraform-ci"
aws-region: "us-west-1"
role-duration-seconds: 7200

# Install the latest version of Terraform CLI
- name: Setup Terraform
Expand Down
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,11 +138,11 @@ module "httpd" {

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_alb_access_log_force_destroy"></a> [alb\_access\_log\_force\_destroy](#input\_alb\_access\_log\_force\_destroy) | Destroy S3 bucket with access logs even if non-empty | `bool` | `false` | no |
| <a name="input_alb_healthcheck_interval"></a> [alb\_healthcheck\_interval](#input\_alb\_healthcheck\_interval) | Number of seconds between checks | `number` | `5` | no |
| <a name="input_alb_healthcheck_path"></a> [alb\_healthcheck\_path](#input\_alb\_healthcheck\_path) | Path on the webserver that the elb will check to determine whether the instance is healthy or not. | `string` | `"/index.html"` | no |
| <a name="input_alb_healthcheck_response_code_matcher"></a> [alb\_healthcheck\_response\_code\_matcher](#input\_alb\_healthcheck\_response\_code\_matcher) | Range of http return codes that can match | `string` | `"200-299"` | no |
| <a name="input_alb_idle_timeout"></a> [alb\_idle\_timeout](#input\_alb\_idle\_timeout) | The time in seconds that the connection is allowed to be idle. | `number` | `60` | no |
| <a name="input_access_log_force_destroy"></a> [alb\_access\_log\_force\_destroy](#input\_alb\_access\_log\_force\_destroy) | Destroy S3 bucket with access logs even if non-empty | `bool` | `false` | no |
| <a name="input_healthcheck_interval"></a> [alb\_healthcheck\_interval](#input\_alb\_healthcheck\_interval) | Number of seconds between checks | `number` | `5` | no |
| <a name="input_healthcheck_path"></a> [alb\_healthcheck\_path](#input\_alb\_healthcheck\_path) | Path on the webserver that the elb will check to determine whether the instance is healthy or not. | `string` | `"/index.html"` | no |
| <a name="input_healthcheck_response_code_matcher"></a> [alb\_healthcheck\_response\_code\_matcher](#input\_alb\_healthcheck\_response\_code\_matcher) | Range of http return codes that can match | `string` | `"200-299"` | no |
| <a name="input_idle_timeout"></a> [alb\_idle\_timeout](#input\_alb\_idle\_timeout) | The time in seconds that the connection is allowed to be idle. | `number` | `60` | no |
| <a name="input_ami_id"></a> [ami\_id](#input\_ami\_id) | Image for host EC2 instances. If not specified, the latest Amazon image will be used. | `string` | `null` | no |
| <a name="input_asg_health_check_grace_period"></a> [asg\_health\_check\_grace\_period](#input\_asg\_health\_check\_grace\_period) | ASG will wait up to this number of seconds for instance to become healthy | `number` | `300` | no |
| <a name="input_asg_instance_type"></a> [asg\_instance\_type](#input\_asg\_instance\_type) | EC2 instances type | `string` | `"t3.micro"` | no |
Expand Down
4 changes: 2 additions & 2 deletions autoscaling.tf
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ resource "aws_appautoscaling_target" "ecs_target" {
service_namespace = "ecs"
}
locals {
lb_arn_parts = split("/", module.pod.load_balancer_arn)
tg_arn_parts = split("/", module.pod.target_group_arn)
lb_arn_parts = split("/", local.load_balancer_arn)
tg_arn_parts = split("/", local.target_group_arn)
}
resource "aws_appautoscaling_policy" "ecs_policy" {
name = "auto-scaling"
Expand Down
10 changes: 10 additions & 0 deletions locals.tf
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,14 @@ locals {
"awslogs-region" = data.aws_region.current.name
}
} : null
asg_name = var.lb_type == "alb" ? module.pod[0].asg_name : module.tcp-pod[0].asg_name
arg_arn = var.lb_type == "alb" ? module.pod[0].asg_arn : module.tcp-pod[0].asg_arn
target_group_arn = var.lb_type == "alb" ? module.pod[0].target_group_arn : module.tcp-pod[0].target_group_arn
load_balancer_arn = var.lb_type == "alb" ? module.pod[0].load_balancer_arn : module.tcp-pod[0].load_balancer_arn
load_balancer_dns_name = var.lb_type == "alb" ? module.pod[0].load_balancer_dns_name : module.tcp-pod[0].load_balancer_dns_name
backend_security_group = var.lb_type == "alb" ? module.pod[0].backend_security_group : module.tcp-pod[0].backend_security_group
instance_role_policy_name = var.lb_type == "alb" ? module.pod[0].instance_role_policy_name : module.tcp-pod[0].instance_role_policy_name
instance_role_policy_attachment = var.lb_type == "alb" ? module.pod[0].instance_role_policy_attachment : module.tcp-pod[0].instance_role_policy_attachment

}

14 changes: 7 additions & 7 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ resource "aws_ecs_capacity_provider" "ecs" {
name = var.service_name

auto_scaling_group_provider {
auto_scaling_group_arn = module.pod.asg_arn
auto_scaling_group_arn = local.arg_arn
managed_termination_protection = var.managed_termination_protection ? "ENABLED" : "DISABLED"
managed_draining = var.managed_draining ? "ENABLED" : "DISABLED"

Expand Down Expand Up @@ -113,7 +113,7 @@ resource "aws_ecs_service" "ecs" {
}

load_balancer {
target_group_arn = module.pod.target_group_arn
target_group_arn = local.target_group_arn
container_name = var.service_name
container_port = var.container_port
}
Expand All @@ -132,17 +132,17 @@ resource "aws_ecs_service" "ecs" {
{
# need these tags for implicit dependency
execution_role_arn : aws_ecs_task_definition.ecs.execution_role_arn
target_group_arn : module.pod.target_group_arn
load_balancer_arn : module.pod.load_balancer_arn
target_group_arn : local.target_group_arn
load_balancer_arn : local.load_balancer_arn
backend_security_group : substr(
base64encode(
jsonencode(
module.pod.backend_security_group
local.backend_security_group
)
), 0, 256
)
instance_role_policy_name : module.pod.instance_role_policy_name
instance_role_policy_attachment : module.pod.instance_role_policy_attachment
instance_role_policy_name : local.instance_role_policy_name
instance_role_policy_attachment : local.instance_role_policy_attachment
},
local.default_module_tags
)
Expand Down
6 changes: 3 additions & 3 deletions outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ output "service_arn" {

output "asg_arn" {
description = "Autoscaling group ARN created for the ECS service."
value = module.pod.asg_arn
value = local.arg_arn
}

output "asg_name" {
description = "Autoscaling group name created for the ECS service."
value = module.pod.asg_name
value = local.asg_name
}

output "load_balancer_dns_name" {
description = "Load balancer DNS name."
value = module.pod.load_balancer_dns_name
value = local.load_balancer_dns_name
}
43 changes: 43 additions & 0 deletions tcp-pod.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
module "tcp-pod" {
count = var.lb_type == "nlb" ? 1 : 0
source = "registry.infrahouse.com/infrahouse/tcp-pod/aws"
version = "0.1.2"
providers = {
aws = aws
aws.dns = aws.dns
}
service_name = var.service_name
environment = var.environment
nlb_name_prefix = substr(var.service_name, 0, 6)
nlb_healthcheck_port = "traffic-port"
nlb_idle_timeout = var.idle_timeout
nlb_healthcheck_interval = var.healthcheck_interval
nlb_healthcheck_timeout = var.healthcheck_timeout
nlb_listener_port = var.container_port
health_check_grace_period = var.asg_health_check_grace_period
health_check_type = "EC2"
attach_target_group_to_asg = false
instance_type = var.asg_instance_type
asg_min_size = var.asg_min_size
asg_max_size = var.asg_max_size
asg_scale_in_protected_instances = "Refresh"
subnets = var.load_balancer_subnets
backend_subnets = var.asg_subnets
zone_id = var.zone_id
dns_a_records = var.dns_names
ami = var.ami_id == null ? data.aws_ami.ecs.image_id : var.ami_id
key_pair_name = data.aws_key_pair.ssh_key_pair.key_name
target_group_port = var.container_port
userdata = data.cloudinit_config.ecs.rendered
instance_profile_permissions = data.aws_iam_policy_document.instance_policy.json
protect_from_scale_in = true # this is to allow ECS manage ASG instances
autoscaling_target_cpu_load = var.autoscaling_target_cpu_usage
root_volume_size = var.root_volume_size
ssh_cidr_block = var.ssh_cidr_block
tags = {
Name : var.service_name
AmazonECSManaged : true
parent_module : local.module_name
parent_module_version : local.module_version
}
}
2 changes: 1 addition & 1 deletion test_data/httpd/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ module "httpd" {
asg_min_size = 1
container_healthcheck_command = "ls"
task_role_arn = aws_iam_role.task_role.arn
alb_access_log_force_destroy = true
access_log_force_destroy = true
dockerSecurityOptions = [
"no-new-privileges",
]
Expand Down
2 changes: 1 addition & 1 deletion test_data/httpd_autoscaling/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ module "httpd" {
asg_min_size = 1
container_healthcheck_command = "ls"
task_role_arn = aws_iam_role.task_role.arn
alb_access_log_force_destroy = true
access_log_force_destroy = true
autoscaling_metric = var.autoscaling_metric
autoscaling_target = var.autoscaling_target

Expand Down
2 changes: 1 addition & 1 deletion test_data/httpd_efs/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ module "httpd" {
task_desired_count = 1
container_healthcheck_command = "ls"
task_role_arn = aws_iam_role.task_role.arn
alb_access_log_force_destroy = true
access_log_force_destroy = true
task_efs_volumes = {
"volume1" : {
file_system_id : aws_efs_file_system.volume1.id
Expand Down
37 changes: 37 additions & 0 deletions test_data/httpd_tcp/datasources.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
data "aws_caller_identity" "this" {}
data "aws_region" "current" {}
data "aws_availability_zones" "available" {
state = "available"
}

data "aws_route53_zone" "cicd" {
name = var.test_zone
}

data "aws_ami" "ubuntu" {
most_recent = true

filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-${var.ubuntu_codename}-*"]
}

filter {
name = "architecture"
values = ["x86_64"]
}

filter {
name = "virtualization-type"
values = ["hvm"]
}

filter {
name = "state"
values = [
"available"
]
}

owners = ["099720109477"] # Canonical
}
47 changes: 47 additions & 0 deletions test_data/httpd_tcp/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
resource "aws_key_pair" "mediapc" {
public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDpgAP1z1Lxg9Uv4tam6WdJBcAftZR4ik7RsSr6aNXqfnTj4civrhd/q8qMqF6wL//3OujVDZfhJcffTzPS2XYhUxh/rRVOB3xcqwETppdykD0XZpkHkc8XtmHpiqk6E9iBI4mDwYcDqEg3/vrDAGYYsnFwWmdDinxzMH1Gei+NPTmTqU+wJ1JZvkw3WBEMZKlUVJC/+nuv+jbMmCtm7sIM4rlp2wyzLWYoidRNMK97sG8+v+mDQol/qXK3Fuetj+1f+vSx2obSzpTxL4RYg1kS6W1fBlSvstDV5bQG4HvywzN5Y8eCpwzHLZ1tYtTycZEApFdy+MSfws5vPOpggQlWfZ4vA8ujfWAF75J+WABV4DlSJ3Ng6rLMW78hVatANUnb9s4clOS8H6yAjv+bU3OElKBkQ10wNneoFIMOA3grjPvPp5r8dI0WDXPIznJThDJO5yMCy3OfCXlu38VDQa1sjVj1zAPG+Vn2DsdVrl50hWSYSB17Zww0MYEr8N5rfFE= aleks@MediaPC"
}

resource "aws_key_pair" "black-mbp" {
public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDBVMh/uBvxKF88z0VxbFYJwhGJklVWf90HJOiESQetC8AJXx6M0x9faPiK5z/SsFjNerCU9TwUZzEgLudB3OWm/X8BChGH3r1g5MsP3FpCd2UCQGu5/0jdX60TePhQ+4SVuoYpjaKIKhulzKM+lEcsJHIk+pM+cKA9yCt4rWghgp7OLXAJE2cA0qy0vv/DytReHoEPFFFtrKUSltmQhu1ggGXH+5pb7kFx2GWLElhVAeG0d+mJdRUXXnDzqjGvW2IrmOAcKJXkF5m9ITjKn55UiuZIPx4k/iLMQQ+am2F/VlttAdEl8Tgo27Q5UhqAH08sHrVnr1qciS8Rdavt8rNPSseFVh7e3wVvMBH4NvEd2gVPThssxlC7BjIfLQGb1jFiRdMHagbG4U4vtpr2pus2PnmcMOQwdC3WjvmyXHjCRQiS16FwJburRfBKGhQf30wjyzvyJ3PDMk4Sni/3Gl69TKb2s91Zq56yhCCrUjMhTtqjmdNvD8jEmIswV+fTyoU= aleks@Black-MBP"
}

resource "random_pet" "hostname" {

}

module "httpd" {
source = "../../"
providers = {
aws = aws
aws.dns = aws
}
load_balancer_subnets = var.subnet_public_ids
asg_subnets = var.subnet_private_ids
dns_names = ["", "www"]
docker_image = "httpd"
container_port = 80
service_name = var.service_name
ssh_key_name = aws_key_pair.black-mbp.key_name
zone_id = data.aws_route53_zone.cicd.zone_id
task_desired_count = 1
asg_max_size = 1
asg_min_size = 1
container_healthcheck_command = "ls"
healthcheck_interval = 10
lb_type = "nlb"
access_log_force_destroy = true
dockerSecurityOptions = [
"no-new-privileges",
]
users = [
{
name : "aleks"
ssh_authorized_keys : [
aws_key_pair.black-mbp.public_key,
aws_key_pair.mediapc.public_key,
]
sudo : ["ALL=(ALL) NOPASSWD:ALL"]
}
]
}
11 changes: 11 additions & 0 deletions test_data/httpd_tcp/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
output "zone_id" {
value = data.aws_route53_zone.cicd.zone_id
}

output "jumphost_hostname" {
value = random_pet.hostname.id
}

output "load_balancer_dns_name" {
value = module.httpd.load_balancer_dns_name
}
12 changes: 12 additions & 0 deletions test_data/httpd_tcp/providers.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
provider "aws" {
region = var.region
assume_role {
role_arn = var.role_arn
}
default_tags {
tags = {
"created_by" : "infrahouse/terraform-aws-ecs" # GitHub repository that created a resource
}

}
}
51 changes: 51 additions & 0 deletions test_data/httpd_tcp/task_role.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
data "aws_iam_policy_document" "task_role_assume" {
statement {
principals {
identifiers = [
"ecs-tasks.amazonaws.com"
]
type = "Service"
}
actions = [
"sts:AssumeRole"
]
condition {
test = "StringEquals"
values = [
data.aws_caller_identity.this.account_id
]
variable = "aws:SourceAccount"
}
condition {
test = "ArnLike"
values = [
"arn:aws:ecs:${data.aws_region.current.name}:${data.aws_caller_identity.this.account_id}:*"
]
variable = "aws:SourceArn"
}
}
}

data "aws_iam_policy_document" "task_role_permissions" {
statement {
actions = [
"s3:*"
]
resources = ["*"]
}
}

resource "aws_iam_policy" "task_role" {
name_prefix = "task-"
policy = data.aws_iam_policy_document.task_role_permissions.json
}

resource "aws_iam_role" "task_role" {
name_prefix = "task-"
assume_role_policy = data.aws_iam_policy_document.task_role_assume.json
}

resource "aws_iam_role_policy_attachment" "task_role" {
policy_arn = aws_iam_policy.task_role.arn
role = aws_iam_role.task_role.name
}
13 changes: 13 additions & 0 deletions test_data/httpd_tcp/terraform.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
terraform {
//noinspection HILUnresolvedReference
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.11"
}
cloudinit = {
source = "hashicorp/cloudinit"
version = "~> 2.3"
}
}
}
18 changes: 18 additions & 0 deletions test_data/httpd_tcp/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
variable "environment" {
default = "development"
}
variable "region" {}
variable "role_arn" {}
variable "service_name" {
default = "test-terraform-aws-ecs"
}
variable "task_role_arn" {}
variable "test_zone" {}
variable "ubuntu_codename" {
default = "jammy"
}


variable "subnet_public_ids" {}
variable "subnet_private_ids" {}
variable "internet_gateway_id" {}
2 changes: 1 addition & 1 deletion test_data/service-network/providers.tf
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ provider "aws" {
}
default_tags {
tags = {
"created_by" : "infrahouse/terraform-aws-pypiserver" # GitHub repository that created a resource
"created_by" : "infrahouse/terraform-aws-ecs" # GitHub repository that created a resource
}

}
Expand Down
Loading

0 comments on commit 9fae278

Please sign in to comment.