From feb2aa3a8c874934a9edfe859be2707819390db1 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Fri, 27 Sep 2024 09:55:46 +0100 Subject: [PATCH 001/116] add blue green tgs --- tf/network/load_balancer/main.tf | 34 +++++++++++++++++++++++++---- tf/network/load_balancer/outputs.tf | 8 +++++-- 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/tf/network/load_balancer/main.tf b/tf/network/load_balancer/main.tf index a2b2971..f48b693 100644 --- a/tf/network/load_balancer/main.tf +++ b/tf/network/load_balancer/main.tf @@ -30,10 +30,27 @@ resource "aws_lb" "lb" { enable_cross_zone_load_balancing = true } -resource "aws_lb_target_group" "tg" { - depends_on = [aws_lb.lb] +resource "aws_lb_target_group" "tg_blue" { + name = "${var.project_name}-tg-blue" + port = var.container_port + protocol = "HTTP" + vpc_id = var.private_vpc_id + + target_type = "ip" + + health_check { + interval = 10 + path = "/health" + protocol = "HTTP" + matcher = "200" + timeout = 5 + healthy_threshold = 2 + unhealthy_threshold = 2 + } +} - name = "${var.project_name}-tg" +resource "aws_lb_target_group" "tg_green" { + name = "${var.project_name}-tg-green" port = var.container_port protocol = "HTTP" vpc_id = var.private_vpc_id @@ -58,6 +75,15 @@ resource "aws_lb_listener" "listener" { default_action { type = "forward" - target_group_arn = aws_lb_target_group.tg.arn + forward { + target_group { + arn = aws_lb_target_group.tg_blue.arn + weight = 100 + } + target_group { + arn = aws_lb_target_group.tg_green.arn + weight = 0 + } + } } } diff --git a/tf/network/load_balancer/outputs.tf b/tf/network/load_balancer/outputs.tf index 2331e8a..eb5682e 100644 --- a/tf/network/load_balancer/outputs.tf +++ b/tf/network/load_balancer/outputs.tf @@ -6,6 +6,10 @@ output "lb_listener_arn" { value = aws_lb_listener.listener.arn } -output "target_group_arn" { - value = aws_lb_target_group.tg.arn +output "blue_target_group_arn" { + value = aws_lb_target_group.tg_blue.arn +} + +output "green_target_group_arn" { + value = aws_lb_target_group.tg_green.arn } From d567cd32e7ff4158c8136a295658aa087ce15d86 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Fri, 27 Sep 2024 11:58:14 +0100 Subject: [PATCH 002/116] mv lb to service --- tf/network/data.tf | 7 ++ tf/network/locals.tf | 11 +- tf/network/main.tf | 112 ++++++++++++++---- tf/network/outputs.tf | 22 +--- tf/network/variables.tf | 12 +- tf/network/vpc_link/data.tf | 6 - tf/network/vpc_link/locals.tf | 7 -- tf/network/vpc_link/main.tf | 91 -------------- tf/network/vpc_link/outputs.tf | 3 - tf/network/vpc_link/variables.tf | 33 ------ tf/service/data.tf | 16 +++ tf/service/deploy/data.tf | 26 ++++ tf/service/deploy/main.tf | 64 ++++++++++ tf/service/deploy/variables.tf | 27 +++++ tf/service/ecs/main.tf | 2 +- tf/service/ecs/variables.tf | 2 +- tf/{network => service}/load_balancer/main.tf | 2 +- .../load_balancer/outputs.tf | 4 +- .../load_balancer/variables.tf | 0 tf/service/locals.tf | 7 ++ tf/service/main.tf | 42 +++++-- tf/service/variables.tf | 22 +--- tf/task/locals.tf | 6 +- 23 files changed, 295 insertions(+), 229 deletions(-) delete mode 100644 tf/network/vpc_link/data.tf delete mode 100644 tf/network/vpc_link/locals.tf delete mode 100644 tf/network/vpc_link/main.tf delete mode 100644 tf/network/vpc_link/outputs.tf delete mode 100644 tf/network/vpc_link/variables.tf create mode 100644 tf/service/data.tf create mode 100644 tf/service/deploy/data.tf create mode 100644 tf/service/deploy/main.tf create mode 100644 tf/service/deploy/variables.tf rename tf/{network => service}/load_balancer/main.tf (98%) rename tf/{network => service}/load_balancer/outputs.tf (77%) rename tf/{network => service}/load_balancer/variables.tf (100%) create mode 100644 tf/service/locals.tf diff --git a/tf/network/data.tf b/tf/network/data.tf index 5821cc3..6fda46b 100644 --- a/tf/network/data.tf +++ b/tf/network/data.tf @@ -16,3 +16,10 @@ data "aws_subnet" "subnets" { for_each = toset(data.aws_subnets.private.ids) id = each.value } + +data "aws_route_tables" "subnet_route_tables" { + filter { + name = "association.subnet-id" + values = data.aws_subnets.private.ids + } +} diff --git a/tf/network/locals.tf b/tf/network/locals.tf index b4a24ef..2cd91fe 100644 --- a/tf/network/locals.tf +++ b/tf/network/locals.tf @@ -1,3 +1,12 @@ locals { - private_subnet_cidrs = [for s in data.aws_subnet.subnets : s.cidr_block] + interface_endpoints = { + ecr_api = "ecr.api" + ecr_dkr = "ecr.dkr" + logs = "logs" + } + private_vpc_id = data.aws_vpc.private.id + private_vpc_cidr_block = data.aws_vpc.private.cidr_block + private_subnet_ids = data.aws_subnets.private.ids + private_subnet_cidrs = [for s in data.aws_subnet.subnets : s.cidr_block] + subnet_route_table_ids = data.aws_route_tables.subnet_route_tables.ids } \ No newline at end of file diff --git a/tf/network/main.tf b/tf/network/main.tf index 889cd6e..1780ced 100644 --- a/tf/network/main.tf +++ b/tf/network/main.tf @@ -1,23 +1,91 @@ -module "load_balancer" { - source = "./load_balancer" - - project_name = var.project_name - container_port = var.container_port - load_balancer_port = var.load_balancer_port - private_vpc_id = data.aws_vpc.private.id - private_vpc_cidr_block = data.aws_vpc.private.cidr_block - private_subnet_ids = data.aws_subnets.private.ids - private_subnet_cidrs = local.private_subnet_cidrs -} - -module "vpc_link" { - source = "./vpc_link" - - project_name = var.project_name - stage_name = var.api_stage_name - lb_listener_arn = module.load_balancer.lb_listener_arn - private_vpc_id = data.aws_vpc.private.id - private_vpc_cidr_block = data.aws_vpc.private.cidr_block - private_subnet_ids = data.aws_subnets.private.ids - private_subnet_cidrs = local.private_subnet_cidrs +resource "aws_security_group" "vpc_endpoint" { + name = "${var.project_name}-vpc-endpoint-sg" + description = "Security group for VPC endpoints" + vpc_id = local.private_vpc_id + + ingress { + from_port = 443 + to_port = 443 + protocol = "tcp" + cidr_blocks = [local.private_vpc_cidr_block] + } + + egress { + from_port = 443 + to_port = 443 + protocol = "tcp" + cidr_blocks = [local.private_vpc_cidr_block] + } +} + +resource "aws_vpc_endpoint" "interface_endpoints" { + for_each = local.interface_endpoints + vpc_id = local.private_vpc_id + service_name = "com.amazonaws.${var.region}.${each.value}" + vpc_endpoint_type = "Interface" + security_group_ids = [aws_security_group.vpc_endpoint.id] + subnet_ids = local.private_subnet_ids + private_dns_enabled = true +} + +resource "aws_vpc_endpoint" "gateway_s3" { + vpc_id = local.private_vpc_id + service_name = "com.amazonaws.${var.region}.s3" + vpc_endpoint_type = "Gateway" + route_table_ids = local.subnet_route_table_ids +} + +resource "aws_security_group" "api_gateway_vpc_link" { + name = "${var.project_name}-api-gateway-vpc-link-sg" + description = "Security group for API Gateway VPC link" + vpc_id = local.private_vpc_id + + ingress { + from_port = 80 + to_port = 80 + protocol = "tcp" + cidr_blocks = local.private_subnet_cidrs + } + + egress { + from_port = 80 + to_port = 80 + protocol = "tcp" + cidr_blocks = local.private_subnet_cidrs + } +} + +resource "aws_apigatewayv2_vpc_link" "this" { + name = "${var.project_name}-vpc-link" + subnet_ids = local.private_subnet_ids + security_group_ids = [aws_security_group.api_gateway_vpc_link.id] +} + +resource "aws_apigatewayv2_integration" "this" { + api_id = aws_apigatewayv2_api.this.id + integration_type = "HTTP_PROXY" + connection_type = "VPC_LINK" + connection_id = aws_apigatewayv2_vpc_link.this.id + integration_method = "ANY" + integration_uri = var.load_balancer_listener_arn + + payload_format_version = "1.0" +} + +resource "aws_apigatewayv2_route" "this" { + api_id = aws_apigatewayv2_api.this.id + route_key = "ANY /{proxy+}" + + target = "integrations/${aws_apigatewayv2_integration.this.id}" +} + +resource "aws_apigatewayv2_stage" "this" { + api_id = aws_apigatewayv2_api.this.id + name = var.api_stage_name + auto_deploy = true +} + +resource "aws_apigatewayv2_api" "this" { + name = "${var.project_name}-api" + protocol_type = "HTTP" } diff --git a/tf/network/outputs.tf b/tf/network/outputs.tf index 2972187..c317e21 100644 --- a/tf/network/outputs.tf +++ b/tf/network/outputs.tf @@ -1,23 +1,3 @@ -output "lb_security_group_id" { - value = module.load_balancer.load_balancer_security_group_id -} - -output "lb_listener_arn" { - value = module.load_balancer.lb_listener_arn -} - -output "target_group_arn" { - value = module.load_balancer.target_group_arn -} - output "api_invoke_url" { - value = module.vpc_link.api_invoke_url -} - -output "private_vpc_id" { - value = data.aws_vpc.private.id -} - -output "private_subnet_ids" { - value = data.aws_subnets.private.ids + value = aws_apigatewayv2_stage.this.invoke_url } diff --git a/tf/network/variables.tf b/tf/network/variables.tf index 2482907..0dc5696 100644 --- a/tf/network/variables.tf +++ b/tf/network/variables.tf @@ -22,13 +22,7 @@ variable "private_vpc_name" { type = string } -variable "initial_task_count" { - description = "initial and minimum number of tasks to run on the ECS instance" - type = number - default = 2 - - validation { - condition = var.initial_task_count >= 2 - error_message = "The initial_task_count must be at least 2." - } +variable "load_balancer_listener_arn" { + type = string + description = "generated from ecs load balancer deployment" } diff --git a/tf/network/vpc_link/data.tf b/tf/network/vpc_link/data.tf deleted file mode 100644 index 6c94f8b..0000000 --- a/tf/network/vpc_link/data.tf +++ /dev/null @@ -1,6 +0,0 @@ -data "aws_route_tables" "subnet_route_tables" { - filter { - name = "association.subnet-id" - values = var.private_subnet_ids - } -} diff --git a/tf/network/vpc_link/locals.tf b/tf/network/vpc_link/locals.tf deleted file mode 100644 index 33425de..0000000 --- a/tf/network/vpc_link/locals.tf +++ /dev/null @@ -1,7 +0,0 @@ -locals { - interface_endpoints = { - ecr_api = "ecr.api" - ecr_dkr = "ecr.dkr" - logs = "logs" - } -} \ No newline at end of file diff --git a/tf/network/vpc_link/main.tf b/tf/network/vpc_link/main.tf deleted file mode 100644 index acf896c..0000000 --- a/tf/network/vpc_link/main.tf +++ /dev/null @@ -1,91 +0,0 @@ -resource "aws_security_group" "vpc_endpoint" { - name = "${var.project_name}-vpc-endpoint-sg" - description = "Security group for VPC endpoints" - vpc_id = var.private_vpc_id - - ingress { - from_port = 443 - to_port = 443 - protocol = "tcp" - cidr_blocks = [var.private_vpc_cidr_block] - } - - egress { - from_port = 443 - to_port = 443 - protocol = "tcp" - cidr_blocks = [var.private_vpc_cidr_block] - } -} - -resource "aws_vpc_endpoint" "interface_endpoints" { - for_each = local.interface_endpoints - vpc_id = var.private_vpc_id - service_name = "com.amazonaws.${var.region}.${each.value}" - vpc_endpoint_type = "Interface" - security_group_ids = [aws_security_group.vpc_endpoint.id] - subnet_ids = var.private_subnet_ids - private_dns_enabled = true -} - -resource "aws_vpc_endpoint" "gateway_s3" { - vpc_id = var.private_vpc_id - service_name = "com.amazonaws.${var.region}.s3" - vpc_endpoint_type = "Gateway" - route_table_ids = data.aws_route_tables.subnet_route_tables.ids -} - -resource "aws_security_group" "api_gateway_vpc_link" { - name = "${var.project_name}-api-gateway-vpc-link-sg" - description = "Security group for API Gateway VPC link" - vpc_id = var.private_vpc_id - - ingress { - from_port = 80 - to_port = 80 - protocol = "tcp" - cidr_blocks = var.private_subnet_cidrs - } - - egress { - from_port = 80 - to_port = 80 - protocol = "tcp" - cidr_blocks = var.private_subnet_cidrs - } -} - -resource "aws_apigatewayv2_vpc_link" "this" { - name = "${var.project_name}-vpc-link" - subnet_ids = var.private_subnet_ids - security_group_ids = [aws_security_group.api_gateway_vpc_link.id] -} - -resource "aws_apigatewayv2_integration" "this" { - api_id = aws_apigatewayv2_api.this.id - integration_type = "HTTP_PROXY" - connection_type = "VPC_LINK" - connection_id = aws_apigatewayv2_vpc_link.this.id - integration_method = "ANY" - integration_uri = var.lb_listener_arn - - payload_format_version = "1.0" -} - -resource "aws_apigatewayv2_route" "this" { - api_id = aws_apigatewayv2_api.this.id - route_key = "ANY /{proxy+}" - - target = "integrations/${aws_apigatewayv2_integration.this.id}" -} - -resource "aws_apigatewayv2_stage" "this" { - api_id = aws_apigatewayv2_api.this.id - name = var.stage_name - auto_deploy = true -} - -resource "aws_apigatewayv2_api" "this" { - name = "${var.project_name}-api" - protocol_type = "HTTP" -} diff --git a/tf/network/vpc_link/outputs.tf b/tf/network/vpc_link/outputs.tf deleted file mode 100644 index c317e21..0000000 --- a/tf/network/vpc_link/outputs.tf +++ /dev/null @@ -1,3 +0,0 @@ -output "api_invoke_url" { - value = aws_apigatewayv2_stage.this.invoke_url -} diff --git a/tf/network/vpc_link/variables.tf b/tf/network/vpc_link/variables.tf deleted file mode 100644 index 5697577..0000000 --- a/tf/network/vpc_link/variables.tf +++ /dev/null @@ -1,33 +0,0 @@ -variable "region" { - type = string - default = "eu-west-2" -} - -variable "project_name" { - type = string -} - -variable "stage_name" { - type = string -} - -variable "private_vpc_id" { - type = string -} - -variable "private_vpc_cidr_block" { - type = string -} - -variable "private_subnet_ids" { - type = list(string) -} - -variable "private_subnet_cidrs" { - type = list(string) -} - -variable "lb_listener_arn" { - type = string - description = "arn to forward api calls to i.e. load balancer" -} diff --git a/tf/service/data.tf b/tf/service/data.tf new file mode 100644 index 0000000..c41e7d8 --- /dev/null +++ b/tf/service/data.tf @@ -0,0 +1,16 @@ +data "aws_vpc" "private" { + filter { + name = "tag:Name" + values = [var.private_vpc_name] + } +} + +data "aws_subnet" "subnets" { + for_each = toset(data.aws_subnets.private.ids) + id = each.value +} + +data "aws_subnet" "subnets" { + for_each = toset(data.aws_subnets.private.ids) + id = each.value +} \ No newline at end of file diff --git a/tf/service/deploy/data.tf b/tf/service/deploy/data.tf new file mode 100644 index 0000000..e7ccfa5 --- /dev/null +++ b/tf/service/deploy/data.tf @@ -0,0 +1,26 @@ +data "aws_iam_policy_document" "codedeploy_assume_role_policy" { + statement { + actions = ["sts:AssumeRole"] + + effect = "Allow" + + principals { + type = "Service" + identifiers = ["codedeploy.amazonaws.com"] + } + } +} + +data "aws_iam_policy_document" "codedeploy_policy" { + statement { + actions = [ + "ecs:UpdateService", + "ecs:DescribeServices", + "elasticloadbalancing:*", + "autoscaling:*", + "codedeploy:*" + ] + effect = "Allow" + resources = ["*"] + } +} diff --git a/tf/service/deploy/main.tf b/tf/service/deploy/main.tf new file mode 100644 index 0000000..c7eab3b --- /dev/null +++ b/tf/service/deploy/main.tf @@ -0,0 +1,64 @@ +resource "aws_codedeploy_app" "ecs_app" { + name = "${var.project_name}-ecs-codedeploy" + compute_platform = "ECS" +} + +resource "aws_iam_role" "this" { + name = "${var.project_name}-codedeploy_role" + assume_role_policy = data.aws_iam_policy_document.codedeploy_assume_role_policy.json +} + +resource "aws_iam_role_policy" "codedeploy_role_policy" { + role = aws_iam_role.this.id + policy = data.aws_iam_policy_document.codedeploy_policy.json +} + +resource "aws_codedeploy_deployment_group" "this" { + app_name = aws_codedeploy_app.ecs_app.name + # Shifts 10% of the traffic in the first increment, then shifts the remaining 90% after 5 minutes + deployment_config_name = "CodeDeployDefault.ECSCanary10Percent5Minutes" + deployment_group_name = "${var.project_name}-blue-green-group" + service_role_arn = aws_iam_role.this.arn + + auto_rollback_configuration { + enabled = true + events = ["DEPLOYMENT_FAILURE"] + } + + blue_green_deployment_config { + deployment_ready_option { + action_on_timeout = "CONTINUE_DEPLOYMENT" + } + + terminate_blue_instances_on_deployment_success { + action = "TERMINATE" + termination_wait_time_in_minutes = 5 + } + } + + deployment_style { + deployment_option = "WITH_TRAFFIC_CONTROL" + deployment_type = "BLUE_GREEN" + } + + ecs_service { + cluster_name = var.cluster_name + service_name = var.service_name + } + + load_balancer_info { + target_group_pair_info { + prod_traffic_route { + listener_arns = [var.lb_listener_arn] + } + + target_group { + name = var.lb_blue_target_group_arn + } + + target_group { + name = var.lb_green_target_group_arn + } + } + } +} \ No newline at end of file diff --git a/tf/service/deploy/variables.tf b/tf/service/deploy/variables.tf new file mode 100644 index 0000000..9ce7940 --- /dev/null +++ b/tf/service/deploy/variables.tf @@ -0,0 +1,27 @@ +variable "project_name" { + type = string +} + +variable "region" { + type = string +} + +variable "cluster_name" { + type = string +} + +variable "service_name" { + type = string +} + +variable "lb_listener_arn" { + type = string +} + +variable "lb_green_target_group_arn" { + type = string +} + +variable "lb_blue_target_group_arn" { + type = string +} \ No newline at end of file diff --git a/tf/service/ecs/main.tf b/tf/service/ecs/main.tf index 2c4eb72..e78a79e 100644 --- a/tf/service/ecs/main.tf +++ b/tf/service/ecs/main.tf @@ -10,7 +10,7 @@ resource "aws_security_group" "ecs_sg" { from_port = 0 to_port = var.container_port protocol = "tcp" - security_groups = [var.load_balancer_security_group_id] + security_groups = [var.lb_security_group_id] } egress { diff --git a/tf/service/ecs/variables.tf b/tf/service/ecs/variables.tf index 817b2ad..9e72fb9 100644 --- a/tf/service/ecs/variables.tf +++ b/tf/service/ecs/variables.tf @@ -22,7 +22,7 @@ variable "load_balancer_port" { type = number } -variable "load_balancer_security_group_id" { +variable "lb_security_group_id" { type = string } diff --git a/tf/network/load_balancer/main.tf b/tf/service/load_balancer/main.tf similarity index 98% rename from tf/network/load_balancer/main.tf rename to tf/service/load_balancer/main.tf index f48b693..771e74e 100644 --- a/tf/network/load_balancer/main.tf +++ b/tf/service/load_balancer/main.tf @@ -74,7 +74,7 @@ resource "aws_lb_listener" "listener" { protocol = "HTTP" default_action { - type = "forward" + type = "forward" forward { target_group { arn = aws_lb_target_group.tg_blue.arn diff --git a/tf/network/load_balancer/outputs.tf b/tf/service/load_balancer/outputs.tf similarity index 77% rename from tf/network/load_balancer/outputs.tf rename to tf/service/load_balancer/outputs.tf index eb5682e..eab12f6 100644 --- a/tf/network/load_balancer/outputs.tf +++ b/tf/service/load_balancer/outputs.tf @@ -1,8 +1,8 @@ -output "load_balancer_security_group_id" { +output "security_group_id" { value = aws_security_group.lb_sg.id } -output "lb_listener_arn" { +output "listener_arn" { value = aws_lb_listener.listener.arn } diff --git a/tf/network/load_balancer/variables.tf b/tf/service/load_balancer/variables.tf similarity index 100% rename from tf/network/load_balancer/variables.tf rename to tf/service/load_balancer/variables.tf diff --git a/tf/service/locals.tf b/tf/service/locals.tf new file mode 100644 index 0000000..4aa8c09 --- /dev/null +++ b/tf/service/locals.tf @@ -0,0 +1,7 @@ +locals { + load_balancer_port = 80 + private_vpc_id = data.aws_vpc.private.id + private_vpc_cidr_block = data.aws_vpc.private.cidr_block + private_subnet_ids = data.aws_subnets.private.ids + private_subnet_cidrs = [for s in data.aws_subnet.subnets : s.cidr_block] +} \ No newline at end of file diff --git a/tf/service/main.tf b/tf/service/main.tf index 02e31b0..58d1373 100644 --- a/tf/service/main.tf +++ b/tf/service/main.tf @@ -1,15 +1,39 @@ module "ecs" { source = "./ecs" - project_name = var.project_name - initial_task_count = var.initial_task_count - container_port = var.container_port - load_balancer_port = var.load_balancer_port - lb_target_group_arn = var.lb_target_group_arn - task_definition_arn = var.task_definition_arn - private_vpc_id = var.private_vpc_id - private_subnet_ids = var.private_subnet_ids - load_balancer_security_group_id = var.load_balancer_security_group_id + project_name = var.project_name + initial_task_count = var.initial_task_count + container_port = var.container_port + load_balancer_port = local.load_balancer_port + task_definition_arn = var.task_definition_arn + private_vpc_id = local.private_vpc_id + private_subnet_ids = local.private_subnet_ids + lb_target_group_arn = module.load_balancer.blue_target_group_arn + lb_security_group_id = module.load_balancer.security_group_id +} + +module "load_balancer" { + source = "./load_balancer" + + project_name = var.project_name + container_port = var.container_port + load_balancer_port = local.load_balancer_port + private_vpc_id = local.private_vpc_id + private_vpc_cidr_block = local.private_vpc_cidr_block + private_subnet_cidrs = local.private_subnet_cidrs + private_subnet_ids = local.private_subnet_ids +} + +module "deploy" { + source = "./deploy" + + project_name = var.project_name + region = var.region + cluster_name = module.ecs.cluster_name + service_name = module.ecs.service_name + lb_listener_arn = module.load_balancer.listener_arn + lb_blue_target_group_arn = module.load_balancer.blue_target_group_arn + lb_green_target_group_arn = module.load_balancer.green_target_group_arn } module "auto_scaling" { diff --git a/tf/service/variables.tf b/tf/service/variables.tf index 7e274e7..95db1b5 100644 --- a/tf/service/variables.tf +++ b/tf/service/variables.tf @@ -6,11 +6,11 @@ variable "region" { type = string } -variable "container_port" { - type = number +variable "private_vpc_name" { + type = string } -variable "load_balancer_port" { +variable "container_port" { type = number } @@ -18,22 +18,6 @@ variable "task_definition_arn" { type = string } -variable "private_vpc_id" { - type = string -} - -variable "private_subnet_ids" { - type = list(string) -} - -variable "lb_target_group_arn" { - type = string -} - -variable "load_balancer_security_group_id" { - type = string -} - variable "initial_task_count" { description = "initial and minimum number of tasks to run on the ECS instance" type = number diff --git a/tf/task/locals.tf b/tf/task/locals.tf index c57f156..02a3650 100644 --- a/tf/task/locals.tf +++ b/tf/task/locals.tf @@ -1,7 +1,7 @@ locals { - formatted_name = replace(var.project_name, "-", "_") - cloudwatch_log_name = "/ecs/${local.formatted_name}" - image_uri = data.aws_ecr_image.this.image_uri + formatted_name = replace(var.project_name, "-", "_") + cloudwatch_log_name = "/ecs/${local.formatted_name}" + image_uri = data.aws_ecr_image.this.image_uri container_definitions = templatefile("${path.module}/container_definitions.tpl", { container_name = var.project_name image_uri = local.image_uri From 7162dc0bef35d118bdf696dc5aabb3b850d2cdc3 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Fri, 27 Sep 2024 13:42:46 +0100 Subject: [PATCH 003/116] deploy refactor --- .github/workflows/deploy.yml | 233 ++++++++++++++++------------------- tf/service/outputs.tf | 4 + 2 files changed, 109 insertions(+), 128 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 2c9cc34..8222310 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -16,7 +16,6 @@ env: TF_VAR_private_vpc_name: ecs-private-vpc TF_VAR_api_stage_name: dev TF_VAR_container_port: 3000 - TF_VAR_load_balancer_port: 80 permissions: id-token: write @@ -54,69 +53,12 @@ jobs: aws_account_id: ${{ vars.AWS_ACCOUNT_ID }} aws_region: ${{ vars.AWS_REGION }} - network: - runs-on: ubuntu-latest - outputs: - lb_security_group_id: ${{ steps.set-envs.outputs.LB_SERCURITY_GROUP_ID }} - lb_listener_arn: ${{ steps.set-envs.outputs.LB_LISTENER_ARN }} - target_group_arn: ${{ steps.set-envs.outputs.TARGET_GROUP_ARN }} - api_invoke_url: ${{ steps.set-envs.outputs.API_INVOKE_URL }} - private_vpc_id: ${{ steps.set-envs.outputs.PRIVATE_VPC_ID }} - private_subnet_ids: ${{ steps.set-envs.outputs.PRIVATE_SUBNET_IDS }} - steps: - - uses: actions/checkout@v4 - - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v4 - with: - aws-region: ${{ env.aws_region }} - role-to-assume: arn:aws:iam::${{ env.aws_account_id }}:role/${{ env.aws_role }} - role-session-name: GitHubActions - - - name: Init - shell: bash - run: | - cd tf/network - terraform init - - - name: Deploy - shell: bash - id: deploy - run: | - cd tf/network - terraform apply -auto-approve - - - name: Set env vars - id: set-envs - shell: bash - run: | - cd tf/network - - LB_SERCURITY_GROUP_ID=$(terraform output -raw lb_security_group_id) - echo "LB_SERCURITY_GROUP_ID=$LB_SERCURITY_GROUP_ID" >> $GITHUB_OUTPUT - - LB_LISTENER_ARN=$(terraform output -raw lb_listener_arn) - echo "LB_LISTENER_ARN=$LB_LISTENER_ARN" >> $GITHUB_OUTPUT - - TARGET_GROUP_ARN=$(terraform output -raw target_group_arn) - echo "TARGET_GROUP_ARN=$TARGET_GROUP_ARN" >> $GITHUB_OUTPUT - - API_INVOKE_URL=$(terraform output -raw api_invoke_url) - echo "API_INVOKE_URL=$API_INVOKE_URL" >> $GITHUB_OUTPUT - - PRIVATE_VPC_ID=$(terraform output -raw private_vpc_id) - echo "PRIVATE_VPC_ID=$PRIVATE_VPC_ID" >> $GITHUB_OUTPUT - - PRIVATE_SUBNET_IDS=$(terraform output -json private_subnet_ids) - echo "PRIVATE_SUBNET_IDS=$PRIVATE_SUBNET_IDS" >> $GITHUB_OUTPUT - - task: needs: build runs-on: ubuntu-latest outputs: task_definition_arn: ${{ steps.set-envs.outputs.TASK_DEFINITION_ARN }} image_uri: ${{ steps.set-envs.outputs.IMAGE_URI }} - cloudwatch_log_group: ${{ steps.set-envs.outputs.CLOUDWATCH_LOG_GROUP }} steps: - uses: actions/checkout@v4 - name: Configure AWS Credentials @@ -151,24 +93,17 @@ jobs: IMAGE_URI=$(terraform output -raw image_uri) echo "IMAGE_URI=$IMAGE_URI" >> $GITHUB_OUTPUT - CLOUDWATCH_LOG_GROUP=$(terraform output -raw cloudwatch_log_group) - echo "CLOUDWATCH_LOG_GROUP=$CLOUDWATCH_LOG_GROUP" >> $GITHUB_OUTPUT - service: needs: - build - task - - network runs-on: ubuntu-latest env: TF_VAR_task_definition_arn: ${{ needs.task.outputs.task_definition_arn }} - TF_VAR_private_vpc_id: ${{ needs.network.outputs.private_vpc_id }} - TF_VAR_private_subnet_ids: ${{ needs.network.outputs.private_subnet_ids }} - TF_VAR_lb_target_group_arn: ${{ needs.network.outputs.target_group_arn }} - TF_VAR_load_balancer_security_group_id: ${{ needs.network.outputs.lb_security_group_id }} outputs: cluster_name: ${{ steps.set-envs.outputs.CLUSTER_NAME }} service_name: ${{ steps.set-envs.outputs.SERVICE_NAME }} + lb_listener_arn: ${{ steps.set-envs.outputs.LB_LISTENER_ARN }} steps: - uses: actions/checkout@v4 - name: Configure AWS Credentials @@ -203,81 +138,123 @@ jobs: SERVICE_NAME=$(terraform output -raw service_name) echo "SERVICE_NAME=$SERVICE_NAME" >> $GITHUB_OUTPUT - check_image: - needs: - - task - - service + LB_LISTENER_ARN=$(terraform output -raw lb_listener_arn) + echo "LB_LISTENER_ARN=$LB_LISTENER_ARN" >> $GITHUB_OUTPUT + + + network: + needs: service runs-on: ubuntu-latest + env: + TF_VAR_load_balancer_listener_arn: ${{ needs.service.outputs.lb_listener_arn }} + outputs: + api_invoke_url: ${{ steps.set-envs.outputs.API_INVOKE_URL }} steps: + - uses: actions/checkout@v4 - name: Configure AWS Credentials uses: aws-actions/configure-aws-credentials@v4 with: - aws-region: ${{ env.aws_region }} - role-to-assume: arn:aws:iam::${{ env.aws_account_id }}:role/${{ env.aws_role }} - role-session-name: GitHubActions + aws-region: ${{ env.aws_region }} + role-to-assume: arn:aws:iam::${{ env.aws_account_id }}:role/${{ env.aws_role }} + role-session-name: GitHubActions - - name: Get current task definition - id: task-def + - name: Init shell: bash run: | - TASK_DEF_ARN=$(aws ecs describe-services \ - --cluster ${{ needs.service.outputs.cluster_name }} \ - --services ${{ needs.service.outputs.service_name }} \ - --region ${{ env.aws_region }} \ - --query 'services[0].taskDefinition' \ - --output text) - echo "TASK_DEF_ARN=$TASK_DEF_ARN" >> $GITHUB_ENV - - - name: Get image from task definition - id: check-image + cd tf/network + terraform init + + - name: Deploy shell: bash + id: deploy run: | - CURRENT_IMAGE=$(aws ecs describe-task-definition \ - --task-definition ${{ env.TASK_DEF_ARN }} \ - --region ${{ env.aws_region }} \ - --query 'taskDefinition.containerDefinitions[*].image' \ - --output text) - echo "CURRENT_IMAGE=$CURRENT_IMAGE" - echo "CURRENT_IMAGE=$CURRENT_IMAGE" >> $GITHUB_ENV + cd tf/network + terraform apply -auto-approve - - name: Compare with Terraform image - id: compare + - name: Set env vars + id: set-envs + shell: bash run: | - if [ "${{ env.CURRENT_IMAGE }}" != "${{ needs.task.outputs.image_uri }}" ]; then - echo "ERROR: Image mismatch! Current image: ${{ env.CURRENT_IMAGE }}, Expected: ${{ needs.task.outputs.image_uri }}" - exit 1 - else - echo "Image matched: ${{ env.CURRENT_IMAGE }}" - fi + cd tf/network - check_response: - needs: - - network - - service - runs-on: ubuntu-latest - steps: - - name: Make API request - id: curl_request - run: | - RESPONSE=$(curl -s ${{ needs.network.outputs.api_invoke_url}}/host) - echo "Response: $RESPONSE" - echo "$RESPONSE" | jq + API_INVOKE_URL=$(terraform output -raw api_invoke_url) + echo "API_INVOKE_URL=$API_INVOKE_URL" >> $GITHUB_OUTPUT + + # check_image: + # needs: + # - task + # - service + # runs-on: ubuntu-latest + # steps: + # - name: Configure AWS Credentials + # uses: aws-actions/configure-aws-credentials@v4 + # with: + # aws-region: ${{ env.aws_region }} + # role-to-assume: arn:aws:iam::${{ env.aws_account_id }}:role/${{ env.aws_role }} + # role-session-name: GitHubActions + + # - name: Get current task definition + # id: task-def + # shell: bash + # run: | + # TASK_DEF_ARN=$(aws ecs describe-services \ + # --cluster ${{ needs.service.outputs.cluster_name }} \ + # --services ${{ needs.service.outputs.service_name }} \ + # --region ${{ env.aws_region }} \ + # --query 'services[0].taskDefinition' \ + # --output text) + # echo "TASK_DEF_ARN=$TASK_DEF_ARN" >> $GITHUB_ENV + + # - name: Get image from task definition + # id: check-image + # shell: bash + # run: | + # CURRENT_IMAGE=$(aws ecs describe-task-definition \ + # --task-definition ${{ env.TASK_DEF_ARN }} \ + # --region ${{ env.aws_region }} \ + # --query 'taskDefinition.containerDefinitions[*].image' \ + # --output text) + # echo "CURRENT_IMAGE=$CURRENT_IMAGE" + # echo "CURRENT_IMAGE=$CURRENT_IMAGE" >> $GITHUB_ENV + + # - name: Compare with Terraform image + # id: compare + # run: | + # if [ "${{ env.CURRENT_IMAGE }}" != "${{ needs.task.outputs.image_uri }}" ]; then + # echo "ERROR: Image mismatch! Current image: ${{ env.CURRENT_IMAGE }}, Expected: ${{ needs.task.outputs.image_uri }}" + # exit 1 + # else + # echo "Image matched: ${{ env.CURRENT_IMAGE }}" + # fi + + # check_response: + # needs: + # - network + # - service + # runs-on: ubuntu-latest + # steps: + # - name: Make API request + # id: curl_request + # run: | + # RESPONSE=$(curl -s ${{ needs.network.outputs.api_invoke_url}}/host) + # echo "Response: $RESPONSE" + # echo "$RESPONSE" | jq - - name: Assert API response contains expected fields - run: | - RESPONSE=$(curl -s ${{ needs.network.outputs.api_invoke_url}}/host) - echo "$RESPONSE" | jq + # - name: Assert API response contains expected fields + # run: | + # RESPONSE=$(curl -s ${{ needs.network.outputs.api_invoke_url}}/host) + # echo "$RESPONSE" | jq - # Extract values from response - MESSAGE=$(echo "$RESPONSE" | jq -r '.message') - IMAGE_URI=$(echo "$RESPONSE" | jq -r '.imageUri') - HOSTNAME=$(echo "$RESPONSE" | jq -r '.hostname') - - # Check if expected fields exist - if [[ "$MESSAGE" == "null" || "$IMAGE_URI" == "null" || "$HOSTNAME" == "null" ]]; then - echo "Error: Response does not contain expected fields." - exit 1 - else - echo "API response contains all expected fields." - fi + # # Extract values from response + # MESSAGE=$(echo "$RESPONSE" | jq -r '.message') + # IMAGE_URI=$(echo "$RESPONSE" | jq -r '.imageUri') + # HOSTNAME=$(echo "$RESPONSE" | jq -r '.hostname') + + # # Check if expected fields exist + # if [[ "$MESSAGE" == "null" || "$IMAGE_URI" == "null" || "$HOSTNAME" == "null" ]]; then + # echo "Error: Response does not contain expected fields." + # exit 1 + # else + # echo "API response contains all expected fields." + # fi \ No newline at end of file diff --git a/tf/service/outputs.tf b/tf/service/outputs.tf index fbff797..2729673 100644 --- a/tf/service/outputs.tf +++ b/tf/service/outputs.tf @@ -5,3 +5,7 @@ output "cluster_name" { output "service_name" { value = module.ecs.service_name } + +output "listener_arn" { + value = module.load_balancer.listener_arn +} From 94d2e30f0254b793423c244a592a0f4a4ab1a8bc Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Fri, 27 Sep 2024 13:43:04 +0100 Subject: [PATCH 004/116] destroy refactor --- .github/workflows/destroy.yml | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/.github/workflows/destroy.yml b/.github/workflows/destroy.yml index 2be9ddc..b2b870e 100644 --- a/.github/workflows/destroy.yml +++ b/.github/workflows/destroy.yml @@ -14,7 +14,6 @@ env: TF_VAR_private_vpc_name: ecs-private-vpc TF_VAR_api_stage_name: dev TF_VAR_container_port: 3000 - TF_VAR_load_balancer_port: 80 permissions: id-token: write @@ -70,14 +69,10 @@ jobs: cd tf/ecr terraform destroy -auto-approve - service: + network: runs-on: ubuntu-latest env: - TF_VAR_task_definition_arn: "arn:aws:ecs:us-east-1:123456789012:task-definition/dummy-task-definition" - TF_VAR_private_vpc_id: "vpc-12345678" - TF_VAR_private_subnet_ids: '["subnet-12345678", "subnet-87654321"]' - TF_VAR_lb_target_group_arn: "arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/dummy-target-group/1234567890123456" - TF_VAR_load_balancer_security_group_id: "sg-12345678" + TF_VAR_load_balancer_listener_arn: "arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/dummy-target-group/1234567890123456" steps: - uses: actions/checkout@v4 - name: Configure AWS Credentials @@ -90,19 +85,22 @@ jobs: - name: Init shell: bash run: | - cd tf/service + cd tf/network terraform init - name: Destroy shell: bash id: destroy run: | - cd tf/service + cd tf/network terraform destroy -auto-approve + - network: + service: runs-on: ubuntu-latest - needs: service + needs: network + env: + TF_VAR_task_definition_arn: "arn:aws:ecs:us-east-1:123456789012:task-definition/dummy-task-definition" steps: - uses: actions/checkout@v4 - name: Configure AWS Credentials @@ -115,12 +113,12 @@ jobs: - name: Init shell: bash run: | - cd tf/network + cd tf/service terraform init - name: Destroy shell: bash id: destroy run: | - cd tf/network + cd tf/service terraform destroy -auto-approve From 0f47d4fc586e43b361a3e6a16b632032aed2e420 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Fri, 27 Sep 2024 13:47:51 +0100 Subject: [PATCH 005/116] fix --- tf/service/data.tf | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tf/service/data.tf b/tf/service/data.tf index c41e7d8..5b8ee89 100644 --- a/tf/service/data.tf +++ b/tf/service/data.tf @@ -9,8 +9,3 @@ data "aws_subnet" "subnets" { for_each = toset(data.aws_subnets.private.ids) id = each.value } - -data "aws_subnet" "subnets" { - for_each = toset(data.aws_subnets.private.ids) - id = each.value -} \ No newline at end of file From 06f8ba2ada5e4fdc2e02dc0331b9d97cc0b24429 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Fri, 27 Sep 2024 13:51:53 +0100 Subject: [PATCH 006/116] data "aws_subnets" --- tf/service/data.tf | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tf/service/data.tf b/tf/service/data.tf index 5b8ee89..5821cc3 100644 --- a/tf/service/data.tf +++ b/tf/service/data.tf @@ -5,6 +5,13 @@ data "aws_vpc" "private" { } } +data "aws_subnets" "private" { + filter { + name = "vpc-id" + values = [data.aws_vpc.private.id] + } +} + data "aws_subnet" "subnets" { for_each = toset(data.aws_subnets.private.ids) id = each.value From 88ca09f6a88bb8317009836ee1d4183a12c8c74a Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Fri, 27 Sep 2024 13:55:30 +0100 Subject: [PATCH 007/116] short name --- tf/service/load_balancer/main.tf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tf/service/load_balancer/main.tf b/tf/service/load_balancer/main.tf index 771e74e..18da06b 100644 --- a/tf/service/load_balancer/main.tf +++ b/tf/service/load_balancer/main.tf @@ -31,7 +31,7 @@ resource "aws_lb" "lb" { } resource "aws_lb_target_group" "tg_blue" { - name = "${var.project_name}-tg-blue" + name = "tg-blue" port = var.container_port protocol = "HTTP" vpc_id = var.private_vpc_id @@ -50,7 +50,7 @@ resource "aws_lb_target_group" "tg_blue" { } resource "aws_lb_target_group" "tg_green" { - name = "${var.project_name}-tg-green" + name = "tg-green" port = var.container_port protocol = "HTTP" vpc_id = var.private_vpc_id From 12211a819c0a845d2716ffc619d41d191b7612fd Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Fri, 27 Sep 2024 14:15:06 +0100 Subject: [PATCH 008/116] rm load_balancer_port var --- tf/network/variables.tf | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tf/network/variables.tf b/tf/network/variables.tf index 0dc5696..92b5e99 100644 --- a/tf/network/variables.tf +++ b/tf/network/variables.tf @@ -10,10 +10,6 @@ variable "container_port" { type = number } -variable "load_balancer_port" { - type = number -} - variable "api_stage_name" { type = string } From b6a8be8f058eefde8b164f034119e631258a516e Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Fri, 27 Sep 2024 14:29:08 +0100 Subject: [PATCH 009/116] mv vpc endpoint to /ecr --- tf/ecr/data.tf | 20 ++++++++++++++++++++ tf/ecr/locals.tf | 12 ++++++++++++ tf/ecr/main.tf | 37 +++++++++++++++++++++++++++++++++++++ tf/ecr/variables.tf | 6 ++++-- tf/network/locals.tf | 2 -- tf/network/main.tf | 37 ------------------------------------- 6 files changed, 73 insertions(+), 41 deletions(-) create mode 100644 tf/ecr/data.tf create mode 100644 tf/ecr/locals.tf diff --git a/tf/ecr/data.tf b/tf/ecr/data.tf new file mode 100644 index 0000000..e5879be --- /dev/null +++ b/tf/ecr/data.tf @@ -0,0 +1,20 @@ +data "aws_vpc" "private" { + filter { + name = "tag:Name" + values = [var.private_vpc_name] + } +} + +data "aws_subnets" "private" { + filter { + name = "vpc-id" + values = [data.aws_vpc.private.id] + } +} + +data "aws_route_tables" "subnet_route_tables" { + filter { + name = "association.subnet-id" + values = data.aws_subnets.private.ids + } +} diff --git a/tf/ecr/locals.tf b/tf/ecr/locals.tf new file mode 100644 index 0000000..9796b83 --- /dev/null +++ b/tf/ecr/locals.tf @@ -0,0 +1,12 @@ +locals { + aws_service_port = 443 + interface_endpoints = { + ecr_api = "ecr.api" + ecr_dkr = "ecr.dkr" + logs = "logs" + } + private_vpc_id = data.aws_vpc.private.id + private_vpc_cidr_block = data.aws_vpc.private.cidr_block + private_subnet_ids = data.aws_subnets.private.ids + subnet_route_table_ids = data.aws_route_tables.subnet_route_tables.ids +} \ No newline at end of file diff --git a/tf/ecr/main.tf b/tf/ecr/main.tf index e4be931..b46a239 100644 --- a/tf/ecr/main.tf +++ b/tf/ecr/main.tf @@ -1,3 +1,40 @@ +resource "aws_security_group" "vpc_endpoint" { + name = "${var.project_name}-vpc-endpoint-sg" + description = "Security group for VPC endpoints" + vpc_id = local.private_vpc_id + + ingress { + from_port = local.aws_service_port + to_port = local.aws_service_port + protocol = "tcp" + cidr_blocks = [local.private_vpc_cidr_block] + } + + egress { + from_port = local.aws_service_port + to_port = local.aws_service_port + protocol = "tcp" + cidr_blocks = [local.private_vpc_cidr_block] + } +} + +resource "aws_vpc_endpoint" "interface_endpoints" { + for_each = local.interface_endpoints + vpc_id = local.private_vpc_id + service_name = "com.amazonaws.${var.region}.${each.value}" + vpc_endpoint_type = "Interface" + security_group_ids = [aws_security_group.vpc_endpoint.id] + subnet_ids = local.private_subnet_ids + private_dns_enabled = true +} + +resource "aws_vpc_endpoint" "gateway_s3" { + vpc_id = local.private_vpc_id + service_name = "com.amazonaws.${var.region}.s3" + vpc_endpoint_type = "Gateway" + route_table_ids = local.subnet_route_table_ids +} + resource "aws_ecr_repository" "this" { name = var.project_name image_tag_mutability = "MUTABLE" diff --git a/tf/ecr/variables.tf b/tf/ecr/variables.tf index 2e3108b..2de7b29 100644 --- a/tf/ecr/variables.tf +++ b/tf/ecr/variables.tf @@ -1,9 +1,11 @@ variable "project_name" { type = string - default = "fargate-auto-scaled-backend" } variable "region" { type = string - default = "eu-west-2" +} + +variable "private_vpc_name" { + type = string } diff --git a/tf/network/locals.tf b/tf/network/locals.tf index 2cd91fe..3ab6851 100644 --- a/tf/network/locals.tf +++ b/tf/network/locals.tf @@ -5,8 +5,6 @@ locals { logs = "logs" } private_vpc_id = data.aws_vpc.private.id - private_vpc_cidr_block = data.aws_vpc.private.cidr_block private_subnet_ids = data.aws_subnets.private.ids private_subnet_cidrs = [for s in data.aws_subnet.subnets : s.cidr_block] - subnet_route_table_ids = data.aws_route_tables.subnet_route_tables.ids } \ No newline at end of file diff --git a/tf/network/main.tf b/tf/network/main.tf index 1780ced..c739d1c 100644 --- a/tf/network/main.tf +++ b/tf/network/main.tf @@ -1,40 +1,3 @@ -resource "aws_security_group" "vpc_endpoint" { - name = "${var.project_name}-vpc-endpoint-sg" - description = "Security group for VPC endpoints" - vpc_id = local.private_vpc_id - - ingress { - from_port = 443 - to_port = 443 - protocol = "tcp" - cidr_blocks = [local.private_vpc_cidr_block] - } - - egress { - from_port = 443 - to_port = 443 - protocol = "tcp" - cidr_blocks = [local.private_vpc_cidr_block] - } -} - -resource "aws_vpc_endpoint" "interface_endpoints" { - for_each = local.interface_endpoints - vpc_id = local.private_vpc_id - service_name = "com.amazonaws.${var.region}.${each.value}" - vpc_endpoint_type = "Interface" - security_group_ids = [aws_security_group.vpc_endpoint.id] - subnet_ids = local.private_subnet_ids - private_dns_enabled = true -} - -resource "aws_vpc_endpoint" "gateway_s3" { - vpc_id = local.private_vpc_id - service_name = "com.amazonaws.${var.region}.s3" - vpc_endpoint_type = "Gateway" - route_table_ids = local.subnet_route_table_ids -} - resource "aws_security_group" "api_gateway_vpc_link" { name = "${var.project_name}-api-gateway-vpc-link-sg" description = "Security group for API Gateway VPC link" From 65493cc11820c4a0b9834d6eb2fdc88acd82b382 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Fri, 27 Sep 2024 14:29:23 +0100 Subject: [PATCH 010/116] fmt --- tf/ecr/locals.tf | 20 ++++++++++---------- tf/ecr/variables.tf | 4 ++-- tf/network/locals.tf | 6 +++--- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/tf/ecr/locals.tf b/tf/ecr/locals.tf index 9796b83..41a7e00 100644 --- a/tf/ecr/locals.tf +++ b/tf/ecr/locals.tf @@ -1,12 +1,12 @@ locals { - aws_service_port = 443 - interface_endpoints = { - ecr_api = "ecr.api" - ecr_dkr = "ecr.dkr" - logs = "logs" - } - private_vpc_id = data.aws_vpc.private.id - private_vpc_cidr_block = data.aws_vpc.private.cidr_block - private_subnet_ids = data.aws_subnets.private.ids - subnet_route_table_ids = data.aws_route_tables.subnet_route_tables.ids + aws_service_port = 443 + interface_endpoints = { + ecr_api = "ecr.api" + ecr_dkr = "ecr.dkr" + logs = "logs" + } + private_vpc_id = data.aws_vpc.private.id + private_vpc_cidr_block = data.aws_vpc.private.cidr_block + private_subnet_ids = data.aws_subnets.private.ids + subnet_route_table_ids = data.aws_route_tables.subnet_route_tables.ids } \ No newline at end of file diff --git a/tf/ecr/variables.tf b/tf/ecr/variables.tf index 2de7b29..660f0f5 100644 --- a/tf/ecr/variables.tf +++ b/tf/ecr/variables.tf @@ -1,9 +1,9 @@ variable "project_name" { - type = string + type = string } variable "region" { - type = string + type = string } variable "private_vpc_name" { diff --git a/tf/network/locals.tf b/tf/network/locals.tf index 3ab6851..479668c 100644 --- a/tf/network/locals.tf +++ b/tf/network/locals.tf @@ -4,7 +4,7 @@ locals { ecr_dkr = "ecr.dkr" logs = "logs" } - private_vpc_id = data.aws_vpc.private.id - private_subnet_ids = data.aws_subnets.private.ids - private_subnet_cidrs = [for s in data.aws_subnet.subnets : s.cidr_block] + private_vpc_id = data.aws_vpc.private.id + private_subnet_ids = data.aws_subnets.private.ids + private_subnet_cidrs = [for s in data.aws_subnet.subnets : s.cidr_block] } \ No newline at end of file From a911f423d13c19d930dd1e9a876da1d06aa2c4e8 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Fri, 27 Sep 2024 14:39:38 +0100 Subject: [PATCH 011/116] type = "CODE_DEPLOY" --- tf/service/ecs/main.tf | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/tf/service/ecs/main.tf b/tf/service/ecs/main.tf index e78a79e..21543da 100644 --- a/tf/service/ecs/main.tf +++ b/tf/service/ecs/main.tf @@ -23,20 +23,14 @@ resource "aws_security_group" "ecs_sg" { } resource "aws_ecs_service" "ecs" { - name = var.project_name - launch_type = "FARGATE" - cluster = aws_ecs_cluster.cluster.id - task_definition = var.task_definition_arn - desired_count = var.initial_task_count - wait_for_steady_state = true - - deployment_circuit_breaker { - enable = true - rollback = true - } + name = var.project_name + launch_type = "FARGATE" + cluster = aws_ecs_cluster.cluster.id + task_definition = var.task_definition_arn + desired_count = var.initial_task_count deployment_controller { - type = "ECS" + type = "CODE_DEPLOY" } network_configuration { @@ -51,12 +45,16 @@ resource "aws_ecs_service" "ecs" { container_port = var.container_port } - # Auto-rollback and rolling deployment settings - deployment_minimum_healthy_percent = 50 # 50% of tasks must remain healthy during deployment - deployment_maximum_percent = 200 # Can scale up to 200% during the deployment process - # Health check grace period (in seconds) for the new tasks health_check_grace_period_seconds = 60 + # Rolling deployment settings for ECS + deployment_minimum_healthy_percent = 50 # 50% of tasks must remain healthy during deployment + deployment_maximum_percent = 200 # Can scale up to 200% during the deployment process + + # Disable force new deployment because CodeDeploy will handle it force_new_deployment = false + + # Disable wait for steady state when using CodeDeploy + wait_for_steady_state = false } From c101c908315b2ddb9b0c9ba961e025f78a9dbbf7 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Fri, 27 Sep 2024 14:50:55 +0100 Subject: [PATCH 012/116] lb_ to output arn --- tf/service/outputs.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tf/service/outputs.tf b/tf/service/outputs.tf index 2729673..2bb0eaf 100644 --- a/tf/service/outputs.tf +++ b/tf/service/outputs.tf @@ -6,6 +6,6 @@ output "service_name" { value = module.ecs.service_name } -output "listener_arn" { +output "lb_listener_arn" { value = module.load_balancer.listener_arn } From 35bbb9e183ebe4ecf7dcd019a1785b04eb6bfe7e Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Fri, 27 Sep 2024 14:58:52 +0100 Subject: [PATCH 013/116] add checks --- .github/workflows/deploy.yml | 140 +++++++++++++++++------------------ 1 file changed, 70 insertions(+), 70 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 8222310..ecfe84d 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -180,81 +180,81 @@ jobs: API_INVOKE_URL=$(terraform output -raw api_invoke_url) echo "API_INVOKE_URL=$API_INVOKE_URL" >> $GITHUB_OUTPUT - # check_image: - # needs: - # - task - # - service - # runs-on: ubuntu-latest - # steps: - # - name: Configure AWS Credentials - # uses: aws-actions/configure-aws-credentials@v4 - # with: - # aws-region: ${{ env.aws_region }} - # role-to-assume: arn:aws:iam::${{ env.aws_account_id }}:role/${{ env.aws_role }} - # role-session-name: GitHubActions + check_image: + needs: + - task + - service + runs-on: ubuntu-latest + steps: + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + aws-region: ${{ env.aws_region }} + role-to-assume: arn:aws:iam::${{ env.aws_account_id }}:role/${{ env.aws_role }} + role-session-name: GitHubActions - # - name: Get current task definition - # id: task-def - # shell: bash - # run: | - # TASK_DEF_ARN=$(aws ecs describe-services \ - # --cluster ${{ needs.service.outputs.cluster_name }} \ - # --services ${{ needs.service.outputs.service_name }} \ - # --region ${{ env.aws_region }} \ - # --query 'services[0].taskDefinition' \ - # --output text) - # echo "TASK_DEF_ARN=$TASK_DEF_ARN" >> $GITHUB_ENV + - name: Get current task definition + id: task-def + shell: bash + run: | + TASK_DEF_ARN=$(aws ecs describe-services \ + --cluster ${{ needs.service.outputs.cluster_name }} \ + --services ${{ needs.service.outputs.service_name }} \ + --region ${{ env.aws_region }} \ + --query 'services[0].taskDefinition' \ + --output text) + echo "TASK_DEF_ARN=$TASK_DEF_ARN" >> $GITHUB_ENV - # - name: Get image from task definition - # id: check-image - # shell: bash - # run: | - # CURRENT_IMAGE=$(aws ecs describe-task-definition \ - # --task-definition ${{ env.TASK_DEF_ARN }} \ - # --region ${{ env.aws_region }} \ - # --query 'taskDefinition.containerDefinitions[*].image' \ - # --output text) - # echo "CURRENT_IMAGE=$CURRENT_IMAGE" - # echo "CURRENT_IMAGE=$CURRENT_IMAGE" >> $GITHUB_ENV + - name: Get image from task definition + id: check-image + shell: bash + run: | + CURRENT_IMAGE=$(aws ecs describe-task-definition \ + --task-definition ${{ env.TASK_DEF_ARN }} \ + --region ${{ env.aws_region }} \ + --query 'taskDefinition.containerDefinitions[*].image' \ + --output text) + echo "CURRENT_IMAGE=$CURRENT_IMAGE" + echo "CURRENT_IMAGE=$CURRENT_IMAGE" >> $GITHUB_ENV - # - name: Compare with Terraform image - # id: compare - # run: | - # if [ "${{ env.CURRENT_IMAGE }}" != "${{ needs.task.outputs.image_uri }}" ]; then - # echo "ERROR: Image mismatch! Current image: ${{ env.CURRENT_IMAGE }}, Expected: ${{ needs.task.outputs.image_uri }}" - # exit 1 - # else - # echo "Image matched: ${{ env.CURRENT_IMAGE }}" - # fi + - name: Compare with Terraform image + id: compare + run: | + if [ "${{ env.CURRENT_IMAGE }}" != "${{ needs.task.outputs.image_uri }}" ]; then + echo "ERROR: Image mismatch! Current image: ${{ env.CURRENT_IMAGE }}, Expected: ${{ needs.task.outputs.image_uri }}" + exit 1 + else + echo "Image matched: ${{ env.CURRENT_IMAGE }}" + fi - # check_response: - # needs: - # - network - # - service - # runs-on: ubuntu-latest - # steps: - # - name: Make API request - # id: curl_request - # run: | - # RESPONSE=$(curl -s ${{ needs.network.outputs.api_invoke_url}}/host) - # echo "Response: $RESPONSE" - # echo "$RESPONSE" | jq + check_response: + needs: + - network + - service + runs-on: ubuntu-latest + steps: + - name: Make API request + id: curl_request + run: | + RESPONSE=$(curl -s ${{ needs.network.outputs.api_invoke_url}}/host) + echo "Response: $RESPONSE" + echo "$RESPONSE" | jq - # - name: Assert API response contains expected fields - # run: | - # RESPONSE=$(curl -s ${{ needs.network.outputs.api_invoke_url}}/host) - # echo "$RESPONSE" | jq + - name: Assert API response contains expected fields + run: | + RESPONSE=$(curl -s ${{ needs.network.outputs.api_invoke_url}}/host) + echo "$RESPONSE" | jq - # # Extract values from response - # MESSAGE=$(echo "$RESPONSE" | jq -r '.message') - # IMAGE_URI=$(echo "$RESPONSE" | jq -r '.imageUri') - # HOSTNAME=$(echo "$RESPONSE" | jq -r '.hostname') + # Extract values from response + MESSAGE=$(echo "$RESPONSE" | jq -r '.message') + IMAGE_URI=$(echo "$RESPONSE" | jq -r '.imageUri') + HOSTNAME=$(echo "$RESPONSE" | jq -r '.hostname') - # # Check if expected fields exist - # if [[ "$MESSAGE" == "null" || "$IMAGE_URI" == "null" || "$HOSTNAME" == "null" ]]; then - # echo "Error: Response does not contain expected fields." - # exit 1 - # else - # echo "API response contains all expected fields." - # fi + # Check if expected fields exist + if [[ "$MESSAGE" == "null" || "$IMAGE_URI" == "null" || "$HOSTNAME" == "null" ]]; then + echo "Error: Response does not contain expected fields." + exit 1 + else + echo "API response contains all expected fields." + fi \ No newline at end of file From 0bba2cfa5930794158a00107b05415f097727c59 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Fri, 27 Sep 2024 15:03:43 +0100 Subject: [PATCH 014/116] test change --- src/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app.js b/src/app.js index 8d9f726..936e337 100644 --- a/src/app.js +++ b/src/app.js @@ -29,4 +29,4 @@ app.get(`/${basePath}/host`, (req, res) => { }); }); -console.log(`Listening on http://localhost:${port}`) \ No newline at end of file +console.log(`Listening on http://localhost:${port}`) From 2aa528e096db1d24a375394ca404035922fcfd64 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Fri, 27 Sep 2024 15:50:03 +0100 Subject: [PATCH 015/116] pass in image tag --- .github/actions/build_image/action.yml | 17 +++++++++++++++-- tf/task/data.tf | 2 +- tf/task/variables.tf | 4 ++++ 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/.github/actions/build_image/action.yml b/.github/actions/build_image/action.yml index 4e0528d..cd1f83f 100644 --- a/.github/actions/build_image/action.yml +++ b/.github/actions/build_image/action.yml @@ -9,6 +9,12 @@ inputs: description: 'ECR aws region' required: true +outputs: + new_build: + description: 'Boolean value indicating if a new build has been pushed' + image_uri: + description: 'The URI of the pushed Docker image' + runs: using: 'composite' steps: @@ -20,7 +26,7 @@ runs: - 'src/**' - name: Check if ECR repository is empty - id: should_build + id: check_should_build shell: bash run: | IMAGE_COUNT=$(aws ecr describe-images --repository-name ${{ github.event.repository.name }} --region ${{ inputs.aws_region }} --query 'imageDetails | length(@)' --output text) @@ -32,6 +38,7 @@ runs: echo "Neither src changed nor ECR is empty" echo "SHOULD_BUILD=false" >> $GITHUB_ENV fi + echo "::set-output name=new_build::${{ env.SHOULD_BUILD }}" - if: env.SHOULD_BUILD == 'true' name: Checkout code @@ -57,5 +64,11 @@ runs: name: Push Docker Image to ECR shell: bash run: | - aws ecr get-login-password --region ${{ env.aws_region }} | docker login --username AWS --password-stdin ${{ inputs.AWS_ACCOUNT_ID }}.dkr.ecr.${{ inputs.aws_region }}.amazonaws.com + aws ecr get-login-password --region ${{ inputs.aws_region }} | docker login --username AWS --password-stdin ${{ inputs.aws_account_id }}.dkr.ecr.${{ inputs.aws_region }}.amazonaws.com docker push ${{ inputs.aws_account_id }}.dkr.ecr.${{ inputs.aws_region }}.amazonaws.com/${{ github.event.repository.name }}:$IMAGE_TAG + IMAGE_URI="${{ inputs.aws_account_id }}.dkr.ecr.${{ inputs.aws_region }}.amazonaws.com/${{ github.event.repository.name }}:$IMAGE_TAG" + echo "::set-output name=image_uri::$IMAGE_URI" + +outputs: + new_build: ${{ steps.check_should_build.outputs.should_build }} + image_uri: ${{ steps.push.outputs.image_uri }} diff --git a/tf/task/data.tf b/tf/task/data.tf index ce5c637..94b7c71 100644 --- a/tf/task/data.tf +++ b/tf/task/data.tf @@ -4,7 +4,7 @@ data "aws_ecr_repository" "this" { data "aws_ecr_image" "this" { repository_name = data.aws_ecr_repository.this.name - most_recent = true + image_tag = var.image_tag } data "aws_iam_policy_document" "assume_role" { diff --git a/tf/task/variables.tf b/tf/task/variables.tf index 0d1d778..ef93630 100644 --- a/tf/task/variables.tf +++ b/tf/task/variables.tf @@ -14,6 +14,10 @@ variable "container_port" { type = number } +variable "image_tag" { + type = string +} + variable "cpu" { type = number default = 256 From 471de683a1ae53f76d1afb18395dafc37617e84f Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Fri, 27 Sep 2024 16:21:44 +0100 Subject: [PATCH 016/116] build.yml --- .github/actions/build_image/action.yml | 16 ++-- .github/workflows/build.yml | 100 +++++++++++++++++++++++++ 2 files changed, 111 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/build.yml diff --git a/.github/actions/build_image/action.yml b/.github/actions/build_image/action.yml index cd1f83f..e9df10f 100644 --- a/.github/actions/build_image/action.yml +++ b/.github/actions/build_image/action.yml @@ -10,10 +10,8 @@ inputs: required: true outputs: - new_build: - description: 'Boolean value indicating if a new build has been pushed' image_uri: - description: 'The URI of the pushed Docker image' + description: 'The URI of the pushed ECR image' runs: using: 'composite' @@ -38,7 +36,6 @@ runs: echo "Neither src changed nor ECR is empty" echo "SHOULD_BUILD=false" >> $GITHUB_ENV fi - echo "::set-output name=new_build::${{ env.SHOULD_BUILD }}" - if: env.SHOULD_BUILD == 'true' name: Checkout code @@ -69,6 +66,15 @@ runs: IMAGE_URI="${{ inputs.aws_account_id }}.dkr.ecr.${{ inputs.aws_region }}.amazonaws.com/${{ github.event.repository.name }}:$IMAGE_TAG" echo "::set-output name=image_uri::$IMAGE_URI" + - if: env.SHOULD_BUILD != 'true' + name: Get Latest ECR Image Tag + shell: bash + run: | + LATEST_TAG=$(aws ecr describe-images --repository-name ${{ github.event.repository.name }} \ + --region ${{ inputs.aws_region }} --query 'sort_by(imageDetails,& imagePushedAt)[-1].imageTags[0]' --output text) + IMAGE_URI="${{ inputs.aws_account_id }}.dkr.ecr.${{ inputs.aws_region }}.amazonaws.com/${{ github.event.repository.name }}:$LATEST_TAG" + echo "IMAGE_URI=$IMAGE_URI" >> $GITHUB_ENV + echo "::set-output name=image_uri::$IMAGE_URI" + outputs: - new_build: ${{ steps.check_should_build.outputs.should_build }} image_uri: ${{ steps.push.outputs.image_uri }} diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..9e47862 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,100 @@ +name: Setup + +on: + workflow_dispatch: + +env: + aws_account_id: ${{ vars.AWS_ACCOUNT_ID }} + aws_region: ${{ vars.AWS_REGION }} + aws_role: ${{ vars.AWS_ROLE }} + + TF_VAR_project_name: ${{ github.event.repository.name }} + TF_VAR_region: ${{ vars.AWS_REGION }} + TF_VAR_private_vpc_name: ecs-private-vpc + TF_VAR_api_stage_name: dev + TF_VAR_container_port: 3000 + +permissions: + id-token: write + contents: read + +jobs: + ecr: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: aws-actions/configure-aws-credentials@v4 + with: + aws-region: ${{ env.aws_region }} + role-to-assume: arn:aws:iam::${{ env.aws_account_id }}:role/${{ env.aws_role }} + role-session-name: GitHubActions + + - name: Init + shell: bash + run: | + cd tf/ecr + terraform init + + - name: Deploy + shell: bash + id: deploy + run: | + cd tf/ecr + terraform apply -auto-approve + + build: + runs-on: ubuntu-latest + needs: ecr + steps: + - uses: actions/checkout@v4 + - uses: aws-actions/configure-aws-credentials@v4 + with: + aws-region: ${{ env.aws_region }} + role-to-assume: arn:aws:iam::${{ env.aws_account_id }}:role/${{ env.aws_role }} + role-session-name: GitHubActions + + - name: Build and push detected changes + id: build-image + uses: ./.github/actions/build_image + with: + aws_account_id: ${{ vars.AWS_ACCOUNT_ID }} + aws_region: ${{ vars.AWS_REGION }} + + task: + needs: build + runs-on: ubuntu-latest + outputs: + task_definition_arn: ${{ steps.set-envs.outputs.TASK_DEFINITION_ARN }} + image_uri: ${{ steps.set-envs.outputs.IMAGE_URI }} + steps: + - uses: actions/checkout@v4 + - uses: aws-actions/configure-aws-credentials@v4 + with: + aws-region: ${{ env.aws_region }} + role-to-assume: arn:aws:iam::${{ env.aws_account_id }}:role/${{ env.aws_role }} + role-session-name: GitHubActions + + - name: Init + shell: bash + run: | + cd tf/task + terraform init + + - name: Deploy + shell: bash + id: deploy + run: | + cd tf/task + terraform apply -auto-approve + + - name: Set env vars + id: set-envs + shell: bash + run: | + cd tf/task + + TASK_DEFINITION_ARN=$(terraform output -raw task_definition_arn) + echo "TASK_DEFINITION_ARN=$TASK_DEFINITION_ARN" >> $GITHUB_OUTPUT + + IMAGE_URI=$(terraform output -raw image_uri) + echo "IMAGE_URI=$IMAGE_URI" >> $GITHUB_OUTPUT From 9c2f1e534fd947d4c25f3d089d50f5474e53cbc0 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Fri, 27 Sep 2024 16:39:27 +0100 Subject: [PATCH 017/116] rename --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9e47862..fff94e2 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,4 +1,4 @@ -name: Setup +name: Build on: workflow_dispatch: From 01f36f66882542c40df8b5a0c3d38a0234dfa7bd Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Fri, 27 Sep 2024 16:43:09 +0100 Subject: [PATCH 018/116] rm trigger --- .github/workflows/deploy.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index ecfe84d..df5b4a1 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -1,9 +1,6 @@ name: Deploy on: - push: - branches: - - main workflow_dispatch: env: From 025daa43d48a8aad05b150be34c6c8fb9e31a002 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Fri, 27 Sep 2024 16:45:10 +0100 Subject: [PATCH 019/116] trigger on this branch --- .github/workflows/build.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fff94e2..c03817c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,6 +1,9 @@ name: Build on: + push: + branches: + - 'blue-green-deploy' workflow_dispatch: env: From ba27088cafa4f63dffb91ff54163912a7b78e5ed Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Fri, 27 Sep 2024 16:48:11 +0100 Subject: [PATCH 020/116] fix --- .github/actions/build_image/action.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/actions/build_image/action.yml b/.github/actions/build_image/action.yml index e9df10f..8e1b1d3 100644 --- a/.github/actions/build_image/action.yml +++ b/.github/actions/build_image/action.yml @@ -75,6 +75,3 @@ runs: IMAGE_URI="${{ inputs.aws_account_id }}.dkr.ecr.${{ inputs.aws_region }}.amazonaws.com/${{ github.event.repository.name }}:$LATEST_TAG" echo "IMAGE_URI=$IMAGE_URI" >> $GITHUB_ENV echo "::set-output name=image_uri::$IMAGE_URI" - -outputs: - image_uri: ${{ steps.push.outputs.image_uri }} From d83a90987d196bff7ceea1d6c5d353c0c3a43be4 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Fri, 27 Sep 2024 16:53:21 +0100 Subject: [PATCH 021/116] more fixes --- .github/actions/build_image/action.yml | 5 ++--- tf/task/data.tf | 9 --------- tf/task/locals.tf | 3 +-- tf/task/outputs.tf | 4 ---- tf/task/variables.tf | 2 +- 5 files changed, 4 insertions(+), 19 deletions(-) diff --git a/.github/actions/build_image/action.yml b/.github/actions/build_image/action.yml index 8e1b1d3..e7b9e4b 100644 --- a/.github/actions/build_image/action.yml +++ b/.github/actions/build_image/action.yml @@ -64,7 +64,7 @@ runs: aws ecr get-login-password --region ${{ inputs.aws_region }} | docker login --username AWS --password-stdin ${{ inputs.aws_account_id }}.dkr.ecr.${{ inputs.aws_region }}.amazonaws.com docker push ${{ inputs.aws_account_id }}.dkr.ecr.${{ inputs.aws_region }}.amazonaws.com/${{ github.event.repository.name }}:$IMAGE_TAG IMAGE_URI="${{ inputs.aws_account_id }}.dkr.ecr.${{ inputs.aws_region }}.amazonaws.com/${{ github.event.repository.name }}:$IMAGE_TAG" - echo "::set-output name=image_uri::$IMAGE_URI" + echo "image_uri=$IMAGE_URI" >> $GITHUB_OUTPUT - if: env.SHOULD_BUILD != 'true' name: Get Latest ECR Image Tag @@ -73,5 +73,4 @@ runs: LATEST_TAG=$(aws ecr describe-images --repository-name ${{ github.event.repository.name }} \ --region ${{ inputs.aws_region }} --query 'sort_by(imageDetails,& imagePushedAt)[-1].imageTags[0]' --output text) IMAGE_URI="${{ inputs.aws_account_id }}.dkr.ecr.${{ inputs.aws_region }}.amazonaws.com/${{ github.event.repository.name }}:$LATEST_TAG" - echo "IMAGE_URI=$IMAGE_URI" >> $GITHUB_ENV - echo "::set-output name=image_uri::$IMAGE_URI" + echo "image_uri=$IMAGE_URI" >> $GITHUB_OUTPUT diff --git a/tf/task/data.tf b/tf/task/data.tf index 94b7c71..0719231 100644 --- a/tf/task/data.tf +++ b/tf/task/data.tf @@ -1,12 +1,3 @@ -data "aws_ecr_repository" "this" { - name = var.project_name -} - -data "aws_ecr_image" "this" { - repository_name = data.aws_ecr_repository.this.name - image_tag = var.image_tag -} - data "aws_iam_policy_document" "assume_role" { statement { effect = "Allow" diff --git a/tf/task/locals.tf b/tf/task/locals.tf index 02a3650..5535c3d 100644 --- a/tf/task/locals.tf +++ b/tf/task/locals.tf @@ -1,10 +1,9 @@ locals { formatted_name = replace(var.project_name, "-", "_") cloudwatch_log_name = "/ecs/${local.formatted_name}" - image_uri = data.aws_ecr_image.this.image_uri container_definitions = templatefile("${path.module}/container_definitions.tpl", { container_name = var.project_name - image_uri = local.image_uri + image_uri = var.image_uri container_port = var.container_port base_path = var.api_stage_name cpu = var.cpu diff --git a/tf/task/outputs.tf b/tf/task/outputs.tf index fcaf686..3964f58 100644 --- a/tf/task/outputs.tf +++ b/tf/task/outputs.tf @@ -2,10 +2,6 @@ output "task_definition_arn" { value = aws_ecs_task_definition.task.arn } -output "image_uri" { - value = local.image_uri -} - output "cloudwatch_log_group" { value = aws_cloudwatch_log_group.ecs_log_group.name } diff --git a/tf/task/variables.tf b/tf/task/variables.tf index ef93630..a845014 100644 --- a/tf/task/variables.tf +++ b/tf/task/variables.tf @@ -14,7 +14,7 @@ variable "container_port" { type = number } -variable "image_tag" { +variable "image_uri" { type = string } From 1553b4037de7e35df1a656f67953157a23a09130 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Fri, 27 Sep 2024 16:58:16 +0100 Subject: [PATCH 022/116] pass image uri --- .github/workflows/build.yml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c03817c..4edaad0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -47,6 +47,8 @@ jobs: build: runs-on: ubuntu-latest + outputs: + image_uri: ${{ steps.build-image.outputs.image_uri }} needs: ecr steps: - uses: actions/checkout@v4 @@ -66,9 +68,10 @@ jobs: task: needs: build runs-on: ubuntu-latest + env: + TF_VAR_image_uri: ${{ needs.build.outputs.image_uri }} outputs: task_definition_arn: ${{ steps.set-envs.outputs.TASK_DEFINITION_ARN }} - image_uri: ${{ steps.set-envs.outputs.IMAGE_URI }} steps: - uses: actions/checkout@v4 - uses: aws-actions/configure-aws-credentials@v4 @@ -95,9 +98,5 @@ jobs: shell: bash run: | cd tf/task - TASK_DEFINITION_ARN=$(terraform output -raw task_definition_arn) echo "TASK_DEFINITION_ARN=$TASK_DEFINITION_ARN" >> $GITHUB_OUTPUT - - IMAGE_URI=$(terraform output -raw image_uri) - echo "IMAGE_URI=$IMAGE_URI" >> $GITHUB_OUTPUT From b5a0effc4d8cd0a587a60486214cc6d5af3fea17 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Fri, 27 Sep 2024 17:02:16 +0100 Subject: [PATCH 023/116] back to tag --- .github/actions/build_image/action.yml | 4 ++++ tf/task/locals.tf | 3 ++- tf/task/variables.tf | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/actions/build_image/action.yml b/.github/actions/build_image/action.yml index e7b9e4b..60748c7 100644 --- a/.github/actions/build_image/action.yml +++ b/.github/actions/build_image/action.yml @@ -10,6 +10,8 @@ inputs: required: true outputs: + image_tag: + description: 'The TAG of the pushed ECR image' image_uri: description: 'The URI of the pushed ECR image' @@ -64,6 +66,7 @@ runs: aws ecr get-login-password --region ${{ inputs.aws_region }} | docker login --username AWS --password-stdin ${{ inputs.aws_account_id }}.dkr.ecr.${{ inputs.aws_region }}.amazonaws.com docker push ${{ inputs.aws_account_id }}.dkr.ecr.${{ inputs.aws_region }}.amazonaws.com/${{ github.event.repository.name }}:$IMAGE_TAG IMAGE_URI="${{ inputs.aws_account_id }}.dkr.ecr.${{ inputs.aws_region }}.amazonaws.com/${{ github.event.repository.name }}:$IMAGE_TAG" + echo "image_tag=$IMAGE_TAG" >> $GITHUB_OUTPUT echo "image_uri=$IMAGE_URI" >> $GITHUB_OUTPUT - if: env.SHOULD_BUILD != 'true' @@ -73,4 +76,5 @@ runs: LATEST_TAG=$(aws ecr describe-images --repository-name ${{ github.event.repository.name }} \ --region ${{ inputs.aws_region }} --query 'sort_by(imageDetails,& imagePushedAt)[-1].imageTags[0]' --output text) IMAGE_URI="${{ inputs.aws_account_id }}.dkr.ecr.${{ inputs.aws_region }}.amazonaws.com/${{ github.event.repository.name }}:$LATEST_TAG" + echo "image_tag=$IMAGE_TAG" >> $GITHUB_OUTPUT echo "image_uri=$IMAGE_URI" >> $GITHUB_OUTPUT diff --git a/tf/task/locals.tf b/tf/task/locals.tf index 5535c3d..02a3650 100644 --- a/tf/task/locals.tf +++ b/tf/task/locals.tf @@ -1,9 +1,10 @@ locals { formatted_name = replace(var.project_name, "-", "_") cloudwatch_log_name = "/ecs/${local.formatted_name}" + image_uri = data.aws_ecr_image.this.image_uri container_definitions = templatefile("${path.module}/container_definitions.tpl", { container_name = var.project_name - image_uri = var.image_uri + image_uri = local.image_uri container_port = var.container_port base_path = var.api_stage_name cpu = var.cpu diff --git a/tf/task/variables.tf b/tf/task/variables.tf index a845014..ef93630 100644 --- a/tf/task/variables.tf +++ b/tf/task/variables.tf @@ -14,7 +14,7 @@ variable "container_port" { type = number } -variable "image_uri" { +variable "image_tag" { type = string } From 4b880d64e3c359b39f4d8c85cf6dfec6c2cdc2fa Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Fri, 27 Sep 2024 17:05:36 +0100 Subject: [PATCH 024/116] fix --- .github/workflows/build.yml | 4 ++-- tf/task/data.tf | 9 +++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4edaad0..dc5b279 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -48,7 +48,7 @@ jobs: build: runs-on: ubuntu-latest outputs: - image_uri: ${{ steps.build-image.outputs.image_uri }} + image_tag: ${{ steps.build-image.outputs.image_tag }} needs: ecr steps: - uses: actions/checkout@v4 @@ -69,7 +69,7 @@ jobs: needs: build runs-on: ubuntu-latest env: - TF_VAR_image_uri: ${{ needs.build.outputs.image_uri }} + TF_VAR_image_tag: ${{ needs.build.outputs.image_tag }} outputs: task_definition_arn: ${{ steps.set-envs.outputs.TASK_DEFINITION_ARN }} steps: diff --git a/tf/task/data.tf b/tf/task/data.tf index 0719231..94b7c71 100644 --- a/tf/task/data.tf +++ b/tf/task/data.tf @@ -1,3 +1,12 @@ +data "aws_ecr_repository" "this" { + name = var.project_name +} + +data "aws_ecr_image" "this" { + repository_name = data.aws_ecr_repository.this.name + image_tag = var.image_tag +} + data "aws_iam_policy_document" "assume_role" { statement { effect = "Allow" From 83367bc7a6c41c828d678ee1f1d6f0850816e75b Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Fri, 27 Sep 2024 17:08:34 +0100 Subject: [PATCH 025/116] most_recent = true --- tf/task/data.tf | 1 + 1 file changed, 1 insertion(+) diff --git a/tf/task/data.tf b/tf/task/data.tf index 94b7c71..bc5959f 100644 --- a/tf/task/data.tf +++ b/tf/task/data.tf @@ -5,6 +5,7 @@ data "aws_ecr_repository" "this" { data "aws_ecr_image" "this" { repository_name = data.aws_ecr_repository.this.name image_tag = var.image_tag + most_recent = true } data "aws_iam_policy_document" "assume_role" { From 768c9f6df366cce5a1de3c4f2a25c983edf172be Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Fri, 27 Sep 2024 17:12:43 +0100 Subject: [PATCH 026/116] baaack to uri --- .github/workflows/build.yml | 4 ++-- tf/task/data.tf | 6 ------ tf/task/locals.tf | 3 +-- tf/task/variables.tf | 2 +- 4 files changed, 4 insertions(+), 11 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index dc5b279..4edaad0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -48,7 +48,7 @@ jobs: build: runs-on: ubuntu-latest outputs: - image_tag: ${{ steps.build-image.outputs.image_tag }} + image_uri: ${{ steps.build-image.outputs.image_uri }} needs: ecr steps: - uses: actions/checkout@v4 @@ -69,7 +69,7 @@ jobs: needs: build runs-on: ubuntu-latest env: - TF_VAR_image_tag: ${{ needs.build.outputs.image_tag }} + TF_VAR_image_uri: ${{ needs.build.outputs.image_uri }} outputs: task_definition_arn: ${{ steps.set-envs.outputs.TASK_DEFINITION_ARN }} steps: diff --git a/tf/task/data.tf b/tf/task/data.tf index bc5959f..3983a4f 100644 --- a/tf/task/data.tf +++ b/tf/task/data.tf @@ -2,12 +2,6 @@ data "aws_ecr_repository" "this" { name = var.project_name } -data "aws_ecr_image" "this" { - repository_name = data.aws_ecr_repository.this.name - image_tag = var.image_tag - most_recent = true -} - data "aws_iam_policy_document" "assume_role" { statement { effect = "Allow" diff --git a/tf/task/locals.tf b/tf/task/locals.tf index 02a3650..5535c3d 100644 --- a/tf/task/locals.tf +++ b/tf/task/locals.tf @@ -1,10 +1,9 @@ locals { formatted_name = replace(var.project_name, "-", "_") cloudwatch_log_name = "/ecs/${local.formatted_name}" - image_uri = data.aws_ecr_image.this.image_uri container_definitions = templatefile("${path.module}/container_definitions.tpl", { container_name = var.project_name - image_uri = local.image_uri + image_uri = var.image_uri container_port = var.container_port base_path = var.api_stage_name cpu = var.cpu diff --git a/tf/task/variables.tf b/tf/task/variables.tf index ef93630..a845014 100644 --- a/tf/task/variables.tf +++ b/tf/task/variables.tf @@ -14,7 +14,7 @@ variable "container_port" { type = number } -variable "image_tag" { +variable "image_uri" { type = string } From 382c43b85606de9dbebd30ff6b1ca1cf4b4c7292 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Fri, 27 Sep 2024 17:16:52 +0100 Subject: [PATCH 027/116] fix --- .github/actions/build_image/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/build_image/action.yml b/.github/actions/build_image/action.yml index 60748c7..c5a9d9d 100644 --- a/.github/actions/build_image/action.yml +++ b/.github/actions/build_image/action.yml @@ -76,5 +76,5 @@ runs: LATEST_TAG=$(aws ecr describe-images --repository-name ${{ github.event.repository.name }} \ --region ${{ inputs.aws_region }} --query 'sort_by(imageDetails,& imagePushedAt)[-1].imageTags[0]' --output text) IMAGE_URI="${{ inputs.aws_account_id }}.dkr.ecr.${{ inputs.aws_region }}.amazonaws.com/${{ github.event.repository.name }}:$LATEST_TAG" - echo "image_tag=$IMAGE_TAG" >> $GITHUB_OUTPUT + echo "image_tag=$LATEST_TAG" >> $GITHUB_OUTPUT echo "image_uri=$IMAGE_URI" >> $GITHUB_OUTPUT From 73782e4899d48c3520ad36b06efa446779770efa Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Fri, 27 Sep 2024 17:21:34 +0100 Subject: [PATCH 028/116] dummy uri --- .github/workflows/destroy.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/destroy.yml b/.github/workflows/destroy.yml index b2b870e..e1e09b7 100644 --- a/.github/workflows/destroy.yml +++ b/.github/workflows/destroy.yml @@ -22,6 +22,8 @@ permissions: jobs: task: runs-on: ubuntu-latest + env: + TF_VAR_image_uri: dummy steps: - uses: actions/checkout@v4 - name: Configure AWS Credentials From 5b763fcc4a359897742d39b78e65c1c00e970539 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Sun, 29 Sep 2024 15:28:19 +0100 Subject: [PATCH 029/116] nudge --- .github/workflows/build.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4edaad0..d449197 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -100,3 +100,5 @@ jobs: cd tf/task TASK_DEFINITION_ARN=$(terraform output -raw task_definition_arn) echo "TASK_DEFINITION_ARN=$TASK_DEFINITION_ARN" >> $GITHUB_OUTPUT + + \ No newline at end of file From 1488ab07595569f36575d83beac2ce661297510d Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Sun, 29 Sep 2024 15:32:44 +0100 Subject: [PATCH 030/116] echo Image:$IMAGE_URI --- .github/actions/build_image/action.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/actions/build_image/action.yml b/.github/actions/build_image/action.yml index c5a9d9d..a457b17 100644 --- a/.github/actions/build_image/action.yml +++ b/.github/actions/build_image/action.yml @@ -68,6 +68,7 @@ runs: IMAGE_URI="${{ inputs.aws_account_id }}.dkr.ecr.${{ inputs.aws_region }}.amazonaws.com/${{ github.event.repository.name }}:$IMAGE_TAG" echo "image_tag=$IMAGE_TAG" >> $GITHUB_OUTPUT echo "image_uri=$IMAGE_URI" >> $GITHUB_OUTPUT + echo Image:$IMAGE_URI - if: env.SHOULD_BUILD != 'true' name: Get Latest ECR Image Tag @@ -78,3 +79,4 @@ runs: IMAGE_URI="${{ inputs.aws_account_id }}.dkr.ecr.${{ inputs.aws_region }}.amazonaws.com/${{ github.event.repository.name }}:$LATEST_TAG" echo "image_tag=$LATEST_TAG" >> $GITHUB_OUTPUT echo "image_uri=$IMAGE_URI" >> $GITHUB_OUTPUT + echo Image:$IMAGE_URI From 1e3ae3dc25fd06032a7771b7b8dcf2704e0a0041 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Sun, 29 Sep 2024 15:39:18 +0100 Subject: [PATCH 031/116] debug --- .github/workflows/build.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d449197..79e26e6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -65,6 +65,9 @@ jobs: aws_account_id: ${{ vars.AWS_ACCOUNT_ID }} aws_region: ${{ vars.AWS_REGION }} + - name: Check image_uri + run: "echo Image URI: ${{ steps.build-image.outputs.image_uri }}" + task: needs: build runs-on: ubuntu-latest From e4c5b70e29d63bd4c311bb56ac456f1b4470055e Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Sun, 29 Sep 2024 15:47:13 +0100 Subject: [PATCH 032/116] chnge action --- .github/actions/build_image/action.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/actions/build_image/action.yml b/.github/actions/build_image/action.yml index a457b17..abafb26 100644 --- a/.github/actions/build_image/action.yml +++ b/.github/actions/build_image/action.yml @@ -9,12 +9,6 @@ inputs: description: 'ECR aws region' required: true -outputs: - image_tag: - description: 'The TAG of the pushed ECR image' - image_uri: - description: 'The URI of the pushed ECR image' - runs: using: 'composite' steps: @@ -80,3 +74,9 @@ runs: echo "image_tag=$LATEST_TAG" >> $GITHUB_OUTPUT echo "image_uri=$IMAGE_URI" >> $GITHUB_OUTPUT echo Image:$IMAGE_URI + +outputs: + image_tag: + description: 'The TAG of the pushed ECR image' + image_uri: + description: 'The URI of the pushed ECR image' From 1392e83eeabfc9a94a64bd2ae7d39fa3db840066 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Sun, 29 Sep 2024 15:54:03 +0100 Subject: [PATCH 033/116] use env --- .github/actions/build_image/action.yml | 14 ++---- .github/workflows/build.yml | 66 +++++++++++++------------- 2 files changed, 36 insertions(+), 44 deletions(-) diff --git a/.github/actions/build_image/action.yml b/.github/actions/build_image/action.yml index abafb26..3fcda9c 100644 --- a/.github/actions/build_image/action.yml +++ b/.github/actions/build_image/action.yml @@ -60,8 +60,7 @@ runs: aws ecr get-login-password --region ${{ inputs.aws_region }} | docker login --username AWS --password-stdin ${{ inputs.aws_account_id }}.dkr.ecr.${{ inputs.aws_region }}.amazonaws.com docker push ${{ inputs.aws_account_id }}.dkr.ecr.${{ inputs.aws_region }}.amazonaws.com/${{ github.event.repository.name }}:$IMAGE_TAG IMAGE_URI="${{ inputs.aws_account_id }}.dkr.ecr.${{ inputs.aws_region }}.amazonaws.com/${{ github.event.repository.name }}:$IMAGE_TAG" - echo "image_tag=$IMAGE_TAG" >> $GITHUB_OUTPUT - echo "image_uri=$IMAGE_URI" >> $GITHUB_OUTPUT + echo "IMAGE_URI=$IMAGE_URI" >> $GITHUB_ENV echo Image:$IMAGE_URI - if: env.SHOULD_BUILD != 'true' @@ -71,12 +70,5 @@ runs: LATEST_TAG=$(aws ecr describe-images --repository-name ${{ github.event.repository.name }} \ --region ${{ inputs.aws_region }} --query 'sort_by(imageDetails,& imagePushedAt)[-1].imageTags[0]' --output text) IMAGE_URI="${{ inputs.aws_account_id }}.dkr.ecr.${{ inputs.aws_region }}.amazonaws.com/${{ github.event.repository.name }}:$LATEST_TAG" - echo "image_tag=$LATEST_TAG" >> $GITHUB_OUTPUT - echo "image_uri=$IMAGE_URI" >> $GITHUB_OUTPUT - echo Image:$IMAGE_URI - -outputs: - image_tag: - description: 'The TAG of the pushed ECR image' - image_uri: - description: 'The URI of the pushed ECR image' + echo "$IMAGE_TAG=$LATEST_TAG" >> $GITHUB_ENV + echo "IMAGE_URI=$IMAGE_URI" >> $GITHUB_ENV diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 79e26e6..e1e83ad 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -66,42 +66,42 @@ jobs: aws_region: ${{ vars.AWS_REGION }} - name: Check image_uri - run: "echo Image URI: ${{ steps.build-image.outputs.image_uri }}" + run: "echo Image URI: ${{ env.IMAGE_URI }}" - task: - needs: build - runs-on: ubuntu-latest - env: - TF_VAR_image_uri: ${{ needs.build.outputs.image_uri }} - outputs: - task_definition_arn: ${{ steps.set-envs.outputs.TASK_DEFINITION_ARN }} - steps: - - uses: actions/checkout@v4 - - uses: aws-actions/configure-aws-credentials@v4 - with: - aws-region: ${{ env.aws_region }} - role-to-assume: arn:aws:iam::${{ env.aws_account_id }}:role/${{ env.aws_role }} - role-session-name: GitHubActions + # task: + # needs: build + # runs-on: ubuntu-latest + # env: + # TF_VAR_image_uri: ${{ needs.build.outputs.image_uri }} + # outputs: + # task_definition_arn: ${{ steps.set-envs.outputs.TASK_DEFINITION_ARN }} + # steps: + # - uses: actions/checkout@v4 + # - uses: aws-actions/configure-aws-credentials@v4 + # with: + # aws-region: ${{ env.aws_region }} + # role-to-assume: arn:aws:iam::${{ env.aws_account_id }}:role/${{ env.aws_role }} + # role-session-name: GitHubActions - - name: Init - shell: bash - run: | - cd tf/task - terraform init + # - name: Init + # shell: bash + # run: | + # cd tf/task + # terraform init - - name: Deploy - shell: bash - id: deploy - run: | - cd tf/task - terraform apply -auto-approve + # - name: Deploy + # shell: bash + # id: deploy + # run: | + # cd tf/task + # terraform apply -auto-approve - - name: Set env vars - id: set-envs - shell: bash - run: | - cd tf/task - TASK_DEFINITION_ARN=$(terraform output -raw task_definition_arn) - echo "TASK_DEFINITION_ARN=$TASK_DEFINITION_ARN" >> $GITHUB_OUTPUT + # - name: Set env vars + # id: set-envs + # shell: bash + # run: | + # cd tf/task + # TASK_DEFINITION_ARN=$(terraform output -raw task_definition_arn) + # echo "TASK_DEFINITION_ARN=$TASK_DEFINITION_ARN" >> $GITHUB_OUTPUT \ No newline at end of file From 0d0af6d61bd29cac809e36cf8a0933eebf22e2b4 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Sun, 29 Sep 2024 15:57:50 +0100 Subject: [PATCH 034/116] test --- .github/workflows/build.yml | 71 ++++++++++++++++++++----------------- 1 file changed, 38 insertions(+), 33 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e1e83ad..3ddb32c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -48,7 +48,7 @@ jobs: build: runs-on: ubuntu-latest outputs: - image_uri: ${{ steps.build-image.outputs.image_uri }} + image_uri: ${{ steps.set-image-uri.outputs.image_uri }} needs: ecr steps: - uses: actions/checkout@v4 @@ -65,43 +65,48 @@ jobs: aws_account_id: ${{ vars.AWS_ACCOUNT_ID }} aws_region: ${{ vars.AWS_REGION }} + - name: Set image_uri output + id: set-image-uri + run: | + echo "image_uri=${{ env.IMAGE_URI }}" >> $GITHUB_OUTPUT + - name: Check image_uri run: "echo Image URI: ${{ env.IMAGE_URI }}" - # task: - # needs: build - # runs-on: ubuntu-latest - # env: - # TF_VAR_image_uri: ${{ needs.build.outputs.image_uri }} - # outputs: - # task_definition_arn: ${{ steps.set-envs.outputs.TASK_DEFINITION_ARN }} - # steps: - # - uses: actions/checkout@v4 - # - uses: aws-actions/configure-aws-credentials@v4 - # with: - # aws-region: ${{ env.aws_region }} - # role-to-assume: arn:aws:iam::${{ env.aws_account_id }}:role/${{ env.aws_role }} - # role-session-name: GitHubActions + task: + needs: build + runs-on: ubuntu-latest + env: + TF_VAR_image_uri: ${{ needs.build.outputs.image_uri }} + outputs: + task_definition_arn: ${{ steps.set-envs.outputs.TASK_DEFINITION_ARN }} + steps: + - uses: actions/checkout@v4 + - uses: aws-actions/configure-aws-credentials@v4 + with: + aws-region: ${{ env.aws_region }} + role-to-assume: arn:aws:iam::${{ env.aws_account_id }}:role/${{ env.aws_role }} + role-session-name: GitHubActions - # - name: Init - # shell: bash - # run: | - # cd tf/task - # terraform init + - name: Init + shell: bash + run: | + cd tf/task + terraform init - # - name: Deploy - # shell: bash - # id: deploy - # run: | - # cd tf/task - # terraform apply -auto-approve + - name: Deploy + shell: bash + id: deploy + run: | + cd tf/task + terraform apply -auto-approve - # - name: Set env vars - # id: set-envs - # shell: bash - # run: | - # cd tf/task - # TASK_DEFINITION_ARN=$(terraform output -raw task_definition_arn) - # echo "TASK_DEFINITION_ARN=$TASK_DEFINITION_ARN" >> $GITHUB_OUTPUT + - name: Set env vars + id: set-envs + shell: bash + run: | + cd tf/task + TASK_DEFINITION_ARN=$(terraform output -raw task_definition_arn) + echo "TASK_DEFINITION_ARN=$TASK_DEFINITION_ARN" >> $GITHUB_OUTPUT \ No newline at end of file From c21df156d6b7c038287ac3a897108819db68de35 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Sun, 29 Sep 2024 16:30:00 +0100 Subject: [PATCH 035/116] setup --- .github/workflows/build.yml | 5 - .github/workflows/setup.yml | 196 ++++++++++++++++++++++++++++++++++++ 2 files changed, 196 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/setup.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3ddb32c..d8d4ab1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,9 +1,6 @@ name: Build on: - push: - branches: - - 'blue-green-deploy' workflow_dispatch: env: @@ -108,5 +105,3 @@ jobs: cd tf/task TASK_DEFINITION_ARN=$(terraform output -raw task_definition_arn) echo "TASK_DEFINITION_ARN=$TASK_DEFINITION_ARN" >> $GITHUB_OUTPUT - - \ No newline at end of file diff --git a/.github/workflows/setup.yml b/.github/workflows/setup.yml new file mode 100644 index 0000000..1250f96 --- /dev/null +++ b/.github/workflows/setup.yml @@ -0,0 +1,196 @@ +name: Setup + +on: + push: + branches: + - 'blue-green-deploy' + workflow_dispatch: + +env: + aws_account_id: ${{ vars.AWS_ACCOUNT_ID }} + aws_region: ${{ vars.AWS_REGION }} + aws_role: ${{ vars.AWS_ROLE }} + + TF_VAR_project_name: ${{ github.event.repository.name }} + TF_VAR_region: ${{ vars.AWS_REGION }} + TF_VAR_private_vpc_name: ecs-private-vpc + TF_VAR_api_stage_name: dev + TF_VAR_container_port: 3000 + +permissions: + id-token: write + contents: read + +jobs: + init-task: + uses: ./.github/workflows/build-deploy-task.yml + with: + aws_account_id: ${{ vars.AWS_ACCOUNT_ID }} + aws_region: ${{ vars.AWS_REGION }} + aws_role: ${{ vars.AWS_ROLE }} + repository_name: ${{ github.repository }} + + service: + needs: + - init-task + runs-on: ubuntu-latest + env: + TF_VAR_task_definition_arn: ${{ needs.init-task.outputs.task_definition_arn }} + outputs: + cluster_name: ${{ steps.set-envs.outputs.CLUSTER_NAME }} + service_name: ${{ steps.set-envs.outputs.SERVICE_NAME }} + lb_listener_arn: ${{ steps.set-envs.outputs.LB_LISTENER_ARN }} + steps: + - uses: actions/checkout@v4 + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + aws-region: ${{ env.aws_region }} + role-to-assume: arn:aws:iam::${{ env.aws_account_id }}:role/${{ env.aws_role }} + role-session-name: GitHubActions + + - name: Init + shell: bash + run: | + cd tf/service + terraform init + +# - name: Deploy +# shell: bash +# id: deploy +# run: | +# cd tf/service +# terraform apply -auto-approve + +# - name: Set env vars +# id: set-envs +# shell: bash +# run: | +# cd tf/service + +# CLUSTER_NAME=$(terraform output -raw cluster_name) +# echo "CLUSTER_NAME=$CLUSTER_NAME" >> $GITHUB_OUTPUT + +# SERVICE_NAME=$(terraform output -raw service_name) +# echo "SERVICE_NAME=$SERVICE_NAME" >> $GITHUB_OUTPUT + +# LB_LISTENER_ARN=$(terraform output -raw lb_listener_arn) +# echo "LB_LISTENER_ARN=$LB_LISTENER_ARN" >> $GITHUB_OUTPUT + + +# network: +# needs: service +# runs-on: ubuntu-latest +# env: +# TF_VAR_load_balancer_listener_arn: ${{ needs.service.outputs.lb_listener_arn }} +# outputs: +# api_invoke_url: ${{ steps.set-envs.outputs.API_INVOKE_URL }} +# steps: +# - uses: actions/checkout@v4 +# - name: Configure AWS Credentials +# uses: aws-actions/configure-aws-credentials@v4 +# with: +# aws-region: ${{ env.aws_region }} +# role-to-assume: arn:aws:iam::${{ env.aws_account_id }}:role/${{ env.aws_role }} +# role-session-name: GitHubActions + +# - name: Init +# shell: bash +# run: | +# cd tf/network +# terraform init + +# - name: Deploy +# shell: bash +# id: deploy +# run: | +# cd tf/network +# terraform apply -auto-approve + +# - name: Set env vars +# id: set-envs +# shell: bash +# run: | +# cd tf/network + +# API_INVOKE_URL=$(terraform output -raw api_invoke_url) +# echo "API_INVOKE_URL=$API_INVOKE_URL" >> $GITHUB_OUTPUT + +# check_image: +# needs: +# - task +# - service +# runs-on: ubuntu-latest +# steps: +# - name: Configure AWS Credentials +# uses: aws-actions/configure-aws-credentials@v4 +# with: +# aws-region: ${{ env.aws_region }} +# role-to-assume: arn:aws:iam::${{ env.aws_account_id }}:role/${{ env.aws_role }} +# role-session-name: GitHubActions + +# - name: Get current task definition +# id: task-def +# shell: bash +# run: | +# TASK_DEF_ARN=$(aws ecs describe-services \ +# --cluster ${{ needs.service.outputs.cluster_name }} \ +# --services ${{ needs.service.outputs.service_name }} \ +# --region ${{ env.aws_region }} \ +# --query 'services[0].taskDefinition' \ +# --output text) +# echo "TASK_DEF_ARN=$TASK_DEF_ARN" >> $GITHUB_ENV + +# - name: Get image from task definition +# id: check-image +# shell: bash +# run: | +# CURRENT_IMAGE=$(aws ecs describe-task-definition \ +# --task-definition ${{ env.TASK_DEF_ARN }} \ +# --region ${{ env.aws_region }} \ +# --query 'taskDefinition.containerDefinitions[*].image' \ +# --output text) +# echo "CURRENT_IMAGE=$CURRENT_IMAGE" +# echo "CURRENT_IMAGE=$CURRENT_IMAGE" >> $GITHUB_ENV + +# - name: Compare with Terraform image +# id: compare +# run: | +# if [ "${{ env.CURRENT_IMAGE }}" != "${{ needs.task.outputs.image_uri }}" ]; then +# echo "ERROR: Image mismatch! Current image: ${{ env.CURRENT_IMAGE }}, Expected: ${{ needs.task.outputs.image_uri }}" +# exit 1 +# else +# echo "Image matched: ${{ env.CURRENT_IMAGE }}" +# fi + +# check_response: +# needs: +# - network +# - service +# runs-on: ubuntu-latest +# steps: +# - name: Make API request +# id: curl_request +# run: | +# RESPONSE=$(curl -s ${{ needs.network.outputs.api_invoke_url}}/host) +# echo "Response: $RESPONSE" +# echo "$RESPONSE" | jq + +# - name: Assert API response contains expected fields +# run: | +# RESPONSE=$(curl -s ${{ needs.network.outputs.api_invoke_url}}/host) +# echo "$RESPONSE" | jq + +# # Extract values from response +# MESSAGE=$(echo "$RESPONSE" | jq -r '.message') +# IMAGE_URI=$(echo "$RESPONSE" | jq -r '.imageUri') +# HOSTNAME=$(echo "$RESPONSE" | jq -r '.hostname') + +# # Check if expected fields exist +# if [[ "$MESSAGE" == "null" || "$IMAGE_URI" == "null" || "$HOSTNAME" == "null" ]]; then +# echo "Error: Response does not contain expected fields." +# exit 1 +# else +# echo "API response contains all expected fields." +# fi + \ No newline at end of file From 54242df3b237a7a07ec91cad01f97ef67d92129c Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Sun, 29 Sep 2024 16:32:27 +0100 Subject: [PATCH 036/116] fix --- .github/workflows/setup.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/setup.yml b/.github/workflows/setup.yml index 1250f96..357eb8c 100644 --- a/.github/workflows/setup.yml +++ b/.github/workflows/setup.yml @@ -23,7 +23,7 @@ permissions: jobs: init-task: - uses: ./.github/workflows/build-deploy-task.yml + uses: ./.github/workflows/build.yml with: aws_account_id: ${{ vars.AWS_ACCOUNT_ID }} aws_region: ${{ vars.AWS_REGION }} From 2e287d77db43d1b675acbf7182d08c8c61c6a1b4 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Sun, 29 Sep 2024 16:33:46 +0100 Subject: [PATCH 037/116] workflow_call --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d8d4ab1..d6fec6e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,7 +1,7 @@ name: Build on: - workflow_dispatch: + workflow_call: env: aws_account_id: ${{ vars.AWS_ACCOUNT_ID }} From 902a2f07ee8c5f6f52e2172aae62c2b50fa850f2 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Sun, 29 Sep 2024 16:39:52 +0100 Subject: [PATCH 038/116] inputs --- .github/workflows/build.yml | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d6fec6e..7420ecd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -2,14 +2,22 @@ name: Build on: workflow_call: + inputs: + aws_account_id: + required: true + type: string + aws_region: + required: true + type: string + aws_role: + required: true + type: string + repository_name: + required: true + type: string env: - aws_account_id: ${{ vars.AWS_ACCOUNT_ID }} - aws_region: ${{ vars.AWS_REGION }} - aws_role: ${{ vars.AWS_ROLE }} - - TF_VAR_project_name: ${{ github.event.repository.name }} - TF_VAR_region: ${{ vars.AWS_REGION }} + TF_VAR_region: ${{ inputs.aws_region }} TF_VAR_private_vpc_name: ecs-private-vpc TF_VAR_api_stage_name: dev TF_VAR_container_port: 3000 @@ -25,8 +33,8 @@ jobs: - uses: actions/checkout@v4 - uses: aws-actions/configure-aws-credentials@v4 with: - aws-region: ${{ env.aws_region }} - role-to-assume: arn:aws:iam::${{ env.aws_account_id }}:role/${{ env.aws_role }} + aws-region: ${{ inputs.aws_region }} + role-to-assume: arn:aws:iam::${{ inputs.aws_account_id }}:role/${{ inputs.aws_role }} role-session-name: GitHubActions - name: Init @@ -51,16 +59,16 @@ jobs: - uses: actions/checkout@v4 - uses: aws-actions/configure-aws-credentials@v4 with: - aws-region: ${{ env.aws_region }} - role-to-assume: arn:aws:iam::${{ env.aws_account_id }}:role/${{ env.aws_role }} + aws-region: ${{ inputs.aws_region }} + role-to-assume: arn:aws:iam::${{ inputs.aws_account_id }}:role/${{ inputs.aws_role }} role-session-name: GitHubActions - name: Build and push detected changes id: build-image uses: ./.github/actions/build_image with: - aws_account_id: ${{ vars.AWS_ACCOUNT_ID }} - aws_region: ${{ vars.AWS_REGION }} + aws_account_id: ${{ inputs.aws_account_id }} + aws_region: ${{ inputs.aws_region }} - name: Set image_uri output id: set-image-uri @@ -81,8 +89,8 @@ jobs: - uses: actions/checkout@v4 - uses: aws-actions/configure-aws-credentials@v4 with: - aws-region: ${{ env.aws_region }} - role-to-assume: arn:aws:iam::${{ env.aws_account_id }}:role/${{ env.aws_role }} + aws-region: ${{ inputs.aws_region }} + role-to-assume: arn:aws:iam::${{ inputs.aws_account_id }}:role/${{ inputs.aws_role }} role-session-name: GitHubActions - name: Init From 1b3bfd8fc1639a3875c7f396d15867ce2d527ef5 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Sun, 29 Sep 2024 16:41:35 +0100 Subject: [PATCH 039/116] project name var --- .github/workflows/build.yml | 1 + .github/workflows/setup.yml | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7420ecd..1f91e8b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -17,6 +17,7 @@ on: type: string env: + TF_VAR_project_name: ${{ inputs.repository_name }} TF_VAR_region: ${{ inputs.aws_region }} TF_VAR_private_vpc_name: ecs-private-vpc TF_VAR_api_stage_name: dev diff --git a/.github/workflows/setup.yml b/.github/workflows/setup.yml index 357eb8c..5335a99 100644 --- a/.github/workflows/setup.yml +++ b/.github/workflows/setup.yml @@ -22,7 +22,7 @@ permissions: contents: read jobs: - init-task: + init: uses: ./.github/workflows/build.yml with: aws_account_id: ${{ vars.AWS_ACCOUNT_ID }} @@ -32,10 +32,10 @@ jobs: service: needs: - - init-task + - init runs-on: ubuntu-latest env: - TF_VAR_task_definition_arn: ${{ needs.init-task.outputs.task_definition_arn }} + TF_VAR_task_definition_arn: ${{ needs.init.outputs.task_definition_arn }} outputs: cluster_name: ${{ steps.set-envs.outputs.CLUSTER_NAME }} service_name: ${{ steps.set-envs.outputs.SERVICE_NAME }} From f7046e886e46713deb0034544c67d0185f605273 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Sun, 29 Sep 2024 17:17:43 +0100 Subject: [PATCH 040/116] vars file --- .github/workflows/build.yml | 11 ++--------- .github/workflows/deploy.yml | 14 ++++---------- .github/workflows/destroy.yml | 14 ++++---------- .github/workflows/setup.yml | 6 ------ tf/variables.tfvars | 5 +++++ 5 files changed, 15 insertions(+), 35 deletions(-) create mode 100644 tf/variables.tfvars diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1f91e8b..cee1947 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -16,13 +16,6 @@ on: required: true type: string -env: - TF_VAR_project_name: ${{ inputs.repository_name }} - TF_VAR_region: ${{ inputs.aws_region }} - TF_VAR_private_vpc_name: ecs-private-vpc - TF_VAR_api_stage_name: dev - TF_VAR_container_port: 3000 - permissions: id-token: write contents: read @@ -49,7 +42,7 @@ jobs: id: deploy run: | cd tf/ecr - terraform apply -auto-approve + terraform apply -auto-approve -var-file=${{ github.workspace }}/tf/variables.tfvars build: runs-on: ubuntu-latest @@ -105,7 +98,7 @@ jobs: id: deploy run: | cd tf/task - terraform apply -auto-approve + terraform apply -auto-approve -var-file=${{ github.workspace }}/tf/variables.tfvars - name: Set env vars id: set-envs diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index df5b4a1..cb23f17 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -8,12 +8,6 @@ env: aws_region: ${{ vars.AWS_REGION }} aws_role: ${{ vars.AWS_ROLE }} - TF_VAR_project_name: ${{ github.event.repository.name }} - TF_VAR_region: ${{ vars.AWS_REGION }} - TF_VAR_private_vpc_name: ecs-private-vpc - TF_VAR_api_stage_name: dev - TF_VAR_container_port: 3000 - permissions: id-token: write contents: read @@ -41,7 +35,7 @@ jobs: id: deploy run: | cd tf/ecr - terraform apply -auto-approve + terraform apply -auto-approve -var-file=${{ github.workspace }}/tf/variables.tfvars - name: Build and push detected changes id: build-image @@ -76,7 +70,7 @@ jobs: id: deploy run: | cd tf/task - terraform apply -auto-approve + terraform apply -auto-approve -var-file=${{ github.workspace }}/tf/variables.tfvars - name: Set env vars id: set-envs @@ -121,7 +115,7 @@ jobs: id: deploy run: | cd tf/service - terraform apply -auto-approve + terraform apply -auto-approve -var-file=${{ github.workspace }}/tf/variables.tfvars - name: Set env vars id: set-envs @@ -166,7 +160,7 @@ jobs: id: deploy run: | cd tf/network - terraform apply -auto-approve + terraform apply -auto-approve -var-file=${{ github.workspace }}/tf/variables.tfvars - name: Set env vars id: set-envs diff --git a/.github/workflows/destroy.yml b/.github/workflows/destroy.yml index e1e09b7..a442e2e 100644 --- a/.github/workflows/destroy.yml +++ b/.github/workflows/destroy.yml @@ -9,12 +9,6 @@ env: aws_region: ${{ vars.AWS_REGION }} aws_role: ${{ vars.AWS_ROLE }} - TF_VAR_project_name: ${{ github.event.repository.name }} - TF_VAR_region: ${{ vars.AWS_REGION }} - TF_VAR_private_vpc_name: ecs-private-vpc - TF_VAR_api_stage_name: dev - TF_VAR_container_port: 3000 - permissions: id-token: write contents: read @@ -44,7 +38,7 @@ jobs: id: destroy run: | cd tf/task - terraform destroy -auto-approve + terraform destroy -auto-approve -var-file=${{ github.workspace }}/tf/variables.tfvars ecr: needs: task @@ -69,7 +63,7 @@ jobs: id: destroy run: | cd tf/ecr - terraform destroy -auto-approve + terraform destroy -auto-approve -var-file=${{ github.workspace }}/tf/variables.tfvars network: runs-on: ubuntu-latest @@ -95,7 +89,7 @@ jobs: id: destroy run: | cd tf/network - terraform destroy -auto-approve + terraform destroy -auto-approve -var-file=${{ github.workspace }}/tf/variables.tfvars service: @@ -123,4 +117,4 @@ jobs: id: destroy run: | cd tf/service - terraform destroy -auto-approve + terraform destroy -auto-approve -var-file=${{ github.workspace }}/tf/variables.tfvars diff --git a/.github/workflows/setup.yml b/.github/workflows/setup.yml index 5335a99..fb1245e 100644 --- a/.github/workflows/setup.yml +++ b/.github/workflows/setup.yml @@ -11,12 +11,6 @@ env: aws_region: ${{ vars.AWS_REGION }} aws_role: ${{ vars.AWS_ROLE }} - TF_VAR_project_name: ${{ github.event.repository.name }} - TF_VAR_region: ${{ vars.AWS_REGION }} - TF_VAR_private_vpc_name: ecs-private-vpc - TF_VAR_api_stage_name: dev - TF_VAR_container_port: 3000 - permissions: id-token: write contents: read diff --git a/tf/variables.tfvars b/tf/variables.tfvars new file mode 100644 index 0000000..45edc73 --- /dev/null +++ b/tf/variables.tfvars @@ -0,0 +1,5 @@ +project_name = "fargate-auto-scaled-backend" +region = "eu-west-2" +private_vpc_name = "ecs-private-vpc" +api_stage_name = "dev" +container_port = 3000 \ No newline at end of file From a10b11d6bdc062c48be24504655feb97c55a50a2 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Sun, 29 Sep 2024 17:25:18 +0100 Subject: [PATCH 041/116] output --- .github/workflows/build.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index cee1947..51c60fd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -15,6 +15,10 @@ on: repository_name: required: true type: string + outputs: + task_definition_arn: + description: "The ARN of the deployed task definition" + value: ${{ jobs.task.outputs.task_definition_arn }} permissions: id-token: write From 0cf3d02d9287ea42e6320645405ce28e8a4db1a7 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Sun, 29 Sep 2024 17:31:21 +0100 Subject: [PATCH 042/116] pass out uri --- .github/workflows/build.yml | 5 +- .github/workflows/setup.yml | 270 ++++++++++++++++++------------------ 2 files changed, 137 insertions(+), 138 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 51c60fd..18a827a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -19,6 +19,8 @@ on: task_definition_arn: description: "The ARN of the deployed task definition" value: ${{ jobs.task.outputs.task_definition_arn }} + image_uri: + value: ${{ jobs.build.outputs.image_uri }} permissions: id-token: write @@ -73,9 +75,6 @@ jobs: run: | echo "image_uri=${{ env.IMAGE_URI }}" >> $GITHUB_OUTPUT - - name: Check image_uri - run: "echo Image URI: ${{ env.IMAGE_URI }}" - task: needs: build runs-on: ubuntu-latest diff --git a/.github/workflows/setup.yml b/.github/workflows/setup.yml index fb1245e..fa34ec7 100644 --- a/.github/workflows/setup.yml +++ b/.github/workflows/setup.yml @@ -49,142 +49,142 @@ jobs: cd tf/service terraform init -# - name: Deploy -# shell: bash -# id: deploy -# run: | -# cd tf/service -# terraform apply -auto-approve - -# - name: Set env vars -# id: set-envs -# shell: bash -# run: | -# cd tf/service - -# CLUSTER_NAME=$(terraform output -raw cluster_name) -# echo "CLUSTER_NAME=$CLUSTER_NAME" >> $GITHUB_OUTPUT - -# SERVICE_NAME=$(terraform output -raw service_name) -# echo "SERVICE_NAME=$SERVICE_NAME" >> $GITHUB_OUTPUT - -# LB_LISTENER_ARN=$(terraform output -raw lb_listener_arn) -# echo "LB_LISTENER_ARN=$LB_LISTENER_ARN" >> $GITHUB_OUTPUT - - -# network: -# needs: service -# runs-on: ubuntu-latest -# env: -# TF_VAR_load_balancer_listener_arn: ${{ needs.service.outputs.lb_listener_arn }} -# outputs: -# api_invoke_url: ${{ steps.set-envs.outputs.API_INVOKE_URL }} -# steps: -# - uses: actions/checkout@v4 -# - name: Configure AWS Credentials -# uses: aws-actions/configure-aws-credentials@v4 -# with: -# aws-region: ${{ env.aws_region }} -# role-to-assume: arn:aws:iam::${{ env.aws_account_id }}:role/${{ env.aws_role }} -# role-session-name: GitHubActions - -# - name: Init -# shell: bash -# run: | -# cd tf/network -# terraform init + - name: Deploy + shell: bash + id: deploy + run: | + cd tf/service + terraform apply -auto-approve + + - name: Set env vars + id: set-envs + shell: bash + run: | + cd tf/service + + CLUSTER_NAME=$(terraform output -raw cluster_name) + echo "CLUSTER_NAME=$CLUSTER_NAME" >> $GITHUB_OUTPUT + + SERVICE_NAME=$(terraform output -raw service_name) + echo "SERVICE_NAME=$SERVICE_NAME" >> $GITHUB_OUTPUT + + LB_LISTENER_ARN=$(terraform output -raw lb_listener_arn) + echo "LB_LISTENER_ARN=$LB_LISTENER_ARN" >> $GITHUB_OUTPUT + + + network: + needs: service + runs-on: ubuntu-latest + env: + TF_VAR_load_balancer_listener_arn: ${{ needs.service.outputs.lb_listener_arn }} + outputs: + api_invoke_url: ${{ steps.set-envs.outputs.API_INVOKE_URL }} + steps: + - uses: actions/checkout@v4 + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + aws-region: ${{ env.aws_region }} + role-to-assume: arn:aws:iam::${{ env.aws_account_id }}:role/${{ env.aws_role }} + role-session-name: GitHubActions + + - name: Init + shell: bash + run: | + cd tf/network + terraform init -# - name: Deploy -# shell: bash -# id: deploy -# run: | -# cd tf/network -# terraform apply -auto-approve - -# - name: Set env vars -# id: set-envs -# shell: bash -# run: | -# cd tf/network - -# API_INVOKE_URL=$(terraform output -raw api_invoke_url) -# echo "API_INVOKE_URL=$API_INVOKE_URL" >> $GITHUB_OUTPUT - -# check_image: -# needs: -# - task -# - service -# runs-on: ubuntu-latest -# steps: -# - name: Configure AWS Credentials -# uses: aws-actions/configure-aws-credentials@v4 -# with: -# aws-region: ${{ env.aws_region }} -# role-to-assume: arn:aws:iam::${{ env.aws_account_id }}:role/${{ env.aws_role }} -# role-session-name: GitHubActions - -# - name: Get current task definition -# id: task-def -# shell: bash -# run: | -# TASK_DEF_ARN=$(aws ecs describe-services \ -# --cluster ${{ needs.service.outputs.cluster_name }} \ -# --services ${{ needs.service.outputs.service_name }} \ -# --region ${{ env.aws_region }} \ -# --query 'services[0].taskDefinition' \ -# --output text) -# echo "TASK_DEF_ARN=$TASK_DEF_ARN" >> $GITHUB_ENV - -# - name: Get image from task definition -# id: check-image -# shell: bash -# run: | -# CURRENT_IMAGE=$(aws ecs describe-task-definition \ -# --task-definition ${{ env.TASK_DEF_ARN }} \ -# --region ${{ env.aws_region }} \ -# --query 'taskDefinition.containerDefinitions[*].image' \ -# --output text) -# echo "CURRENT_IMAGE=$CURRENT_IMAGE" -# echo "CURRENT_IMAGE=$CURRENT_IMAGE" >> $GITHUB_ENV - -# - name: Compare with Terraform image -# id: compare -# run: | -# if [ "${{ env.CURRENT_IMAGE }}" != "${{ needs.task.outputs.image_uri }}" ]; then -# echo "ERROR: Image mismatch! Current image: ${{ env.CURRENT_IMAGE }}, Expected: ${{ needs.task.outputs.image_uri }}" -# exit 1 -# else -# echo "Image matched: ${{ env.CURRENT_IMAGE }}" -# fi - -# check_response: -# needs: -# - network -# - service -# runs-on: ubuntu-latest -# steps: -# - name: Make API request -# id: curl_request -# run: | -# RESPONSE=$(curl -s ${{ needs.network.outputs.api_invoke_url}}/host) -# echo "Response: $RESPONSE" -# echo "$RESPONSE" | jq + - name: Deploy + shell: bash + id: deploy + run: | + cd tf/network + terraform apply -auto-approve + + - name: Set env vars + id: set-envs + shell: bash + run: | + cd tf/network + + API_INVOKE_URL=$(terraform output -raw api_invoke_url) + echo "API_INVOKE_URL=$API_INVOKE_URL" >> $GITHUB_OUTPUT + + check_image: + needs: + - init + - service + runs-on: ubuntu-latest + steps: + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + aws-region: ${{ env.aws_region }} + role-to-assume: arn:aws:iam::${{ env.aws_account_id }}:role/${{ env.aws_role }} + role-session-name: GitHubActions + + - name: Get current task definition + id: task-def + shell: bash + run: | + TASK_DEF_ARN=$(aws ecs describe-services \ + --cluster ${{ needs.service.outputs.cluster_name }} \ + --services ${{ needs.service.outputs.service_name }} \ + --region ${{ env.aws_region }} \ + --query 'services[0].taskDefinition' \ + --output text) + echo "TASK_DEF_ARN=$TASK_DEF_ARN" >> $GITHUB_ENV + + - name: Get image from task definition + id: check-image + shell: bash + run: | + CURRENT_IMAGE=$(aws ecs describe-task-definition \ + --task-definition ${{ env.TASK_DEF_ARN }} \ + --region ${{ env.aws_region }} \ + --query 'taskDefinition.containerDefinitions[*].image' \ + --output text) + echo "CURRENT_IMAGE=$CURRENT_IMAGE" + echo "CURRENT_IMAGE=$CURRENT_IMAGE" >> $GITHUB_ENV + + - name: Compare with Terraform image + id: compare + run: | + if [ "${{ env.CURRENT_IMAGE }}" != "${{ needs.init.outputs.image_uri }}" ]; then + echo "ERROR: Image mismatch! Current image: ${{ env.CURRENT_IMAGE }}, Expected: ${{ needs.task.outputs.image_uri }}" + exit 1 + else + echo "Image matched: ${{ env.CURRENT_IMAGE }}" + fi + + check_response: + needs: + - network + - service + runs-on: ubuntu-latest + steps: + - name: Make API request + id: curl_request + run: | + RESPONSE=$(curl -s ${{ needs.network.outputs.api_invoke_url}}/host) + echo "Response: $RESPONSE" + echo "$RESPONSE" | jq -# - name: Assert API response contains expected fields -# run: | -# RESPONSE=$(curl -s ${{ needs.network.outputs.api_invoke_url}}/host) -# echo "$RESPONSE" | jq + - name: Assert API response contains expected fields + run: | + RESPONSE=$(curl -s ${{ needs.network.outputs.api_invoke_url}}/host) + echo "$RESPONSE" | jq -# # Extract values from response -# MESSAGE=$(echo "$RESPONSE" | jq -r '.message') -# IMAGE_URI=$(echo "$RESPONSE" | jq -r '.imageUri') -# HOSTNAME=$(echo "$RESPONSE" | jq -r '.hostname') - -# # Check if expected fields exist -# if [[ "$MESSAGE" == "null" || "$IMAGE_URI" == "null" || "$HOSTNAME" == "null" ]]; then -# echo "Error: Response does not contain expected fields." -# exit 1 -# else -# echo "API response contains all expected fields." -# fi + # Extract values from response + MESSAGE=$(echo "$RESPONSE" | jq -r '.message') + IMAGE_URI=$(echo "$RESPONSE" | jq -r '.imageUri') + HOSTNAME=$(echo "$RESPONSE" | jq -r '.hostname') + + # Check if expected fields exist + if [[ "$MESSAGE" == "null" || "$IMAGE_URI" == "null" || "$HOSTNAME" == "null" ]]; then + echo "Error: Response does not contain expected fields." + exit 1 + else + echo "API response contains all expected fields." + fi \ No newline at end of file From 4e78cd245a65c799567dad592acc02d8adc88c63 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Sun, 29 Sep 2024 17:35:36 +0100 Subject: [PATCH 043/116] -var-file=${{ github.workspace }}/tf/variables.tfvars --- .github/workflows/setup.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/setup.yml b/.github/workflows/setup.yml index fa34ec7..53d5b8d 100644 --- a/.github/workflows/setup.yml +++ b/.github/workflows/setup.yml @@ -54,7 +54,7 @@ jobs: id: deploy run: | cd tf/service - terraform apply -auto-approve + terraform apply -auto-approve -var-file=${{ github.workspace }}/tf/variables.tfvars - name: Set env vars id: set-envs @@ -99,7 +99,7 @@ jobs: id: deploy run: | cd tf/network - terraform apply -auto-approve + terraform apply -auto-approve -var-file=${{ github.workspace }}/tf/variables.tfvars - name: Set env vars id: set-envs From ec687d797ac9eb5558993609a42c2141260c6bd2 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Sun, 29 Sep 2024 17:50:02 +0100 Subject: [PATCH 044/116] rm env: --- .github/workflows/setup.yml | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/.github/workflows/setup.yml b/.github/workflows/setup.yml index 53d5b8d..21adc01 100644 --- a/.github/workflows/setup.yml +++ b/.github/workflows/setup.yml @@ -6,11 +6,6 @@ on: - 'blue-green-deploy' workflow_dispatch: -env: - aws_account_id: ${{ vars.AWS_ACCOUNT_ID }} - aws_region: ${{ vars.AWS_REGION }} - aws_role: ${{ vars.AWS_ROLE }} - permissions: id-token: write contents: read @@ -39,8 +34,8 @@ jobs: - name: Configure AWS Credentials uses: aws-actions/configure-aws-credentials@v4 with: - aws-region: ${{ env.aws_region }} - role-to-assume: arn:aws:iam::${{ env.aws_account_id }}:role/${{ env.aws_role }} + aws-region: ${{ vars.aws_region }} + role-to-assume: arn:aws:iam::${{ vars.aws_account_id }}:role/${{ vars.aws_role }} role-session-name: GitHubActions - name: Init @@ -84,8 +79,8 @@ jobs: - name: Configure AWS Credentials uses: aws-actions/configure-aws-credentials@v4 with: - aws-region: ${{ env.aws_region }} - role-to-assume: arn:aws:iam::${{ env.aws_account_id }}:role/${{ env.aws_role }} + aws-region: ${{ vars.aws_region }} + role-to-assume: arn:aws:iam::${{ vars.aws_account_id }}:role/${{ vars.aws_role }} role-session-name: GitHubActions - name: Init @@ -119,8 +114,8 @@ jobs: - name: Configure AWS Credentials uses: aws-actions/configure-aws-credentials@v4 with: - aws-region: ${{ env.aws_region }} - role-to-assume: arn:aws:iam::${{ env.aws_account_id }}:role/${{ env.aws_role }} + aws-region: ${{ vars.aws_region }} + role-to-assume: arn:aws:iam::${{ vars.aws_account_id }}:role/${{ vars.aws_role }} role-session-name: GitHubActions - name: Get current task definition @@ -130,7 +125,7 @@ jobs: TASK_DEF_ARN=$(aws ecs describe-services \ --cluster ${{ needs.service.outputs.cluster_name }} \ --services ${{ needs.service.outputs.service_name }} \ - --region ${{ env.aws_region }} \ + --region ${{ vars.aws_region }} \ --query 'services[0].taskDefinition' \ --output text) echo "TASK_DEF_ARN=$TASK_DEF_ARN" >> $GITHUB_ENV @@ -141,7 +136,7 @@ jobs: run: | CURRENT_IMAGE=$(aws ecs describe-task-definition \ --task-definition ${{ env.TASK_DEF_ARN }} \ - --region ${{ env.aws_region }} \ + --region ${{ vars.aws_region }} \ --query 'taskDefinition.containerDefinitions[*].image' \ --output text) echo "CURRENT_IMAGE=$CURRENT_IMAGE" From 62146783901b1f39aa22ab1c959bfd4a71748292 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Sun, 29 Sep 2024 18:22:48 +0100 Subject: [PATCH 045/116] rm repo name var --- .github/workflows/build.yml | 5 ++--- .github/workflows/setup.yml | 4 ---- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 18a827a..1840376 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -12,9 +12,6 @@ on: aws_role: required: true type: string - repository_name: - required: true - type: string outputs: task_definition_arn: description: "The ARN of the deployed task definition" @@ -109,4 +106,6 @@ jobs: run: | cd tf/task TASK_DEFINITION_ARN=$(terraform output -raw task_definition_arn) + TASK_DEFINITION_REVISION=$(terraform output -raw task_definition_revision) echo "TASK_DEFINITION_ARN=$TASK_DEFINITION_ARN" >> $GITHUB_OUTPUT + echo "TASK_DEFINITION_REVISION=$TASK_DEFINITION_REVISION" >> $GITHUB_OUTPUT diff --git a/.github/workflows/setup.yml b/.github/workflows/setup.yml index 21adc01..499ed4b 100644 --- a/.github/workflows/setup.yml +++ b/.github/workflows/setup.yml @@ -1,9 +1,6 @@ name: Setup on: - push: - branches: - - 'blue-green-deploy' workflow_dispatch: permissions: @@ -17,7 +14,6 @@ jobs: aws_account_id: ${{ vars.AWS_ACCOUNT_ID }} aws_region: ${{ vars.AWS_REGION }} aws_role: ${{ vars.AWS_ROLE }} - repository_name: ${{ github.repository }} service: needs: From 88abbb675863741641762e45cc3478b863717c11 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Mon, 30 Sep 2024 10:57:44 +0100 Subject: [PATCH 046/116] pass in codedeploy_app_name var --- tf/service/deploy/main.tf | 2 +- tf/service/deploy/variables.tf | 4 ++++ tf/service/main.tf | 1 + tf/service/variables.tf | 4 ++++ tf/variables.tfvars | 11 ++++++----- 5 files changed, 16 insertions(+), 6 deletions(-) diff --git a/tf/service/deploy/main.tf b/tf/service/deploy/main.tf index c7eab3b..d09d12b 100644 --- a/tf/service/deploy/main.tf +++ b/tf/service/deploy/main.tf @@ -1,5 +1,5 @@ resource "aws_codedeploy_app" "ecs_app" { - name = "${var.project_name}-ecs-codedeploy" + name = var.codedeploy_app_name compute_platform = "ECS" } diff --git a/tf/service/deploy/variables.tf b/tf/service/deploy/variables.tf index 9ce7940..744dc2d 100644 --- a/tf/service/deploy/variables.tf +++ b/tf/service/deploy/variables.tf @@ -14,6 +14,10 @@ variable "service_name" { type = string } +variable "codedeploy_app_name" { + type = string +} + variable "lb_listener_arn" { type = string } diff --git a/tf/service/main.tf b/tf/service/main.tf index 58d1373..a9bacbe 100644 --- a/tf/service/main.tf +++ b/tf/service/main.tf @@ -28,6 +28,7 @@ module "deploy" { source = "./deploy" project_name = var.project_name + codedeploy_app_name = var.codedeploy_app_name region = var.region cluster_name = module.ecs.cluster_name service_name = module.ecs.service_name diff --git a/tf/service/variables.tf b/tf/service/variables.tf index 95db1b5..f82d372 100644 --- a/tf/service/variables.tf +++ b/tf/service/variables.tf @@ -2,6 +2,10 @@ variable "project_name" { type = string } +variable "codedeploy_app_name" { + type = string +} + variable "region" { type = string } diff --git a/tf/variables.tfvars b/tf/variables.tfvars index 45edc73..3d7592f 100644 --- a/tf/variables.tfvars +++ b/tf/variables.tfvars @@ -1,5 +1,6 @@ -project_name = "fargate-auto-scaled-backend" -region = "eu-west-2" -private_vpc_name = "ecs-private-vpc" -api_stage_name = "dev" -container_port = 3000 \ No newline at end of file +project_name = "fargate-auto-scaled-backend" +codedeploy_app_name = "fargate-auto-scaled-backend-ecs-codedeploy" +region = "eu-west-2" +private_vpc_name = "ecs-private-vpc" +api_stage_name = "dev" +container_port = 3000 \ No newline at end of file From ea2a839071a7595db5a2de45c5985ee215b7659b Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Mon, 30 Sep 2024 11:02:52 +0100 Subject: [PATCH 047/116] kick --- .github/workflows/setup.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/setup.yml b/.github/workflows/setup.yml index 499ed4b..05f0425 100644 --- a/.github/workflows/setup.yml +++ b/.github/workflows/setup.yml @@ -1,6 +1,9 @@ name: Setup on: + push: + branches: + - 'blue-green-deploy' workflow_dispatch: permissions: From e31e9c48e0d6875eb70d97119b4954e171a8e7e9 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Mon, 30 Sep 2024 11:06:15 +0100 Subject: [PATCH 048/116] output task_definition_revision --- tf/task/outputs.tf | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tf/task/outputs.tf b/tf/task/outputs.tf index 3964f58..cd6f347 100644 --- a/tf/task/outputs.tf +++ b/tf/task/outputs.tf @@ -2,6 +2,10 @@ output "task_definition_arn" { value = aws_ecs_task_definition.task.arn } +output "task_definition_revision" { + value = aws_ecs_task_definition.task.revision +} + output "cloudwatch_log_group" { value = aws_cloudwatch_log_group.ecs_log_group.name } From 3701b837065cf71fe37d74a0739a4a928dba2d32 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Mon, 30 Sep 2024 11:10:37 +0100 Subject: [PATCH 049/116] add deployment to destroy --- .github/workflows/destroy.yml | 50 ++++++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 15 deletions(-) diff --git a/.github/workflows/destroy.yml b/.github/workflows/destroy.yml index a442e2e..f897613 100644 --- a/.github/workflows/destroy.yml +++ b/.github/workflows/destroy.yml @@ -2,12 +2,9 @@ name: Destroy on: workflow_dispatch: - workflow_call: env: - aws_account_id: ${{ vars.AWS_ACCOUNT_ID }} - aws_region: ${{ vars.AWS_REGION }} - aws_role: ${{ vars.AWS_ROLE }} + TF_VAR_load_balancer_listener_arn: "arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/dummy-target-group/1234567890123456" permissions: id-token: write @@ -23,8 +20,8 @@ jobs: - name: Configure AWS Credentials uses: aws-actions/configure-aws-credentials@v4 with: - aws-region: ${{ env.aws_region }} - role-to-assume: arn:aws:iam::${{ env.aws_account_id }}:role/${{ env.aws_role }} + aws-region: ${{ vars.aws_region }} + role-to-assume: arn:aws:iam::${{ vars.aws_account_id }}:role/${{ vars.aws_role }} role-session-name: GitHubActions - name: Init @@ -48,8 +45,8 @@ jobs: - name: Configure AWS Credentials uses: aws-actions/configure-aws-credentials@v4 with: - aws-region: ${{ env.aws_region }} - role-to-assume: arn:aws:iam::${{ env.aws_account_id }}:role/${{ env.aws_role }} + aws-region: ${{ vars.aws_region }} + role-to-assume: arn:aws:iam::${{ vars.aws_account_id }}:role/${{ vars.aws_role }} role-session-name: GitHubActions - name: Init @@ -67,15 +64,13 @@ jobs: network: runs-on: ubuntu-latest - env: - TF_VAR_load_balancer_listener_arn: "arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/dummy-target-group/1234567890123456" steps: - uses: actions/checkout@v4 - name: Configure AWS Credentials uses: aws-actions/configure-aws-credentials@v4 with: - aws-region: ${{ env.aws_region }} - role-to-assume: arn:aws:iam::${{ env.aws_account_id }}:role/${{ env.aws_role }} + aws-region: ${{ vars.aws_region }} + role-to-assume: arn:aws:iam::${{ vars.aws_account_id }}:role/${{ vars.aws_role }} role-session-name: GitHubActions - name: Init @@ -91,10 +86,35 @@ jobs: cd tf/network terraform destroy -auto-approve -var-file=${{ github.workspace }}/tf/variables.tfvars + deployment: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + aws-region: ${{ vars.aws_region }} + role-to-assume: arn:aws:iam::${{ vars.aws_account_id }}:role/${{ vars.aws_role }} + role-session-name: GitHubActions + + - name: Init + shell: bash + run: | + cd tf/deployment + terraform init + + - name: Destroy + shell: bash + id: destroy + run: | + cd tf/deployment + terraform destroy -auto-approve -var-file=${{ github.workspace }}/tf/variables.tfvars service: runs-on: ubuntu-latest - needs: network + needs: + - network + - deployment env: TF_VAR_task_definition_arn: "arn:aws:ecs:us-east-1:123456789012:task-definition/dummy-task-definition" steps: @@ -102,8 +122,8 @@ jobs: - name: Configure AWS Credentials uses: aws-actions/configure-aws-credentials@v4 with: - aws-region: ${{ env.aws_region }} - role-to-assume: arn:aws:iam::${{ env.aws_account_id }}:role/${{ env.aws_role }} + aws-region: ${{ vars.aws_region }} + role-to-assume: arn:aws:iam::${{ vars.aws_account_id }}:role/${{ vars.aws_role }} role-session-name: GitHubActions - name: Init From 941c27a795473b691176aaffa16bf1b7b85c96be Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Mon, 30 Sep 2024 11:31:51 +0100 Subject: [PATCH 050/116] rm deploy --- .github/workflows/destroy.yml | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/.github/workflows/destroy.yml b/.github/workflows/destroy.yml index f897613..59b4b58 100644 --- a/.github/workflows/destroy.yml +++ b/.github/workflows/destroy.yml @@ -85,36 +85,11 @@ jobs: run: | cd tf/network terraform destroy -auto-approve -var-file=${{ github.workspace }}/tf/variables.tfvars - - deployment: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v4 - with: - aws-region: ${{ vars.aws_region }} - role-to-assume: arn:aws:iam::${{ vars.aws_account_id }}:role/${{ vars.aws_role }} - role-session-name: GitHubActions - - - name: Init - shell: bash - run: | - cd tf/deployment - terraform init - - - name: Destroy - shell: bash - id: destroy - run: | - cd tf/deployment - terraform destroy -auto-approve -var-file=${{ github.workspace }}/tf/variables.tfvars service: runs-on: ubuntu-latest needs: - network - - deployment env: TF_VAR_task_definition_arn: "arn:aws:ecs:us-east-1:123456789012:task-definition/dummy-task-definition" steps: From 5f7a0989ab5fed79b8319634ee4841122819d4dd Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Mon, 30 Sep 2024 14:00:57 +0100 Subject: [PATCH 051/116] check existing svc --- .github/workflows/setup.yml | 269 +++++++++++++++--------------------- 1 file changed, 115 insertions(+), 154 deletions(-) diff --git a/.github/workflows/setup.yml b/.github/workflows/setup.yml index 05f0425..363adc3 100644 --- a/.github/workflows/setup.yml +++ b/.github/workflows/setup.yml @@ -11,174 +11,135 @@ permissions: contents: read jobs: - init: - uses: ./.github/workflows/build.yml - with: - aws_account_id: ${{ vars.AWS_ACCOUNT_ID }} - aws_region: ${{ vars.AWS_REGION }} - aws_role: ${{ vars.AWS_ROLE }} - - service: - needs: - - init - runs-on: ubuntu-latest - env: - TF_VAR_task_definition_arn: ${{ needs.init.outputs.task_definition_arn }} - outputs: - cluster_name: ${{ steps.set-envs.outputs.CLUSTER_NAME }} - service_name: ${{ steps.set-envs.outputs.SERVICE_NAME }} - lb_listener_arn: ${{ steps.set-envs.outputs.LB_LISTENER_ARN }} - steps: - - uses: actions/checkout@v4 - - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v4 - with: - aws-region: ${{ vars.aws_region }} - role-to-assume: arn:aws:iam::${{ vars.aws_account_id }}:role/${{ vars.aws_role }} - role-session-name: GitHubActions - - - name: Init - shell: bash - run: | - cd tf/service - terraform init - - - name: Deploy - shell: bash - id: deploy - run: | - cd tf/service - terraform apply -auto-approve -var-file=${{ github.workspace }}/tf/variables.tfvars - - - name: Set env vars - id: set-envs - shell: bash - run: | - cd tf/service - - CLUSTER_NAME=$(terraform output -raw cluster_name) - echo "CLUSTER_NAME=$CLUSTER_NAME" >> $GITHUB_OUTPUT - - SERVICE_NAME=$(terraform output -raw service_name) - echo "SERVICE_NAME=$SERVICE_NAME" >> $GITHUB_OUTPUT - - LB_LISTENER_ARN=$(terraform output -raw lb_listener_arn) - echo "LB_LISTENER_ARN=$LB_LISTENER_ARN" >> $GITHUB_OUTPUT - - - network: - needs: service + check: runs-on: ubuntu-latest env: - TF_VAR_load_balancer_listener_arn: ${{ needs.service.outputs.lb_listener_arn }} + TFVARS_FILE: tf/variables.tfvars outputs: - api_invoke_url: ${{ steps.set-envs.outputs.API_INVOKE_URL }} + service_exists: ${{ steps.check-service-exists.outputs.SERVICE_EXISTS }} steps: - uses: actions/checkout@v4 - - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v4 + - uses: aws-actions/configure-aws-credentials@v4 with: aws-region: ${{ vars.aws_region }} role-to-assume: arn:aws:iam::${{ vars.aws_account_id }}:role/${{ vars.aws_role }} role-session-name: GitHubActions - - name: Init - shell: bash - run: | - cd tf/network - terraform init - - - name: Deploy - shell: bash - id: deploy - run: | - cd tf/network - terraform apply -auto-approve -var-file=${{ github.workspace }}/tf/variables.tfvars - - - name: Set env vars - id: set-envs - shell: bash - run: | - cd tf/network - - API_INVOKE_URL=$(terraform output -raw api_invoke_url) - echo "API_INVOKE_URL=$API_INVOKE_URL" >> $GITHUB_OUTPUT - - check_image: - needs: - - init - - service - runs-on: ubuntu-latest - steps: - - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v4 - with: - aws-region: ${{ vars.aws_region }} - role-to-assume: arn:aws:iam::${{ vars.aws_account_id }}:role/${{ vars.aws_role }} - role-session-name: GitHubActions - - - name: Get current task definition - id: task-def - shell: bash - run: | - TASK_DEF_ARN=$(aws ecs describe-services \ - --cluster ${{ needs.service.outputs.cluster_name }} \ - --services ${{ needs.service.outputs.service_name }} \ - --region ${{ vars.aws_region }} \ - --query 'services[0].taskDefinition' \ - --output text) - echo "TASK_DEF_ARN=$TASK_DEF_ARN" >> $GITHUB_ENV - - - name: Get image from task definition - id: check-image - shell: bash - run: | - CURRENT_IMAGE=$(aws ecs describe-task-definition \ - --task-definition ${{ env.TASK_DEF_ARN }} \ - --region ${{ vars.aws_region }} \ - --query 'taskDefinition.containerDefinitions[*].image' \ - --output text) - echo "CURRENT_IMAGE=$CURRENT_IMAGE" - echo "CURRENT_IMAGE=$CURRENT_IMAGE" >> $GITHUB_ENV - - - name: Compare with Terraform image - id: compare + - name: Read project_name from variables.tfvars + id: read-vars run: | - if [ "${{ env.CURRENT_IMAGE }}" != "${{ needs.init.outputs.image_uri }}" ]; then - echo "ERROR: Image mismatch! Current image: ${{ env.CURRENT_IMAGE }}, Expected: ${{ needs.task.outputs.image_uri }}" - exit 1 - else - echo "Image matched: ${{ env.CURRENT_IMAGE }}" - fi + PROJECT_NAME=$(grep 'project_name' "$TFVARS_FILE" | sed 's/.*= "\(.*\)"/\1/') + echo "Extracted Project Name: $PROJECT_NAME" + echo "PROJECT_NAME=$PROJECT_NAME" >> $GITHUB_ENV - check_response: - needs: - - network - - service - runs-on: ubuntu-latest - steps: - - name: Make API request - id: curl_request + - name: Check if ECS service exists + id: check-service-exists run: | - RESPONSE=$(curl -s ${{ needs.network.outputs.api_invoke_url}}/host) - echo "Response: $RESPONSE" - echo "$RESPONSE" | jq - - - name: Assert API response contains expected fields - run: | - RESPONSE=$(curl -s ${{ needs.network.outputs.api_invoke_url}}/host) - echo "$RESPONSE" | jq + SERVICE_NAME=$(aws ecs describe-services \ + --cluster \ + --services ${{ steps.read-vars.outputs.read-vars.PROJECT_NAME }} \ + --query 'services[0].status' \ + --region ${{ vars.aws_region }} \ + --output text 2>/dev/null || echo "NOT_FOUND") - # Extract values from response - MESSAGE=$(echo "$RESPONSE" | jq -r '.message') - IMAGE_URI=$(echo "$RESPONSE" | jq -r '.imageUri') - HOSTNAME=$(echo "$RESPONSE" | jq -r '.hostname') - - # Check if expected fields exist - if [[ "$MESSAGE" == "null" || "$IMAGE_URI" == "null" || "$HOSTNAME" == "null" ]]; then - echo "Error: Response does not contain expected fields." - exit 1 + if [ "$SERVICE_NAME" == "NOT_FOUND" ]; then + echo "SERVICE_EXISTS=false" >> $GITHUB_ENV else - echo "API response contains all expected fields." + echo "SERVICE_EXISTS=true" >> $GITHUB_ENV fi + + - name: Set output for service existence + run: echo "SERVICE_EXISTS=${{ env.SERVICE_EXISTS }}" >> $GITHUB_OUTPUT + + init: + needs: check + if: ${{ needs.check.outputs.service_exists == 'false' }} + uses: ./.github/workflows/build.yml + with: + aws_account_id: ${{ vars.AWS_ACCOUNT_ID }} + aws_region: ${{ vars.AWS_REGION }} + aws_role: ${{ vars.AWS_ROLE }} + + # service: + # needs: + # - check + # - init + # if: ${{ needs.check.outputs.service_exists == 'false' }} + # runs-on: ubuntu-latest + # env: + # TF_VAR_task_definition_arn: ${{ needs.init.outputs.task_definition_arn }} + # outputs: + # cluster_name: ${{ steps.set-envs.outputs.CLUSTER_NAME }} + # service_name: ${{ steps.set-envs.outputs.SERVICE_NAME }} + # lb_listener_arn: ${{ steps.set-envs.outputs.LB_LISTENER_ARN }} + # steps: + # - uses: actions/checkout@v4 + # - name: Configure AWS Credentials + # uses: aws-actions/configure-aws-credentials@v4 + # with: + # aws-region: ${{ vars.aws_region }} + # role-to-assume: arn:aws:iam::${{ vars.aws_account_id }}:role/${{ vars.aws_role }} + # role-session-name: GitHubActions + + # - name: Init + # shell: bash + # run: | + # cd tf/service + # terraform init + + # - name: Deploy + # shell: bash + # id: deploy + # run: | + # cd tf/service + # terraform apply -auto-approve -var-file=${{ github.workspace }}/tf/variables.tfvars + + # - name: Set env vars + # id: set-envs + # shell: bash + # run: | + # cd tf/service + # LB_LISTENER_ARN=$(terraform output -raw lb_listener_arn) + # echo "LB_LISTENER_ARN=$LB_LISTENER_ARN" >> $GITHUB_OUTPUT + + + # network: + # needs: + # - check + # - service + # if: ${{ needs.check.outputs.service_exists == 'false' }} + # runs-on: ubuntu-latest + # env: + # TF_VAR_load_balancer_listener_arn: ${{ needs.service.outputs.lb_listener_arn }} + # outputs: + # api_invoke_url: ${{ steps.set-envs.outputs.API_INVOKE_URL }} + # steps: + # - uses: actions/checkout@v4 + # - name: Configure AWS Credentials + # uses: aws-actions/configure-aws-credentials@v4 + # with: + # aws-region: ${{ vars.aws_region }} + # role-to-assume: arn:aws:iam::${{ vars.aws_account_id }}:role/${{ vars.aws_role }} + # role-session-name: GitHubActions + + # - name: Init + # shell: bash + # run: | + # cd tf/network + # terraform init + + # - name: Deploy + # shell: bash + # id: deploy + # run: | + # cd tf/network + # terraform apply -auto-approve -var-file=${{ github.workspace }}/tf/variables.tfvars + + # - name: Set env vars + # id: set-envs + # shell: bash + # run: | + # cd tf/network + # API_INVOKE_URL=$(terraform output -raw api_invoke_url) + # echo "API_INVOKE_URL=$API_INVOKE_URL" >> $GITHUB_OUTPUT \ No newline at end of file From e82ca0be3c4c7e1965a3648843c9a1a8a8b85412 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Mon, 30 Sep 2024 14:19:30 +0100 Subject: [PATCH 052/116] cluster check --- .github/workflows/setup.yml | 23 ++++++++++++++++++----- tf/service/ecs/main.tf | 2 +- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/.github/workflows/setup.yml b/.github/workflows/setup.yml index 363adc3..c7bb1a2 100644 --- a/.github/workflows/setup.yml +++ b/.github/workflows/setup.yml @@ -32,17 +32,30 @@ jobs: echo "Extracted Project Name: $PROJECT_NAME" echo "PROJECT_NAME=$PROJECT_NAME" >> $GITHUB_ENV + - name: Check if ECS cluster exists + id: check-cluster-exists + run: | + CLUSTER_STATUS=$(aws ecs describe-clusters \ + --clusters ${{ env.PROJECT_NAME }} \ + --region ${{ vars.aws_region }} \ + --query 'clusters[0].status' \ + --output text 2>/dev/null || echo "NOT_FOUND") + + echo "Cluster status: $CLUSTER_STATUS" + echo "CLUSTER_STATUS=$CLUSTER_STATUS" >> $GITHUB_ENV + - name: Check if ECS service exists id: check-service-exists + if: ${{ env.CLUSTER_STATUS != 'NOT_FOUND' }} run: | - SERVICE_NAME=$(aws ecs describe-services \ - --cluster \ - --services ${{ steps.read-vars.outputs.read-vars.PROJECT_NAME }} \ + SERVICE_STATUS=$(aws ecs describe-services \ + --cluster ${{ env.PROJECT_NAME }} \ + --services ${{ env.PROJECT_NAME }} \ --query 'services[0].status' \ --region ${{ vars.aws_region }} \ --output text 2>/dev/null || echo "NOT_FOUND") - - if [ "$SERVICE_NAME" == "NOT_FOUND" ]; then + + if [ "$SERVICE_STATUS" == "NOT_FOUND" ]; then echo "SERVICE_EXISTS=false" >> $GITHUB_ENV else echo "SERVICE_EXISTS=true" >> $GITHUB_ENV diff --git a/tf/service/ecs/main.tf b/tf/service/ecs/main.tf index 21543da..c20c938 100644 --- a/tf/service/ecs/main.tf +++ b/tf/service/ecs/main.tf @@ -1,5 +1,5 @@ resource "aws_ecs_cluster" "cluster" { - name = "${var.project_name}-cluster" + name = var.project_name } resource "aws_security_group" "ecs_sg" { From 30052e07c6be7a5f5b8723df19df99646f1b297c Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Mon, 30 Sep 2024 14:23:20 +0100 Subject: [PATCH 053/116] fix output --- .github/workflows/setup.yml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/.github/workflows/setup.yml b/.github/workflows/setup.yml index c7bb1a2..0c6a3dd 100644 --- a/.github/workflows/setup.yml +++ b/.github/workflows/setup.yml @@ -9,16 +9,17 @@ on: permissions: id-token: write contents: read - + jobs: check: runs-on: ubuntu-latest env: TFVARS_FILE: tf/variables.tfvars outputs: - service_exists: ${{ steps.check-service-exists.outputs.SERVICE_EXISTS }} + service_exists: ${{ steps.set-output.outputs.SERVICE_EXISTS }} # Correct output reference steps: - uses: actions/checkout@v4 + - uses: aws-actions/configure-aws-credentials@v4 with: aws-region: ${{ vars.aws_region }} @@ -62,17 +63,19 @@ jobs: fi - name: Set output for service existence + id: set-output run: echo "SERVICE_EXISTS=${{ env.SERVICE_EXISTS }}" >> $GITHUB_OUTPUT - + init: needs: check - if: ${{ needs.check.outputs.service_exists == 'false' }} + if: ${{ needs.check.outputs.service_exists == 'false' }} uses: ./.github/workflows/build.yml with: aws_account_id: ${{ vars.AWS_ACCOUNT_ID }} aws_region: ${{ vars.AWS_REGION }} aws_role: ${{ vars.AWS_ROLE }} + # service: # needs: # - check From 6c602a162d56e697ed730693c74b4f661239762b Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Mon, 30 Sep 2024 14:27:40 +0100 Subject: [PATCH 054/116] service and network deploy --- .github/workflows/setup.yml | 158 ++++++++++++++++++------------------ 1 file changed, 78 insertions(+), 80 deletions(-) diff --git a/.github/workflows/setup.yml b/.github/workflows/setup.yml index 0c6a3dd..d60f891 100644 --- a/.github/workflows/setup.yml +++ b/.github/workflows/setup.yml @@ -75,87 +75,85 @@ jobs: aws_region: ${{ vars.AWS_REGION }} aws_role: ${{ vars.AWS_ROLE }} + service: + needs: + - check + - init + if: ${{ needs.check.outputs.service_exists == 'false' }} + runs-on: ubuntu-latest + env: + TF_VAR_task_definition_arn: ${{ needs.init.outputs.task_definition_arn }} + outputs: + cluster_name: ${{ steps.set-envs.outputs.CLUSTER_NAME }} + service_name: ${{ steps.set-envs.outputs.SERVICE_NAME }} + lb_listener_arn: ${{ steps.set-envs.outputs.LB_LISTENER_ARN }} + steps: + - uses: actions/checkout@v4 + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + aws-region: ${{ vars.aws_region }} + role-to-assume: arn:aws:iam::${{ vars.aws_account_id }}:role/${{ vars.aws_role }} + role-session-name: GitHubActions - # service: - # needs: - # - check - # - init - # if: ${{ needs.check.outputs.service_exists == 'false' }} - # runs-on: ubuntu-latest - # env: - # TF_VAR_task_definition_arn: ${{ needs.init.outputs.task_definition_arn }} - # outputs: - # cluster_name: ${{ steps.set-envs.outputs.CLUSTER_NAME }} - # service_name: ${{ steps.set-envs.outputs.SERVICE_NAME }} - # lb_listener_arn: ${{ steps.set-envs.outputs.LB_LISTENER_ARN }} - # steps: - # - uses: actions/checkout@v4 - # - name: Configure AWS Credentials - # uses: aws-actions/configure-aws-credentials@v4 - # with: - # aws-region: ${{ vars.aws_region }} - # role-to-assume: arn:aws:iam::${{ vars.aws_account_id }}:role/${{ vars.aws_role }} - # role-session-name: GitHubActions - - # - name: Init - # shell: bash - # run: | - # cd tf/service - # terraform init + - name: Init + shell: bash + run: | + cd tf/service + terraform init - # - name: Deploy - # shell: bash - # id: deploy - # run: | - # cd tf/service - # terraform apply -auto-approve -var-file=${{ github.workspace }}/tf/variables.tfvars - - # - name: Set env vars - # id: set-envs - # shell: bash - # run: | - # cd tf/service - # LB_LISTENER_ARN=$(terraform output -raw lb_listener_arn) - # echo "LB_LISTENER_ARN=$LB_LISTENER_ARN" >> $GITHUB_OUTPUT - - - # network: - # needs: - # - check - # - service - # if: ${{ needs.check.outputs.service_exists == 'false' }} - # runs-on: ubuntu-latest - # env: - # TF_VAR_load_balancer_listener_arn: ${{ needs.service.outputs.lb_listener_arn }} - # outputs: - # api_invoke_url: ${{ steps.set-envs.outputs.API_INVOKE_URL }} - # steps: - # - uses: actions/checkout@v4 - # - name: Configure AWS Credentials - # uses: aws-actions/configure-aws-credentials@v4 - # with: - # aws-region: ${{ vars.aws_region }} - # role-to-assume: arn:aws:iam::${{ vars.aws_account_id }}:role/${{ vars.aws_role }} - # role-session-name: GitHubActions - - # - name: Init - # shell: bash - # run: | - # cd tf/network - # terraform init + - name: Deploy + shell: bash + id: deploy + run: | + cd tf/service + terraform apply -auto-approve -var-file=${{ github.workspace }}/tf/variables.tfvars + + - name: Set env vars + id: set-envs + shell: bash + run: | + cd tf/service + LB_LISTENER_ARN=$(terraform output -raw lb_listener_arn) + echo "LB_LISTENER_ARN=$LB_LISTENER_ARN" >> $GITHUB_OUTPUT + + network: + needs: + - check + - service + if: ${{ needs.check.outputs.service_exists == 'false' }} + runs-on: ubuntu-latest + env: + TF_VAR_load_balancer_listener_arn: ${{ needs.service.outputs.lb_listener_arn }} + outputs: + api_invoke_url: ${{ steps.set-envs.outputs.API_INVOKE_URL }} + steps: + - uses: actions/checkout@v4 + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + aws-region: ${{ vars.aws_region }} + role-to-assume: arn:aws:iam::${{ vars.aws_account_id }}:role/${{ vars.aws_role }} + role-session-name: GitHubActions + + - name: Init + shell: bash + run: | + cd tf/network + terraform init - # - name: Deploy - # shell: bash - # id: deploy - # run: | - # cd tf/network - # terraform apply -auto-approve -var-file=${{ github.workspace }}/tf/variables.tfvars - - # - name: Set env vars - # id: set-envs - # shell: bash - # run: | - # cd tf/network - # API_INVOKE_URL=$(terraform output -raw api_invoke_url) - # echo "API_INVOKE_URL=$API_INVOKE_URL" >> $GITHUB_OUTPUT + - name: Deploy + shell: bash + id: deploy + run: | + cd tf/network + terraform apply -auto-approve -var-file=${{ github.workspace }}/tf/variables.tfvars + + - name: Set env vars + id: set-envs + shell: bash + run: | + cd tf/network + API_INVOKE_URL=$(terraform output -raw api_invoke_url) + echo "API_INVOKE_URL=$API_INVOKE_URL" >> $GITHUB_OUTPUT \ No newline at end of file From f1e225a243634a8560f91ec68fe664a116cd143c Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Mon, 30 Sep 2024 15:12:23 +0100 Subject: [PATCH 055/116] mv check to action file --- .github/actions/check_svc/action.yml | 65 ++++++++++++++++++++++++++++ .github/workflows/setup.yml | 55 +++-------------------- 2 files changed, 72 insertions(+), 48 deletions(-) create mode 100644 .github/actions/check_svc/action.yml diff --git a/.github/actions/check_svc/action.yml b/.github/actions/check_svc/action.yml new file mode 100644 index 0000000..d34104e --- /dev/null +++ b/.github/actions/check_svc/action.yml @@ -0,0 +1,65 @@ +name: Check ECS Service +description: Check if an ECS cluster and service exist +inputs: + aws_region: + description: 'AWS Region' + required: true + aws_role: + description: 'AWS Role to assume' + required: true + tfvars_file: + description: 'Path to the tfvars file' + required: true +outputs: + service_exists: + description: 'Output whether the service exists or not' +runs: + using: "composite" + steps: + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + aws-region: ${{ inputs.aws_region }} + role-to-assume: arn:aws:iam::${{ inputs.aws_role }} + role-session-name: GitHubActions + + - name: Read project_name from tfvars file + id: read-project-name + run: | + # Extract project_name from tfvars file + PROJECT_NAME=$(grep 'project_name' "${{ inputs.tfvars_file }}" | sed 's/.*= "\(.*\)"/\1/') + echo "Extracted Project Name: $PROJECT_NAME" + echo "PROJECT_NAME=$PROJECT_NAME" >> $GITHUB_ENV + + - name: Check if ECS cluster exists + id: check-cluster-exists + run: | + CLUSTER_STATUS=$(aws ecs describe-clusters \ + --clusters ${{ env.PROJECT_NAME }} \ + --region ${{ inputs.aws_region }} \ + --query 'clusters[0].status' \ + --output text 2>/dev/null || echo "NOT_FOUND") + + echo "Cluster status: $CLUSTER_STATUS" + echo "CLUSTER_STATUS=$CLUSTER_STATUS" >> $GITHUB_ENV + + - name: Check if ECS service exists + id: check-service-exists + if: ${{ env.CLUSTER_STATUS != 'NOT_FOUND' }} + run: | + SERVICE_STATUS=$(aws ecs describe-services \ + --cluster ${{ env.PROJECT_NAME }} \ + --services ${{ env.PROJECT_NAME }} \ + --query 'services[0].status' \ + --region ${{ inputs.aws_region }} \ + --output text 2>/dev/null || echo "NOT_FOUND") + + if [ "$SERVICE_STATUS" == "NOT_FOUND" ]; then + echo "SERVICE_EXISTS=false" >> $GITHUB_ENV + else + echo "SERVICE_EXISTS=true" >> $GITHUB_ENV + fi + + - name: Set output for service existence + id: set-output + run: echo "SERVICE_EXISTS=${{ env.SERVICE_EXISTS }}" >> $GITHUB_OUTPUT diff --git a/.github/workflows/setup.yml b/.github/workflows/setup.yml index d60f891..46232c9 100644 --- a/.github/workflows/setup.yml +++ b/.github/workflows/setup.yml @@ -13,58 +13,17 @@ permissions: jobs: check: runs-on: ubuntu-latest - env: - TFVARS_FILE: tf/variables.tfvars outputs: - service_exists: ${{ steps.set-output.outputs.SERVICE_EXISTS }} # Correct output reference + service_exists: ${{ steps.check-ecs-service.outputs.service_exists }} steps: - uses: actions/checkout@v4 - - - uses: aws-actions/configure-aws-credentials@v4 + - name: Check ECS Service + id: check-ecs-service + uses: ./.github/actions/check_svc with: - aws-region: ${{ vars.aws_region }} - role-to-assume: arn:aws:iam::${{ vars.aws_account_id }}:role/${{ vars.aws_role }} - role-session-name: GitHubActions - - - name: Read project_name from variables.tfvars - id: read-vars - run: | - PROJECT_NAME=$(grep 'project_name' "$TFVARS_FILE" | sed 's/.*= "\(.*\)"/\1/') - echo "Extracted Project Name: $PROJECT_NAME" - echo "PROJECT_NAME=$PROJECT_NAME" >> $GITHUB_ENV - - - name: Check if ECS cluster exists - id: check-cluster-exists - run: | - CLUSTER_STATUS=$(aws ecs describe-clusters \ - --clusters ${{ env.PROJECT_NAME }} \ - --region ${{ vars.aws_region }} \ - --query 'clusters[0].status' \ - --output text 2>/dev/null || echo "NOT_FOUND") - - echo "Cluster status: $CLUSTER_STATUS" - echo "CLUSTER_STATUS=$CLUSTER_STATUS" >> $GITHUB_ENV - - - name: Check if ECS service exists - id: check-service-exists - if: ${{ env.CLUSTER_STATUS != 'NOT_FOUND' }} - run: | - SERVICE_STATUS=$(aws ecs describe-services \ - --cluster ${{ env.PROJECT_NAME }} \ - --services ${{ env.PROJECT_NAME }} \ - --query 'services[0].status' \ - --region ${{ vars.aws_region }} \ - --output text 2>/dev/null || echo "NOT_FOUND") - - if [ "$SERVICE_STATUS" == "NOT_FOUND" ]; then - echo "SERVICE_EXISTS=false" >> $GITHUB_ENV - else - echo "SERVICE_EXISTS=true" >> $GITHUB_ENV - fi - - - name: Set output for service existence - id: set-output - run: echo "SERVICE_EXISTS=${{ env.SERVICE_EXISTS }}" >> $GITHUB_OUTPUT + aws_region: ${{ vars.aws_region }} + aws_role: ${{ vars.aws_account_id }}:role/${{ vars.aws_role }} + tfvars_file: "tf/variables.tfvars" init: needs: check From 4be309a63755b35115bca1b5a0f132a7091ead00 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Mon, 30 Sep 2024 15:14:07 +0100 Subject: [PATCH 056/116] shell: bash --- .github/actions/check_svc/action.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/actions/check_svc/action.yml b/.github/actions/check_svc/action.yml index d34104e..a38b5ad 100644 --- a/.github/actions/check_svc/action.yml +++ b/.github/actions/check_svc/action.yml @@ -25,6 +25,7 @@ runs: - name: Read project_name from tfvars file id: read-project-name + shell: bash run: | # Extract project_name from tfvars file PROJECT_NAME=$(grep 'project_name' "${{ inputs.tfvars_file }}" | sed 's/.*= "\(.*\)"/\1/') @@ -33,6 +34,7 @@ runs: - name: Check if ECS cluster exists id: check-cluster-exists + shell: bash run: | CLUSTER_STATUS=$(aws ecs describe-clusters \ --clusters ${{ env.PROJECT_NAME }} \ @@ -46,6 +48,7 @@ runs: - name: Check if ECS service exists id: check-service-exists if: ${{ env.CLUSTER_STATUS != 'NOT_FOUND' }} + shell: bash run: | SERVICE_STATUS=$(aws ecs describe-services \ --cluster ${{ env.PROJECT_NAME }} \ @@ -62,4 +65,5 @@ runs: - name: Set output for service existence id: set-output + shell: bash run: echo "SERVICE_EXISTS=${{ env.SERVICE_EXISTS }}" >> $GITHUB_OUTPUT From 85fbcf97dbfdfa5dfab935b72342d839ad9b664c Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Mon, 30 Sep 2024 15:42:51 +0100 Subject: [PATCH 057/116] pass in codedeploy_group_name var --- tf/service/deploy/main.tf | 2 +- tf/service/deploy/variables.tf | 4 ++++ tf/service/main.tf | 1 + tf/service/variables.tf | 4 ++++ tf/variables.tfvars | 13 +++++++------ 5 files changed, 17 insertions(+), 7 deletions(-) diff --git a/tf/service/deploy/main.tf b/tf/service/deploy/main.tf index d09d12b..f3b970a 100644 --- a/tf/service/deploy/main.tf +++ b/tf/service/deploy/main.tf @@ -14,7 +14,7 @@ resource "aws_iam_role_policy" "codedeploy_role_policy" { } resource "aws_codedeploy_deployment_group" "this" { - app_name = aws_codedeploy_app.ecs_app.name + app_name = var.codedeploy_group_name # Shifts 10% of the traffic in the first increment, then shifts the remaining 90% after 5 minutes deployment_config_name = "CodeDeployDefault.ECSCanary10Percent5Minutes" deployment_group_name = "${var.project_name}-blue-green-group" diff --git a/tf/service/deploy/variables.tf b/tf/service/deploy/variables.tf index 744dc2d..6c22b3a 100644 --- a/tf/service/deploy/variables.tf +++ b/tf/service/deploy/variables.tf @@ -18,6 +18,10 @@ variable "codedeploy_app_name" { type = string } +variable "codedeploy_group_name" { + type = string +} + variable "lb_listener_arn" { type = string } diff --git a/tf/service/main.tf b/tf/service/main.tf index a9bacbe..0b25391 100644 --- a/tf/service/main.tf +++ b/tf/service/main.tf @@ -29,6 +29,7 @@ module "deploy" { project_name = var.project_name codedeploy_app_name = var.codedeploy_app_name + codedeploy_group_name = var.codedeploy_group_name region = var.region cluster_name = module.ecs.cluster_name service_name = module.ecs.service_name diff --git a/tf/service/variables.tf b/tf/service/variables.tf index f82d372..e359f47 100644 --- a/tf/service/variables.tf +++ b/tf/service/variables.tf @@ -6,6 +6,10 @@ variable "codedeploy_app_name" { type = string } +variable "codedeploy_group_name" { + type = string +} + variable "region" { type = string } diff --git a/tf/variables.tfvars b/tf/variables.tfvars index 3d7592f..64702af 100644 --- a/tf/variables.tfvars +++ b/tf/variables.tfvars @@ -1,6 +1,7 @@ -project_name = "fargate-auto-scaled-backend" -codedeploy_app_name = "fargate-auto-scaled-backend-ecs-codedeploy" -region = "eu-west-2" -private_vpc_name = "ecs-private-vpc" -api_stage_name = "dev" -container_port = 3000 \ No newline at end of file +project_name = "fargate-auto-scaled-backend" +codedeploy_app_name = "fargate-auto-scaled-backend-ecs-codedeploy" +codedeploy_group_name = "fargate-auto-scaled-backend-ecs-deploy-group" +region = "eu-west-2" +private_vpc_name = "ecs-private-vpc" +api_stage_name = "dev" +container_port = 3000 \ No newline at end of file From 930b4fe4b4d115c1f4249d95c1dcff6cfd69ce67 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Mon, 30 Sep 2024 15:46:34 +0100 Subject: [PATCH 058/116] rm setup trigger --- .github/workflows/setup.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/setup.yml b/.github/workflows/setup.yml index 46232c9..1615958 100644 --- a/.github/workflows/setup.yml +++ b/.github/workflows/setup.yml @@ -1,9 +1,6 @@ name: Setup on: - push: - branches: - - 'blue-green-deploy' workflow_dispatch: permissions: From 1e034af6e8d6d728c39cbd4ac89d454ced51d68f Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Mon, 30 Sep 2024 16:37:26 +0100 Subject: [PATCH 059/116] create deployment in ci --- .github/workflows/deploy.yml | 313 ++++++++++------------------------- appspec.json | 18 ++ 2 files changed, 102 insertions(+), 229 deletions(-) create mode 100644 appspec.json diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index cb23f17..d861928 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -1,251 +1,106 @@ -name: Deploy +name: Setup on: + push: + branches: + - 'blue-green-deploy' workflow_dispatch: -env: - aws_account_id: ${{ vars.AWS_ACCOUNT_ID }} - aws_region: ${{ vars.AWS_REGION }} - aws_role: ${{ vars.AWS_ROLE }} - permissions: id-token: write contents: read jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v4 - with: - aws-region: ${{ env.aws_region }} - role-to-assume: arn:aws:iam::${{ env.aws_account_id }}:role/${{ env.aws_role }} - role-session-name: GitHubActions - - - name: Init - shell: bash - run: | - cd tf/ecr - terraform init - - - name: Deploy - shell: bash - id: deploy - run: | - cd tf/ecr - terraform apply -auto-approve -var-file=${{ github.workspace }}/tf/variables.tfvars - - - name: Build and push detected changes - id: build-image - uses: ./.github/actions/build_image - with: - aws_account_id: ${{ vars.AWS_ACCOUNT_ID }} - aws_region: ${{ vars.AWS_REGION }} - - task: - needs: build - runs-on: ubuntu-latest - outputs: - task_definition_arn: ${{ steps.set-envs.outputs.TASK_DEFINITION_ARN }} - image_uri: ${{ steps.set-envs.outputs.IMAGE_URI }} - steps: - - uses: actions/checkout@v4 - - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v4 - with: - aws-region: ${{ env.aws_region }} - role-to-assume: arn:aws:iam::${{ env.aws_account_id }}:role/${{ env.aws_role }} - role-session-name: GitHubActions - - - name: Init - shell: bash - run: | - cd tf/task - terraform init - - - name: Deploy - shell: bash - id: deploy - run: | - cd tf/task - terraform apply -auto-approve -var-file=${{ github.workspace }}/tf/variables.tfvars - - - name: Set env vars - id: set-envs - shell: bash - run: | - cd tf/task - - TASK_DEFINITION_ARN=$(terraform output -raw task_definition_arn) - echo "TASK_DEFINITION_ARN=$TASK_DEFINITION_ARN" >> $GITHUB_OUTPUT - - IMAGE_URI=$(terraform output -raw image_uri) - echo "IMAGE_URI=$IMAGE_URI" >> $GITHUB_OUTPUT - - service: - needs: - - build - - task + code: + uses: ./.github/workflows/build.yml + with: + aws_account_id: ${{ vars.AWS_ACCOUNT_ID }} + aws_region: ${{ vars.AWS_REGION }} + aws_role: ${{ vars.AWS_ROLE }} + + deploy: runs-on: ubuntu-latest env: - TF_VAR_task_definition_arn: ${{ needs.task.outputs.task_definition_arn }} - outputs: - cluster_name: ${{ steps.set-envs.outputs.CLUSTER_NAME }} - service_name: ${{ steps.set-envs.outputs.SERVICE_NAME }} - lb_listener_arn: ${{ steps.set-envs.outputs.LB_LISTENER_ARN }} + TF_VAR_FILE: tf/variables.tfvars steps: - uses: actions/checkout@v4 - - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v4 + - uses: aws-actions/configure-aws-credentials@v4 with: - aws-region: ${{ env.aws_region }} - role-to-assume: arn:aws:iam::${{ env.aws_account_id }}:role/${{ env.aws_role }} + aws-region: ${{ inputs.aws_region }} + role-to-assume: arn:aws:iam::${{ inputs.aws_account_id }}:role/${{ inputs.aws_role }} role-session-name: GitHubActions - - name: Init - shell: bash - run: | - cd tf/service - terraform init - - - name: Deploy + - name: Read code deploy app vars from tfvars file + id: read-vars shell: bash - id: deploy run: | - cd tf/service - terraform apply -auto-approve -var-file=${{ github.workspace }}/tf/variables.tfvars - - - name: Set env vars - id: set-envs - shell: bash - run: | - cd tf/service - - CLUSTER_NAME=$(terraform output -raw cluster_name) - echo "CLUSTER_NAME=$CLUSTER_NAME" >> $GITHUB_OUTPUT - - SERVICE_NAME=$(terraform output -raw service_name) - echo "SERVICE_NAME=$SERVICE_NAME" >> $GITHUB_OUTPUT - - LB_LISTENER_ARN=$(terraform output -raw lb_listener_arn) - echo "LB_LISTENER_ARN=$LB_LISTENER_ARN" >> $GITHUB_OUTPUT - - - network: - needs: service - runs-on: ubuntu-latest - env: - TF_VAR_load_balancer_listener_arn: ${{ needs.service.outputs.lb_listener_arn }} - outputs: - api_invoke_url: ${{ steps.set-envs.outputs.API_INVOKE_URL }} - steps: - - uses: actions/checkout@v4 - - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v4 - with: - aws-region: ${{ env.aws_region }} - role-to-assume: arn:aws:iam::${{ env.aws_account_id }}:role/${{ env.aws_role }} - role-session-name: GitHubActions - - - name: Init - shell: bash - run: | - cd tf/network - terraform init - - - name: Deploy - shell: bash - id: deploy - run: | - cd tf/network - terraform apply -auto-approve -var-file=${{ github.workspace }}/tf/variables.tfvars - - - name: Set env vars - id: set-envs - shell: bash - run: | - cd tf/network - - API_INVOKE_URL=$(terraform output -raw api_invoke_url) - echo "API_INVOKE_URL=$API_INVOKE_URL" >> $GITHUB_OUTPUT - - check_image: - needs: - - task - - service - runs-on: ubuntu-latest - steps: - - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v4 - with: - aws-region: ${{ env.aws_region }} - role-to-assume: arn:aws:iam::${{ env.aws_account_id }}:role/${{ env.aws_role }} - role-session-name: GitHubActions - - - name: Get current task definition - id: task-def - shell: bash - run: | - TASK_DEF_ARN=$(aws ecs describe-services \ - --cluster ${{ needs.service.outputs.cluster_name }} \ - --services ${{ needs.service.outputs.service_name }} \ - --region ${{ env.aws_region }} \ - --query 'services[0].taskDefinition' \ - --output text) - echo "TASK_DEF_ARN=$TASK_DEF_ARN" >> $GITHUB_ENV - - - name: Get image from task definition - id: check-image - shell: bash - run: | - CURRENT_IMAGE=$(aws ecs describe-task-definition \ - --task-definition ${{ env.TASK_DEF_ARN }} \ - --region ${{ env.aws_region }} \ - --query 'taskDefinition.containerDefinitions[*].image' \ - --output text) - echo "CURRENT_IMAGE=$CURRENT_IMAGE" - echo "CURRENT_IMAGE=$CURRENT_IMAGE" >> $GITHUB_ENV - - - name: Compare with Terraform image - id: compare - run: | - if [ "${{ env.CURRENT_IMAGE }}" != "${{ needs.task.outputs.image_uri }}" ]; then - echo "ERROR: Image mismatch! Current image: ${{ env.CURRENT_IMAGE }}, Expected: ${{ needs.task.outputs.image_uri }}" + CODE_DEPLOY_APP_NAME=$(grep 'codedeploy_app_name' "${{ env.TF_VAR_FILE }}" | sed 's/.*= "\(.*\)"/\1/') + echo "Extracted codedeploy_app_name: $CODE_DEPLOY_APP_NAME" + echo "CODE_DEPLOY_APP_NAME=$CODE_DEPLOY_APP_NAME" >> $GITHUB_ENV + + CODE_DEPLOY_GROUP_NAME=$(grep 'codedeploy_group_name' "${{ env.TF_VAR_FILE }}" | sed 's/.*= "\(.*\)"/\1/') + echo "Extracted codedeploy_group_name: $CODE_DEPLOY_APP_NAME" + echo "CODE_DEPLOY_GROUP_NAME=$CODE_DEPLOY_GROUP_NAME" >> $GITHUB_ENV + + CONTAINER_PORT=$(grep 'container_port' "${{ env.TF_VAR_FILE }}" | sed 's/.*= "\(.*\)"/\1/') + echo "Extracted container_port: $CONTAINER_PORT" + echo "CONTAINER_PORT=$CONTAINER_PORT" >> $GITHUB_ENV + + PROJECT_NAME=$(grep 'project_name' "${{ env.TF_VAR_FILE }}" | sed 's/.*= "\(.*\)"/\1/') + echo "Extracted project_name: $PROJECT_NAME" + echo "PROJECT_NAME=$PROJECT_NAME" >> $GITHUB_ENV + + # Step 3: Replace placeholders in the appspec.json file + - name: Prepare AppSpec File + run: | + sed -i 's|{{TASK_DEFINITION_ARN}}|${{ needs.init.outputs.task_definition_arn }}|g' appspec.json + sed -i 's|{{CONTAINER_NAME}}|${{ steps.read-vars.outputs.project_name }}|g' appspec.json + sed -i 's|{{CONTAINER_PORT}}|${{ steps.read-vars.outputs.container_port }}|g' appspec.json + cat appspec.json + + # Step 4: Create CodeDeploy Deployment + - name: Create CodeDeploy Deployment + run: | + echo "Creating CodeDeploy deployment" + aws deploy create-deployment \ + --application-name "${{ steps.read-vars.outputs.CODEDEPLOY_APP_NAME }}" \ + --deployment-group-name "${{ steps.read-vars.outputs.CODE_DEPLOY_GROUP_NAME }}" \ + --deployment-config-name CodeDeployDefault.ECSAllAtOnce \ + --revision "revisionType=AppSpecContent,appSpecContent={\"content\":\"$(cat appspec.json | jq -c .)\"}" \ + --region ${{ vars.AWS_REGION }} + + # Step 5: Monitor Deployment Status + - name: Monitor Deployment Status + run: | + echo "Monitoring CodeDeploy deployment status" + DEPLOYMENT_ID=$(aws deploy list-deployments \ + --application-name "${{ steps.read-vars.outputs.CODEDEPLOY_APP_NAME }}" \ + --deployment-group-name "${{ steps.read-vars.outputs.CODE_DEPLOY_GROUP_NAME }}" \ + --region ${{ vars.AWS_REGION }} \ + --max-items 1 \ + --query 'deployments[0]' --output text) + + if [ "$DEPLOYMENT_ID" == "None" ]; then + echo "No deployment found." exit 1 - else - echo "Image matched: ${{ env.CURRENT_IMAGE }}" fi - check_response: - needs: - - network - - service - runs-on: ubuntu-latest - steps: - - name: Make API request - id: curl_request - run: | - RESPONSE=$(curl -s ${{ needs.network.outputs.api_invoke_url}}/host) - echo "Response: $RESPONSE" - echo "$RESPONSE" | jq - - - name: Assert API response contains expected fields - run: | - RESPONSE=$(curl -s ${{ needs.network.outputs.api_invoke_url}}/host) - echo "$RESPONSE" | jq + echo "Deployment ID: $DEPLOYMENT_ID" - # Extract values from response - MESSAGE=$(echo "$RESPONSE" | jq -r '.message') - IMAGE_URI=$(echo "$RESPONSE" | jq -r '.imageUri') - HOSTNAME=$(echo "$RESPONSE" | jq -r '.hostname') - - # Check if expected fields exist - if [[ "$MESSAGE" == "null" || "$IMAGE_URI" == "null" || "$HOSTNAME" == "null" ]]; then - echo "Error: Response does not contain expected fields." - exit 1 - else - echo "API response contains all expected fields." - fi - \ No newline at end of file + # Loop to check the deployment status + while true; do + STATUS=$(aws deploy get-deployment --deployment-id $DEPLOYMENT_ID --query 'deploymentInfo.status' --output text) + + echo "Deployment status: $STATUS" + + if [[ "$STATUS" == "Succeeded" ]]; then + echo "Deployment succeeded!" + break + elif [[ "$STATUS" == "Failed" || "$STATUS" == "Stopped" ]]; then + echo "Deployment failed!" + exit 1 + else + echo "Deployment is in progress..." + sleep 30 + fi + done \ No newline at end of file diff --git a/appspec.json b/appspec.json new file mode 100644 index 0000000..a2fd81f --- /dev/null +++ b/appspec.json @@ -0,0 +1,18 @@ +{ + "version": "0.0", + "Resources": [ + { + "TargetService": { + "Type": "AWS::ECS::Service", + "Properties": { + "TaskDefinition": "{{TASK_DEFINITION_ARN}}", + "LoadBalancerInfo": { + "ContainerName": "{{CONTAINER_NAME}}", + "ContainerPort": {{CONTAINER_PORT}} + } + } + } + } + ] + } + \ No newline at end of file From 6ea3cb9ad9767cf7b84e68b310b05aa380735ff7 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Mon, 30 Sep 2024 16:40:36 +0100 Subject: [PATCH 060/116] ci job order fix --- .github/workflows/deploy.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index d861928..1ec41c0 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -19,6 +19,7 @@ jobs: aws_role: ${{ vars.AWS_ROLE }} deploy: + needs: code runs-on: ubuntu-latest env: TF_VAR_FILE: tf/variables.tfvars From 294791034c3054cd27e2ce5e46b1bced3bdb19fb Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Mon, 30 Sep 2024 16:44:02 +0100 Subject: [PATCH 061/116] fix --- .github/workflows/deploy.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 1ec41c0..263d62a 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -1,4 +1,4 @@ -name: Setup +name: Deploy on: push: @@ -27,8 +27,8 @@ jobs: - uses: actions/checkout@v4 - uses: aws-actions/configure-aws-credentials@v4 with: - aws-region: ${{ inputs.aws_region }} - role-to-assume: arn:aws:iam::${{ inputs.aws_account_id }}:role/${{ inputs.aws_role }} + aws-region: ${{ vars.AWS_REGION }} + role-to-assume: arn:aws:iam::${{ vars.AWS_ACCOUNT_ID }}:role/${{ vars.AWS_ROLE }} role-session-name: GitHubActions - name: Read code deploy app vars from tfvars file From 928d9ef591641ad959c4613d8d74ae2cedbe5d3a Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Mon, 30 Sep 2024 16:53:45 +0100 Subject: [PATCH 062/116] add revision as version --- .github/workflows/build.yml | 4 ++++ .github/workflows/deploy.yml | 3 ++- appspec.json | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1840376..32d1f3c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -16,6 +16,9 @@ on: task_definition_arn: description: "The ARN of the deployed task definition" value: ${{ jobs.task.outputs.task_definition_arn }} + task_definition_revsion: + description: "The revision of the deployed task definition" + value: ${{ jobs.task.outputs.task_definition_revision }} image_uri: value: ${{ jobs.build.outputs.image_uri }} @@ -79,6 +82,7 @@ jobs: TF_VAR_image_uri: ${{ needs.build.outputs.image_uri }} outputs: task_definition_arn: ${{ steps.set-envs.outputs.TASK_DEFINITION_ARN }} + task_definition_revision: ${{ steps.set-envs.outputs.TASK_DEFINITION_REVISION }} steps: - uses: actions/checkout@v4 - uses: aws-actions/configure-aws-credentials@v4 diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 263d62a..e34f1d5 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -43,7 +43,7 @@ jobs: echo "Extracted codedeploy_group_name: $CODE_DEPLOY_APP_NAME" echo "CODE_DEPLOY_GROUP_NAME=$CODE_DEPLOY_GROUP_NAME" >> $GITHUB_ENV - CONTAINER_PORT=$(grep 'container_port' "${{ env.TF_VAR_FILE }}" | sed 's/.*= "\(.*\)"/\1/') + CONTAINER_PORT=$(grep 'container_port' "${{ env.TF_VAR_FILE }}" | sed 's/.*= //') echo "Extracted container_port: $CONTAINER_PORT" echo "CONTAINER_PORT=$CONTAINER_PORT" >> $GITHUB_ENV @@ -54,6 +54,7 @@ jobs: # Step 3: Replace placeholders in the appspec.json file - name: Prepare AppSpec File run: | + sed -i 's|{{TASK_VERSION}}|${{ needs.init.outputs.task.task_definition_revision }}|g' appspec.json sed -i 's|{{TASK_DEFINITION_ARN}}|${{ needs.init.outputs.task_definition_arn }}|g' appspec.json sed -i 's|{{CONTAINER_NAME}}|${{ steps.read-vars.outputs.project_name }}|g' appspec.json sed -i 's|{{CONTAINER_PORT}}|${{ steps.read-vars.outputs.container_port }}|g' appspec.json diff --git a/appspec.json b/appspec.json index a2fd81f..d940e67 100644 --- a/appspec.json +++ b/appspec.json @@ -1,5 +1,5 @@ { - "version": "0.0", + "version": "{{TASK_VERSION}}", "Resources": [ { "TargetService": { From bcdf9af4a843ed83564cb515cfa6ff4a1e153d23 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Mon, 30 Sep 2024 17:01:08 +0100 Subject: [PATCH 063/116] $GITHUB_OUTPUT --- .github/workflows/deploy.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index e34f1d5..abc88df 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -37,25 +37,25 @@ jobs: run: | CODE_DEPLOY_APP_NAME=$(grep 'codedeploy_app_name' "${{ env.TF_VAR_FILE }}" | sed 's/.*= "\(.*\)"/\1/') echo "Extracted codedeploy_app_name: $CODE_DEPLOY_APP_NAME" - echo "CODE_DEPLOY_APP_NAME=$CODE_DEPLOY_APP_NAME" >> $GITHUB_ENV + echo "CODE_DEPLOY_APP_NAME=$CODE_DEPLOY_APP_NAME" >> $GITHUB_OUTPUT CODE_DEPLOY_GROUP_NAME=$(grep 'codedeploy_group_name' "${{ env.TF_VAR_FILE }}" | sed 's/.*= "\(.*\)"/\1/') echo "Extracted codedeploy_group_name: $CODE_DEPLOY_APP_NAME" - echo "CODE_DEPLOY_GROUP_NAME=$CODE_DEPLOY_GROUP_NAME" >> $GITHUB_ENV + echo "CODE_DEPLOY_GROUP_NAME=$CODE_DEPLOY_GROUP_NAME" >> $GITHUB_OUTPUT CONTAINER_PORT=$(grep 'container_port' "${{ env.TF_VAR_FILE }}" | sed 's/.*= //') echo "Extracted container_port: $CONTAINER_PORT" - echo "CONTAINER_PORT=$CONTAINER_PORT" >> $GITHUB_ENV + echo "CONTAINER_PORT=$CONTAINER_PORT" >> $GITHUB_OUTPUT PROJECT_NAME=$(grep 'project_name' "${{ env.TF_VAR_FILE }}" | sed 's/.*= "\(.*\)"/\1/') echo "Extracted project_name: $PROJECT_NAME" - echo "PROJECT_NAME=$PROJECT_NAME" >> $GITHUB_ENV + echo "PROJECT_NAME=$PROJECT_NAME" >> $GITHUB_OUTPUT # Step 3: Replace placeholders in the appspec.json file - name: Prepare AppSpec File run: | - sed -i 's|{{TASK_VERSION}}|${{ needs.init.outputs.task.task_definition_revision }}|g' appspec.json - sed -i 's|{{TASK_DEFINITION_ARN}}|${{ needs.init.outputs.task_definition_arn }}|g' appspec.json + sed -i 's|{{TASK_VERSION}}|${{ needs.code.outputs.task_definition_revision }}|g' appspec.json + sed -i 's|{{TASK_DEFINITION_ARN}}|${{ needs.code.outputs.task_definition_arn }}|g' appspec.json sed -i 's|{{CONTAINER_NAME}}|${{ steps.read-vars.outputs.project_name }}|g' appspec.json sed -i 's|{{CONTAINER_PORT}}|${{ steps.read-vars.outputs.container_port }}|g' appspec.json cat appspec.json From b45d2f7fb1c2c798083c89dfd6f8752b194a8924 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Mon, 30 Sep 2024 17:05:11 +0100 Subject: [PATCH 064/116] typo --- .github/workflows/deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index abc88df..0d0f768 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -54,7 +54,7 @@ jobs: # Step 3: Replace placeholders in the appspec.json file - name: Prepare AppSpec File run: | - sed -i 's|{{TASK_VERSION}}|${{ needs.code.outputs.task_definition_revision }}|g' appspec.json + sed -i 's|{{TASK_VERSION}}|${{ needs.code.outputs.task_definition_revsion }}|g' appspec.json sed -i 's|{{TASK_DEFINITION_ARN}}|${{ needs.code.outputs.task_definition_arn }}|g' appspec.json sed -i 's|{{CONTAINER_NAME}}|${{ steps.read-vars.outputs.project_name }}|g' appspec.json sed -i 's|{{CONTAINER_PORT}}|${{ steps.read-vars.outputs.container_port }}|g' appspec.json From 2a75b6f4cc6697abc8a8b77f08aa0e937c9fda0a Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Mon, 30 Sep 2024 17:10:33 +0100 Subject: [PATCH 065/116] escape json --- .github/workflows/deploy.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 0d0f768..96b24d9 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -64,11 +64,13 @@ jobs: - name: Create CodeDeploy Deployment run: | echo "Creating CodeDeploy deployment" + APP_SPEC_CONTENT=$(cat appspec.json | jq -c .) + aws deploy create-deployment \ - --application-name "${{ steps.read-vars.outputs.CODEDEPLOY_APP_NAME }}" \ - --deployment-group-name "${{ steps.read-vars.outputs.CODE_DEPLOY_GROUP_NAME }}" \ + --application-name "${{ env.CODE_DEPLOY_APP_NAME }}" \ + --deployment-group-name "${{ env.CODE_DEPLOY_GROUP_NAME }}" \ --deployment-config-name CodeDeployDefault.ECSAllAtOnce \ - --revision "revisionType=AppSpecContent,appSpecContent={\"content\":\"$(cat appspec.json | jq -c .)\"}" \ + --revision "revisionType=AppSpecContent,appSpecContent={\"content\":\"$APP_SPEC_CONTENT\"}" \ --region ${{ vars.AWS_REGION }} # Step 5: Monitor Deployment Status From a81a2476bc24dc8153fa4da14152b12208175c49 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 1 Oct 2024 09:28:17 +0100 Subject: [PATCH 066/116] setup --- .github/workflows/setup.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/setup.yml b/.github/workflows/setup.yml index 1615958..46232c9 100644 --- a/.github/workflows/setup.yml +++ b/.github/workflows/setup.yml @@ -1,6 +1,9 @@ name: Setup on: + push: + branches: + - 'blue-green-deploy' workflow_dispatch: permissions: From 188f7f5406eb12a85967aee2e6a53350007e9e8c Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 1 Oct 2024 09:51:29 +0100 Subject: [PATCH 067/116] check for inactive cluster --- .github/actions/check_svc/action.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/actions/check_svc/action.yml b/.github/actions/check_svc/action.yml index a38b5ad..63bd3c6 100644 --- a/.github/actions/check_svc/action.yml +++ b/.github/actions/check_svc/action.yml @@ -32,7 +32,7 @@ runs: echo "Extracted Project Name: $PROJECT_NAME" echo "PROJECT_NAME=$PROJECT_NAME" >> $GITHUB_ENV - - name: Check if ECS cluster exists + - name: Check if ECS cluster active id: check-cluster-exists shell: bash run: | @@ -45,6 +45,11 @@ runs: echo "Cluster status: $CLUSTER_STATUS" echo "CLUSTER_STATUS=$CLUSTER_STATUS" >> $GITHUB_ENV + if [ "$CLUSTER_STATUS" == "INACTIVE" ]; then + echo "SERVICE_EXISTS=false" >> $GITHUB_ENV + exit 0 + fi + - name: Check if ECS service exists id: check-service-exists if: ${{ env.CLUSTER_STATUS != 'NOT_FOUND' }} From a241cf1da262c34a77ed5044c4244b776153b13d Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 1 Oct 2024 10:03:55 +0100 Subject: [PATCH 068/116] rm trigger --- .github/workflows/deploy.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 96b24d9..787aeae 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -1,9 +1,9 @@ name: Deploy on: - push: - branches: - - 'blue-green-deploy' + # push: + # branches: + # - 'blue-green-deploy' workflow_dispatch: permissions: From b829ab01ae2a0965ddf1ee627c73e6cc6ffd77f8 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 1 Oct 2024 10:09:56 +0100 Subject: [PATCH 069/116] fix --- .github/actions/check_svc/action.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/actions/check_svc/action.yml b/.github/actions/check_svc/action.yml index 63bd3c6..c5edce6 100644 --- a/.github/actions/check_svc/action.yml +++ b/.github/actions/check_svc/action.yml @@ -47,12 +47,11 @@ runs: if [ "$CLUSTER_STATUS" == "INACTIVE" ]; then echo "SERVICE_EXISTS=false" >> $GITHUB_ENV - exit 0 fi - name: Check if ECS service exists id: check-service-exists - if: ${{ env.CLUSTER_STATUS != 'NOT_FOUND' }} + if: ${{ env.CLUSTER_STATUS == 'ACTIVE' }} shell: bash run: | SERVICE_STATUS=$(aws ecs describe-services \ @@ -68,6 +67,12 @@ runs: echo "SERVICE_EXISTS=true" >> $GITHUB_ENV fi + - name: Override service exists boolean + id: check-service-exists + if: ${{ env.CLUSTER_STATUS != 'ACTIVE' }} + shell: bash + run: echo "SERVICE_EXISTS=false" >> $GITHUB_ENV + - name: Set output for service existence id: set-output shell: bash From ce0c8a2017855d52beafb335f5fb0d980bc9f47d Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 1 Oct 2024 10:11:20 +0100 Subject: [PATCH 070/116] set id --- .github/actions/check_svc/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/check_svc/action.yml b/.github/actions/check_svc/action.yml index c5edce6..479b42c 100644 --- a/.github/actions/check_svc/action.yml +++ b/.github/actions/check_svc/action.yml @@ -68,7 +68,7 @@ runs: fi - name: Override service exists boolean - id: check-service-exists + id: override-service-exists if: ${{ env.CLUSTER_STATUS != 'ACTIVE' }} shell: bash run: echo "SERVICE_EXISTS=false" >> $GITHUB_ENV From d393aed0387efa46a46f778a21f3050a0f258012 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 1 Oct 2024 10:12:09 +0100 Subject: [PATCH 071/116] set bool in $GITHUB_OUTPUT --- .github/actions/check_svc/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/check_svc/action.yml b/.github/actions/check_svc/action.yml index 479b42c..451032f 100644 --- a/.github/actions/check_svc/action.yml +++ b/.github/actions/check_svc/action.yml @@ -71,7 +71,7 @@ runs: id: override-service-exists if: ${{ env.CLUSTER_STATUS != 'ACTIVE' }} shell: bash - run: echo "SERVICE_EXISTS=false" >> $GITHUB_ENV + run: echo "SERVICE_EXISTS=false" >> $GITHUB_OUTPUT - name: Set output for service existence id: set-output From 2c8e0da878d1a718100d4dd5f6ab1622abbd7c46 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 1 Oct 2024 10:27:32 +0100 Subject: [PATCH 072/116] combine --- .github/actions/check_svc/action.yml | 45 +++++++++++----------------- 1 file changed, 18 insertions(+), 27 deletions(-) diff --git a/.github/actions/check_svc/action.yml b/.github/actions/check_svc/action.yml index 451032f..ab62ca3 100644 --- a/.github/actions/check_svc/action.yml +++ b/.github/actions/check_svc/action.yml @@ -32,10 +32,11 @@ runs: echo "Extracted Project Name: $PROJECT_NAME" echo "PROJECT_NAME=$PROJECT_NAME" >> $GITHUB_ENV - - name: Check if ECS cluster active - id: check-cluster-exists + - name: Check if ECS cluster and service exist + id: check-cluster-and-service-exists shell: bash run: | + # Check if the ECS cluster exists and is ACTIVE CLUSTER_STATUS=$(aws ecs describe-clusters \ --clusters ${{ env.PROJECT_NAME }} \ --region ${{ inputs.aws_region }} \ @@ -43,35 +44,25 @@ runs: --output text 2>/dev/null || echo "NOT_FOUND") echo "Cluster status: $CLUSTER_STATUS" - echo "CLUSTER_STATUS=$CLUSTER_STATUS" >> $GITHUB_ENV - if [ "$CLUSTER_STATUS" == "INACTIVE" ]; then - echo "SERVICE_EXISTS=false" >> $GITHUB_ENV - fi - - - name: Check if ECS service exists - id: check-service-exists - if: ${{ env.CLUSTER_STATUS == 'ACTIVE' }} - shell: bash - run: | - SERVICE_STATUS=$(aws ecs describe-services \ - --cluster ${{ env.PROJECT_NAME }} \ - --services ${{ env.PROJECT_NAME }} \ - --query 'services[0].status' \ - --region ${{ inputs.aws_region }} \ - --output text 2>/dev/null || echo "NOT_FOUND") - - if [ "$SERVICE_STATUS" == "NOT_FOUND" ]; then + if [ "$CLUSTER_STATUS" != "ACTIVE" ]; then + # If cluster is not ACTIVE, set service existence to false echo "SERVICE_EXISTS=false" >> $GITHUB_ENV else - echo "SERVICE_EXISTS=true" >> $GITHUB_ENV - fi + # If the cluster is active, check if the service exists + SERVICE_STATUS=$(aws ecs describe-services \ + --cluster ${{ env.PROJECT_NAME }} \ + --services ${{ env.PROJECT_NAME }} \ + --query 'services[0].status' \ + --region ${{ inputs.aws_region }} \ + --output text 2>/dev/null || echo "NOT_FOUND") - - name: Override service exists boolean - id: override-service-exists - if: ${{ env.CLUSTER_STATUS != 'ACTIVE' }} - shell: bash - run: echo "SERVICE_EXISTS=false" >> $GITHUB_OUTPUT + if [ "$SERVICE_STATUS" == "NOT_FOUND" ]; then + echo "SERVICE_EXISTS=false" >> $GITHUB_ENV + else + echo "SERVICE_EXISTS=true" >> $GITHUB_ENV + fi + fi - name: Set output for service existence id: set-output From 842eb782b3be1e8f96865786f9312ae2dce72820 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 1 Oct 2024 10:33:10 +0100 Subject: [PATCH 073/116] debug --- .github/workflows/setup.yml | 166 ++++++++++++++++++------------------ 1 file changed, 84 insertions(+), 82 deletions(-) diff --git a/.github/workflows/setup.yml b/.github/workflows/setup.yml index 46232c9..7b3df23 100644 --- a/.github/workflows/setup.yml +++ b/.github/workflows/setup.yml @@ -24,95 +24,97 @@ jobs: aws_region: ${{ vars.aws_region }} aws_role: ${{ vars.aws_account_id }}:role/${{ vars.aws_role }} tfvars_file: "tf/variables.tfvars" + - name: Display service_exists output + run: echo "service_exists=${{ steps.check-ecs-service.outputs.service_exists }}" - init: - needs: check - if: ${{ needs.check.outputs.service_exists == 'false' }} - uses: ./.github/workflows/build.yml - with: - aws_account_id: ${{ vars.AWS_ACCOUNT_ID }} - aws_region: ${{ vars.AWS_REGION }} - aws_role: ${{ vars.AWS_ROLE }} + # init: + # needs: check + # if: ${{ needs.check.outputs.service_exists == 'false' }} + # uses: ./.github/workflows/build.yml + # with: + # aws_account_id: ${{ vars.AWS_ACCOUNT_ID }} + # aws_region: ${{ vars.AWS_REGION }} + # aws_role: ${{ vars.AWS_ROLE }} - service: - needs: - - check - - init - if: ${{ needs.check.outputs.service_exists == 'false' }} - runs-on: ubuntu-latest - env: - TF_VAR_task_definition_arn: ${{ needs.init.outputs.task_definition_arn }} - outputs: - cluster_name: ${{ steps.set-envs.outputs.CLUSTER_NAME }} - service_name: ${{ steps.set-envs.outputs.SERVICE_NAME }} - lb_listener_arn: ${{ steps.set-envs.outputs.LB_LISTENER_ARN }} - steps: - - uses: actions/checkout@v4 - - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v4 - with: - aws-region: ${{ vars.aws_region }} - role-to-assume: arn:aws:iam::${{ vars.aws_account_id }}:role/${{ vars.aws_role }} - role-session-name: GitHubActions + # service: + # needs: + # - check + # - init + # if: ${{ needs.check.outputs.service_exists == 'false' }} + # runs-on: ubuntu-latest + # env: + # TF_VAR_task_definition_arn: ${{ needs.init.outputs.task_definition_arn }} + # outputs: + # cluster_name: ${{ steps.set-envs.outputs.CLUSTER_NAME }} + # service_name: ${{ steps.set-envs.outputs.SERVICE_NAME }} + # lb_listener_arn: ${{ steps.set-envs.outputs.LB_LISTENER_ARN }} + # steps: + # - uses: actions/checkout@v4 + # - name: Configure AWS Credentials + # uses: aws-actions/configure-aws-credentials@v4 + # with: + # aws-region: ${{ vars.aws_region }} + # role-to-assume: arn:aws:iam::${{ vars.aws_account_id }}:role/${{ vars.aws_role }} + # role-session-name: GitHubActions - - name: Init - shell: bash - run: | - cd tf/service - terraform init + # - name: Init + # shell: bash + # run: | + # cd tf/service + # terraform init - - name: Deploy - shell: bash - id: deploy - run: | - cd tf/service - terraform apply -auto-approve -var-file=${{ github.workspace }}/tf/variables.tfvars + # - name: Deploy + # shell: bash + # id: deploy + # run: | + # cd tf/service + # terraform apply -auto-approve -var-file=${{ github.workspace }}/tf/variables.tfvars - - name: Set env vars - id: set-envs - shell: bash - run: | - cd tf/service - LB_LISTENER_ARN=$(terraform output -raw lb_listener_arn) - echo "LB_LISTENER_ARN=$LB_LISTENER_ARN" >> $GITHUB_OUTPUT + # - name: Set env vars + # id: set-envs + # shell: bash + # run: | + # cd tf/service + # LB_LISTENER_ARN=$(terraform output -raw lb_listener_arn) + # echo "LB_LISTENER_ARN=$LB_LISTENER_ARN" >> $GITHUB_OUTPUT - network: - needs: - - check - - service - if: ${{ needs.check.outputs.service_exists == 'false' }} - runs-on: ubuntu-latest - env: - TF_VAR_load_balancer_listener_arn: ${{ needs.service.outputs.lb_listener_arn }} - outputs: - api_invoke_url: ${{ steps.set-envs.outputs.API_INVOKE_URL }} - steps: - - uses: actions/checkout@v4 - - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v4 - with: - aws-region: ${{ vars.aws_region }} - role-to-assume: arn:aws:iam::${{ vars.aws_account_id }}:role/${{ vars.aws_role }} - role-session-name: GitHubActions + # network: + # needs: + # - check + # - service + # if: ${{ needs.check.outputs.service_exists == 'false' }} + # runs-on: ubuntu-latest + # env: + # TF_VAR_load_balancer_listener_arn: ${{ needs.service.outputs.lb_listener_arn }} + # outputs: + # api_invoke_url: ${{ steps.set-envs.outputs.API_INVOKE_URL }} + # steps: + # - uses: actions/checkout@v4 + # - name: Configure AWS Credentials + # uses: aws-actions/configure-aws-credentials@v4 + # with: + # aws-region: ${{ vars.aws_region }} + # role-to-assume: arn:aws:iam::${{ vars.aws_account_id }}:role/${{ vars.aws_role }} + # role-session-name: GitHubActions - - name: Init - shell: bash - run: | - cd tf/network - terraform init + # - name: Init + # shell: bash + # run: | + # cd tf/network + # terraform init - - name: Deploy - shell: bash - id: deploy - run: | - cd tf/network - terraform apply -auto-approve -var-file=${{ github.workspace }}/tf/variables.tfvars + # - name: Deploy + # shell: bash + # id: deploy + # run: | + # cd tf/network + # terraform apply -auto-approve -var-file=${{ github.workspace }}/tf/variables.tfvars - - name: Set env vars - id: set-envs - shell: bash - run: | - cd tf/network - API_INVOKE_URL=$(terraform output -raw api_invoke_url) - echo "API_INVOKE_URL=$API_INVOKE_URL" >> $GITHUB_OUTPUT + # - name: Set env vars + # id: set-envs + # shell: bash + # run: | + # cd tf/network + # API_INVOKE_URL=$(terraform output -raw api_invoke_url) + # echo "API_INVOKE_URL=$API_INVOKE_URL" >> $GITHUB_OUTPUT \ No newline at end of file From e8630af6ef14e612b5eb514bd74b719c73686a08 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 1 Oct 2024 10:35:03 +0100 Subject: [PATCH 074/116] case service_exists --- .github/actions/check_svc/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/check_svc/action.yml b/.github/actions/check_svc/action.yml index ab62ca3..115b49e 100644 --- a/.github/actions/check_svc/action.yml +++ b/.github/actions/check_svc/action.yml @@ -67,4 +67,4 @@ runs: - name: Set output for service existence id: set-output shell: bash - run: echo "SERVICE_EXISTS=${{ env.SERVICE_EXISTS }}" >> $GITHUB_OUTPUT + run: echo "service_exists=${{ env.SERVICE_EXISTS }}" >> $GITHUB_OUTPUT From 379c1ab836c8ac6dd235df9a50c693ce78ec9b37 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 1 Oct 2024 10:55:51 +0100 Subject: [PATCH 075/116] refactor --- .github/actions/check_svc/action.yml | 8 +- .github/workflows/build.yml | 8 +- .github/workflows/init.yml | 51 ++++++++ .github/workflows/setup.yml | 180 ++++++++++++--------------- 4 files changed, 138 insertions(+), 109 deletions(-) create mode 100644 .github/workflows/init.yml diff --git a/.github/actions/check_svc/action.yml b/.github/actions/check_svc/action.yml index 115b49e..24dfea7 100644 --- a/.github/actions/check_svc/action.yml +++ b/.github/actions/check_svc/action.yml @@ -10,9 +10,7 @@ inputs: tfvars_file: description: 'Path to the tfvars file' required: true -outputs: - service_exists: - description: 'Output whether the service exists or not' + runs: using: "composite" steps: @@ -64,7 +62,3 @@ runs: fi fi - - name: Set output for service existence - id: set-output - shell: bash - run: echo "service_exists=${{ env.SERVICE_EXISTS }}" >> $GITHUB_OUTPUT diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 32d1f3c..017e680 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -20,7 +20,7 @@ on: description: "The revision of the deployed task definition" value: ${{ jobs.task.outputs.task_definition_revision }} image_uri: - value: ${{ jobs.build.outputs.image_uri }} + value: ${{ jobs.image.outputs.image_uri }} permissions: id-token: write @@ -50,7 +50,7 @@ jobs: cd tf/ecr terraform apply -auto-approve -var-file=${{ github.workspace }}/tf/variables.tfvars - build: + image: runs-on: ubuntu-latest outputs: image_uri: ${{ steps.set-image-uri.outputs.image_uri }} @@ -76,10 +76,10 @@ jobs: echo "image_uri=${{ env.IMAGE_URI }}" >> $GITHUB_OUTPUT task: - needs: build + needs: image runs-on: ubuntu-latest env: - TF_VAR_image_uri: ${{ needs.build.outputs.image_uri }} + TF_VAR_image_uri: ${{ needs.image.outputs.image_uri }} outputs: task_definition_arn: ${{ steps.set-envs.outputs.TASK_DEFINITION_ARN }} task_definition_revision: ${{ steps.set-envs.outputs.TASK_DEFINITION_REVISION }} diff --git a/.github/workflows/init.yml b/.github/workflows/init.yml new file mode 100644 index 0000000..a651b19 --- /dev/null +++ b/.github/workflows/init.yml @@ -0,0 +1,51 @@ +name: Init + +on: + push: + branches: + - 'blue-green-deploy' + workflow_dispatch: + +permissions: + id-token: write + contents: read + +jobs: + check: + runs-on: ubuntu-latest + outputs: + service_exists: ${{ steps.set-output.outputs.service_exists }} + steps: + - uses: actions/checkout@v4 + - name: Check ECS Service + id: check-ecs-service + uses: ./.github/actions/check_svc + with: + aws_region: ${{ vars.aws_region }} + aws_role: ${{ vars.aws_account_id }}:role/${{ vars.aws_role }} + tfvars_file: "tf/variables.tfvars" + + - name: Set output for service existence + id: set-output + shell: bash + run: echo "service_exists=${{ env.SERVICE_EXISTS }}" >> $GITHUB_OUTPUT + + build: + needs: check + if: ${{ needs.check.outputs.service_exists == 'false' }} + uses: ./.github/workflows/build.yml + with: + aws_account_id: ${{ vars.AWS_ACCOUNT_ID }} + aws_region: ${{ vars.AWS_REGION }} + aws_role: ${{ vars.AWS_ROLE }} + + setup: + needs: + - check + - build + if: ${{ needs.check.outputs.service_exists == 'false' }} + uses: ./.github/workflows/setup.yml + with: + aws_account_id: ${{ vars.AWS_ACCOUNT_ID }} + aws_region: ${{ vars.AWS_REGION }} + aws_role: ${{ vars.AWS_ROLE }} \ No newline at end of file diff --git a/.github/workflows/setup.yml b/.github/workflows/setup.yml index 7b3df23..d6c055c 100644 --- a/.github/workflows/setup.yml +++ b/.github/workflows/setup.yml @@ -1,120 +1,104 @@ name: Setup on: - push: - branches: - - 'blue-green-deploy' - workflow_dispatch: + workflow_call: + inputs: + aws_account_id: + required: true + type: string + aws_region: + required: true + type: string + aws_role: + required: true + type: string + task_definition_arn: + required: true + type: string + + outputs: + api_invoke_url: + description: "The API gateway url to invoke the app" + value: ${{ jobs.network.outputs.api_invoke_url }} permissions: id-token: write contents: read jobs: - check: + service: runs-on: ubuntu-latest + env: + TF_VAR_task_definition_arn: ${{ inputs.task_definition_arn }} outputs: - service_exists: ${{ steps.check-ecs-service.outputs.service_exists }} + cluster_name: ${{ steps.set-envs.outputs.CLUSTER_NAME }} + service_name: ${{ steps.set-envs.outputs.SERVICE_NAME }} + lb_listener_arn: ${{ steps.set-envs.outputs.LB_LISTENER_ARN }} steps: - uses: actions/checkout@v4 - - name: Check ECS Service - id: check-ecs-service - uses: ./.github/actions/check_svc + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v4 with: - aws_region: ${{ vars.aws_region }} - aws_role: ${{ vars.aws_account_id }}:role/${{ vars.aws_role }} - tfvars_file: "tf/variables.tfvars" - - name: Display service_exists output - run: echo "service_exists=${{ steps.check-ecs-service.outputs.service_exists }}" - - # init: - # needs: check - # if: ${{ needs.check.outputs.service_exists == 'false' }} - # uses: ./.github/workflows/build.yml - # with: - # aws_account_id: ${{ vars.AWS_ACCOUNT_ID }} - # aws_region: ${{ vars.AWS_REGION }} - # aws_role: ${{ vars.AWS_ROLE }} + aws-region: ${{ inputs.aws_region }} + role-to-assume: arn:aws:iam::${{ inputs.aws_account_id }}:role/${{ inputs.aws_role }} + role-session-name: GitHubActions - # service: - # needs: - # - check - # - init - # if: ${{ needs.check.outputs.service_exists == 'false' }} - # runs-on: ubuntu-latest - # env: - # TF_VAR_task_definition_arn: ${{ needs.init.outputs.task_definition_arn }} - # outputs: - # cluster_name: ${{ steps.set-envs.outputs.CLUSTER_NAME }} - # service_name: ${{ steps.set-envs.outputs.SERVICE_NAME }} - # lb_listener_arn: ${{ steps.set-envs.outputs.LB_LISTENER_ARN }} - # steps: - # - uses: actions/checkout@v4 - # - name: Configure AWS Credentials - # uses: aws-actions/configure-aws-credentials@v4 - # with: - # aws-region: ${{ vars.aws_region }} - # role-to-assume: arn:aws:iam::${{ vars.aws_account_id }}:role/${{ vars.aws_role }} - # role-session-name: GitHubActions - - # - name: Init - # shell: bash - # run: | - # cd tf/service - # terraform init + - name: Init + shell: bash + run: | + cd tf/service + terraform init - # - name: Deploy - # shell: bash - # id: deploy - # run: | - # cd tf/service - # terraform apply -auto-approve -var-file=${{ github.workspace }}/tf/variables.tfvars + - name: Deploy + shell: bash + id: deploy + run: | + cd tf/service + terraform apply -auto-approve -var-file=${{ github.workspace }}/tf/variables.tfvars - # - name: Set env vars - # id: set-envs - # shell: bash - # run: | - # cd tf/service - # LB_LISTENER_ARN=$(terraform output -raw lb_listener_arn) - # echo "LB_LISTENER_ARN=$LB_LISTENER_ARN" >> $GITHUB_OUTPUT + - name: Set env vars + id: set-envs + shell: bash + run: | + cd tf/service + LB_LISTENER_ARN=$(terraform output -raw lb_listener_arn) + echo "LB_LISTENER_ARN=$LB_LISTENER_ARN" >> $GITHUB_OUTPUT - # network: - # needs: - # - check - # - service - # if: ${{ needs.check.outputs.service_exists == 'false' }} - # runs-on: ubuntu-latest - # env: - # TF_VAR_load_balancer_listener_arn: ${{ needs.service.outputs.lb_listener_arn }} - # outputs: - # api_invoke_url: ${{ steps.set-envs.outputs.API_INVOKE_URL }} - # steps: - # - uses: actions/checkout@v4 - # - name: Configure AWS Credentials - # uses: aws-actions/configure-aws-credentials@v4 - # with: - # aws-region: ${{ vars.aws_region }} - # role-to-assume: arn:aws:iam::${{ vars.aws_account_id }}:role/${{ vars.aws_role }} - # role-session-name: GitHubActions + network: + needs: + - service + runs-on: ubuntu-latest + env: + TF_VAR_load_balancer_listener_arn: ${{ needs.service.outputs.lb_listener_arn }} + outputs: + api_invoke_url: ${{ steps.set-envs.outputs.API_INVOKE_URL }} + steps: + - uses: actions/checkout@v4 + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + aws-region: ${{ inputs.aws_region }} + role-to-assume: arn:aws:iam::${{ inputs.aws_account_id }}:role/${{ inputs.aws_role }} + role-session-name: GitHubActions - # - name: Init - # shell: bash - # run: | - # cd tf/network - # terraform init + - name: Init + shell: bash + run: | + cd tf/network + terraform init - # - name: Deploy - # shell: bash - # id: deploy - # run: | - # cd tf/network - # terraform apply -auto-approve -var-file=${{ github.workspace }}/tf/variables.tfvars + - name: Deploy + shell: bash + id: deploy + run: | + cd tf/network + terraform apply -auto-approve -var-file=${{ github.workspace }}/tf/variables.tfvars - # - name: Set env vars - # id: set-envs - # shell: bash - # run: | - # cd tf/network - # API_INVOKE_URL=$(terraform output -raw api_invoke_url) - # echo "API_INVOKE_URL=$API_INVOKE_URL" >> $GITHUB_OUTPUT + - name: Set env vars + id: set-envs + shell: bash + run: | + cd tf/network + API_INVOKE_URL=$(terraform output -raw api_invoke_url) + echo "API_INVOKE_URL=$API_INVOKE_URL" >> $GITHUB_OUTPUT \ No newline at end of file From df55b8fa40d43ea66dec0cb6f4c0bf36ea64b28f Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 1 Oct 2024 10:57:11 +0100 Subject: [PATCH 076/116] task_definition_arn: --- .github/workflows/init.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/init.yml b/.github/workflows/init.yml index a651b19..dfdd302 100644 --- a/.github/workflows/init.yml +++ b/.github/workflows/init.yml @@ -48,4 +48,5 @@ jobs: with: aws_account_id: ${{ vars.AWS_ACCOUNT_ID }} aws_region: ${{ vars.AWS_REGION }} - aws_role: ${{ vars.AWS_ROLE }} \ No newline at end of file + aws_role: ${{ vars.AWS_ROLE }} + task_definition_arn: ${{ needs.build.outputs.task_definition_arn }} \ No newline at end of file From f045f76c744ae2da444c9aec7c634ca8f4fa5b70 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 1 Oct 2024 11:05:52 +0100 Subject: [PATCH 077/116] fix code deploy app reference --- tf/service/deploy/main.tf | 4 ++-- tf/variables.tfvars | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tf/service/deploy/main.tf b/tf/service/deploy/main.tf index f3b970a..db2251d 100644 --- a/tf/service/deploy/main.tf +++ b/tf/service/deploy/main.tf @@ -14,10 +14,10 @@ resource "aws_iam_role_policy" "codedeploy_role_policy" { } resource "aws_codedeploy_deployment_group" "this" { - app_name = var.codedeploy_group_name + app_name = aws_codedeploy_app.ecs_app.name # Shifts 10% of the traffic in the first increment, then shifts the remaining 90% after 5 minutes deployment_config_name = "CodeDeployDefault.ECSCanary10Percent5Minutes" - deployment_group_name = "${var.project_name}-blue-green-group" + deployment_group_name = var.codedeploy_group_name service_role_arn = aws_iam_role.this.arn auto_rollback_configuration { diff --git a/tf/variables.tfvars b/tf/variables.tfvars index 64702af..53afc4c 100644 --- a/tf/variables.tfvars +++ b/tf/variables.tfvars @@ -1,6 +1,6 @@ project_name = "fargate-auto-scaled-backend" codedeploy_app_name = "fargate-auto-scaled-backend-ecs-codedeploy" -codedeploy_group_name = "fargate-auto-scaled-backend-ecs-deploy-group" +codedeploy_group_name = "fargate-auto-scaled-backend-ecs-blue-green-group" region = "eu-west-2" private_vpc_name = "ecs-private-vpc" api_stage_name = "dev" From 1619ebe02d877fbd226df47b8515b5aebdae8aa6 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 1 Oct 2024 11:56:27 +0100 Subject: [PATCH 078/116] fixes + trigger --- .github/workflows/deploy.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 787aeae..0358fac 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -1,9 +1,9 @@ name: Deploy on: - # push: - # branches: - # - 'blue-green-deploy' + push: + branches: + - 'blue-green-deploy' workflow_dispatch: permissions: @@ -67,8 +67,8 @@ jobs: APP_SPEC_CONTENT=$(cat appspec.json | jq -c .) aws deploy create-deployment \ - --application-name "${{ env.CODE_DEPLOY_APP_NAME }}" \ - --deployment-group-name "${{ env.CODE_DEPLOY_GROUP_NAME }}" \ + --application-name "${{ steps.read-vars.outputs.codedeploy_app_name }}" \ + --deployment-group-name "${{ steps.read-vars.outputs.codedeploy_group_name }}" \ --deployment-config-name CodeDeployDefault.ECSAllAtOnce \ --revision "revisionType=AppSpecContent,appSpecContent={\"content\":\"$APP_SPEC_CONTENT\"}" \ --region ${{ vars.AWS_REGION }} @@ -78,8 +78,8 @@ jobs: run: | echo "Monitoring CodeDeploy deployment status" DEPLOYMENT_ID=$(aws deploy list-deployments \ - --application-name "${{ steps.read-vars.outputs.CODEDEPLOY_APP_NAME }}" \ - --deployment-group-name "${{ steps.read-vars.outputs.CODE_DEPLOY_GROUP_NAME }}" \ + --application-name "${{ steps.read-vars.outputs.codedeploy_app_name }}" \ + --deployment-group-name "${{ steps.read-vars.outputs.codedeploy_group_name }}" \ --region ${{ vars.AWS_REGION }} \ --max-items 1 \ --query 'deployments[0]' --output text) From cdf64955ee4e4723f54e3b68fe3c449ee405a7e3 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 1 Oct 2024 12:01:22 +0100 Subject: [PATCH 079/116] pass into env vars --- .github/workflows/deploy.yml | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 0358fac..759291d 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -62,25 +62,31 @@ jobs: # Step 4: Create CodeDeploy Deployment - name: Create CodeDeploy Deployment + env: + APP_NAME: ${{ steps.read-vars.outputs.codedeploy_app_name }} + GROUP_NAME: ${{ steps.read-vars.outputs.codedeploy_group_name }} run: | echo "Creating CodeDeploy deployment" APP_SPEC_CONTENT=$(cat appspec.json | jq -c .) aws deploy create-deployment \ - --application-name "${{ steps.read-vars.outputs.codedeploy_app_name }}" \ - --deployment-group-name "${{ steps.read-vars.outputs.codedeploy_group_name }}" \ + --application-name "$APP_NAME" \ + --deployment-group-name "$GROUP_NAME" \ --deployment-config-name CodeDeployDefault.ECSAllAtOnce \ --revision "revisionType=AppSpecContent,appSpecContent={\"content\":\"$APP_SPEC_CONTENT\"}" \ --region ${{ vars.AWS_REGION }} # Step 5: Monitor Deployment Status - name: Monitor Deployment Status + env: + APP_NAME: ${{ steps.read-vars.outputs.codedeploy_app_name }} + GROUP_NAME: ${{ steps.read-vars.outputs.codedeploy_group_name }} run: | echo "Monitoring CodeDeploy deployment status" DEPLOYMENT_ID=$(aws deploy list-deployments \ - --application-name "${{ steps.read-vars.outputs.codedeploy_app_name }}" \ - --deployment-group-name "${{ steps.read-vars.outputs.codedeploy_group_name }}" \ - --region ${{ vars.AWS_REGION }} \ + --application-name "$APP_NAME" \ + --deployment-group-name "$GROUP_NAME" \ + --region ${{ vars.AWS_REGION }} \ --max-items 1 \ --query 'deployments[0]' --output text) From 09ef97c58f609cd0fc0964900bf6be887f15fb34 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 1 Oct 2024 12:04:55 +0100 Subject: [PATCH 080/116] casing fix? --- .github/workflows/deploy.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 759291d..81aa4d2 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -63,8 +63,8 @@ jobs: # Step 4: Create CodeDeploy Deployment - name: Create CodeDeploy Deployment env: - APP_NAME: ${{ steps.read-vars.outputs.codedeploy_app_name }} - GROUP_NAME: ${{ steps.read-vars.outputs.codedeploy_group_name }} + APP_NAME: ${{ steps.read-vars.outputs.CODE_DEPLOY_APP_NAME }} + GROUP_NAME: ${{ steps.read-vars.outputs.CODE_DEPLOY_GROUP_NAME }} run: | echo "Creating CodeDeploy deployment" APP_SPEC_CONTENT=$(cat appspec.json | jq -c .) @@ -79,8 +79,8 @@ jobs: # Step 5: Monitor Deployment Status - name: Monitor Deployment Status env: - APP_NAME: ${{ steps.read-vars.outputs.codedeploy_app_name }} - GROUP_NAME: ${{ steps.read-vars.outputs.codedeploy_group_name }} + APP_NAME: ${{ steps.read-vars.outputs.CODE_DEPLOY_APP_NAME }} + GROUP_NAME: ${{ steps.read-vars.outputs.CODE_DEPLOY_GROUP_NAME }} run: | echo "Monitoring CodeDeploy deployment status" DEPLOYMENT_ID=$(aws deploy list-deployments \ From 423c2b89eb1bde2e7227404ec776a9e4c4aff616 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 1 Oct 2024 12:18:01 +0100 Subject: [PATCH 081/116] file pipe --- .github/workflows/deploy.yml | 6 ++++-- .github/workflows/init.yml | 6 +++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 81aa4d2..de1356e 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -69,11 +69,13 @@ jobs: echo "Creating CodeDeploy deployment" APP_SPEC_CONTENT=$(cat appspec.json | jq -c .) + echo "{\"revisionType\":\"AppSpecContent\",\"appSpecContent\":{\"content\":\"$APP_SPEC_CONTENT\"}}" > revision.json + aws deploy create-deployment \ --application-name "$APP_NAME" \ --deployment-group-name "$GROUP_NAME" \ - --deployment-config-name CodeDeployDefault.ECSAllAtOnce \ - --revision "revisionType=AppSpecContent,appSpecContent={\"content\":\"$APP_SPEC_CONTENT\"}" \ + --deployment-config-name CodeDeployDefault.ECSCanary10Percent5Minutes \ + --revision "file://revision.json" \ --region ${{ vars.AWS_REGION }} # Step 5: Monitor Deployment Status diff --git a/.github/workflows/init.yml b/.github/workflows/init.yml index dfdd302..6ce1970 100644 --- a/.github/workflows/init.yml +++ b/.github/workflows/init.yml @@ -1,9 +1,9 @@ name: Init on: - push: - branches: - - 'blue-green-deploy' + # push: + # branches: + # - 'blue-green-deploy' workflow_dispatch: permissions: From f8876f09e1aa4749fa9e13ff607f7887c2382cbc Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 1 Oct 2024 12:22:10 +0100 Subject: [PATCH 082/116] json fix --- .github/workflows/deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index de1356e..c6ef9b3 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -69,7 +69,7 @@ jobs: echo "Creating CodeDeploy deployment" APP_SPEC_CONTENT=$(cat appspec.json | jq -c .) - echo "{\"revisionType\":\"AppSpecContent\",\"appSpecContent\":{\"content\":\"$APP_SPEC_CONTENT\"}}" > revision.json + echo "{\"revisionType\":\"AppSpecContent\",\"appSpecContent\":{\"content\":$APP_SPEC_CONTENT}}" > revision.json aws deploy create-deployment \ --application-name "$APP_NAME" \ From 858c5af34d659ea147e16e6f86f9d4c4152f2dd9 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 1 Oct 2024 12:25:51 +0100 Subject: [PATCH 083/116] escapign fix --- .github/workflows/deploy.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index c6ef9b3..bb819a1 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -68,8 +68,9 @@ jobs: run: | echo "Creating CodeDeploy deployment" APP_SPEC_CONTENT=$(cat appspec.json | jq -c .) + ESCAPED_APP_SPEC_CONTENT=$(echo "$APP_SPEC_CONTENT" | sed 's/"/\\"/g') - echo "{\"revisionType\":\"AppSpecContent\",\"appSpecContent\":{\"content\":$APP_SPEC_CONTENT}}" > revision.json + echo "{\"revisionType\":\"AppSpecContent\",\"appSpecContent\":{\"content\":$ESCAPED_APP_SPEC_CONTENT}}" > revision.json aws deploy create-deployment \ --application-name "$APP_NAME" \ From 64111ee0375be8223f52fa2b19db3c84e8203145 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 1 Oct 2024 14:42:00 +0100 Subject: [PATCH 084/116] app_specs_bucket --- .github/workflows/build.yml | 5 +++++ tf/task/main.tf | 5 +++++ tf/task/outputs.tf | 4 ++++ 3 files changed, 14 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 017e680..963f87f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -21,6 +21,8 @@ on: value: ${{ jobs.task.outputs.task_definition_revision }} image_uri: value: ${{ jobs.image.outputs.image_uri }} + app_specs_bucket: + value: ${{ jobs.task.outputs.app_specs_bucket }} permissions: id-token: write @@ -83,6 +85,7 @@ jobs: outputs: task_definition_arn: ${{ steps.set-envs.outputs.TASK_DEFINITION_ARN }} task_definition_revision: ${{ steps.set-envs.outputs.TASK_DEFINITION_REVISION }} + app_specs_bucket: ${{ steps.set-envs.outputs.APP_SPECS_BUCKET }} steps: - uses: actions/checkout@v4 - uses: aws-actions/configure-aws-credentials@v4 @@ -111,5 +114,7 @@ jobs: cd tf/task TASK_DEFINITION_ARN=$(terraform output -raw task_definition_arn) TASK_DEFINITION_REVISION=$(terraform output -raw task_definition_revision) + APP_SPECS_BUCKET=$(terraform output -raw app_specs_bucket) echo "TASK_DEFINITION_ARN=$TASK_DEFINITION_ARN" >> $GITHUB_OUTPUT echo "TASK_DEFINITION_REVISION=$TASK_DEFINITION_REVISION" >> $GITHUB_OUTPUT + echo "APP_SPECS_BUCKET=$APP_SPECS_BUCKET" >> $GITHUB_OUTPUT diff --git a/tf/task/main.tf b/tf/task/main.tf index e71a9e4..1f42d43 100644 --- a/tf/task/main.tf +++ b/tf/task/main.tf @@ -1,3 +1,8 @@ +resource "aws_s3_bucket" "app_specs" { + bucket = "${var.project_name}-app-specs" + force_destroy = true +} + resource "aws_iam_role" "ecs_task_role" { name = "${var.project_name}-ecs-task-role" assume_role_policy = data.aws_iam_policy_document.assume_role.json diff --git a/tf/task/outputs.tf b/tf/task/outputs.tf index cd6f347..62d586f 100644 --- a/tf/task/outputs.tf +++ b/tf/task/outputs.tf @@ -9,3 +9,7 @@ output "task_definition_revision" { output "cloudwatch_log_group" { value = aws_cloudwatch_log_group.ecs_log_group.name } + +output "app_specs_bucket" { + value = aws_s3_bucket.app_specs.bucket +} From 9a38f8a9e1e4c924f4627859048db9044ef86082 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 1 Oct 2024 14:53:58 +0100 Subject: [PATCH 085/116] yaml --- .github/workflows/build.yml | 2 +- .github/workflows/deploy.yml | 95 ++++++++++++++++++------------------ .github/workflows/init.yml | 6 +-- appspec.json | 18 ------- appspec.yaml | 9 ++++ 5 files changed, 60 insertions(+), 70 deletions(-) delete mode 100644 appspec.json create mode 100644 appspec.yaml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 963f87f..74d5468 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -16,7 +16,7 @@ on: task_definition_arn: description: "The ARN of the deployed task definition" value: ${{ jobs.task.outputs.task_definition_arn }} - task_definition_revsion: + task_definition_revision: description: "The revision of the deployed task definition" value: ${{ jobs.task.outputs.task_definition_revision }} image_uri: diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index bb819a1..2fa7b2d 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -1,9 +1,9 @@ name: Deploy on: - push: - branches: - - 'blue-green-deploy' + # push: + # branches: + # - 'blue-green-deploy' workflow_dispatch: permissions: @@ -23,6 +23,7 @@ jobs: runs-on: ubuntu-latest env: TF_VAR_FILE: tf/variables.tfvars + APP_SPEC_FILE: appspec.yaml steps: - uses: actions/checkout@v4 - uses: aws-actions/configure-aws-credentials@v4 @@ -54,11 +55,14 @@ jobs: # Step 3: Replace placeholders in the appspec.json file - name: Prepare AppSpec File run: | - sed -i 's|{{TASK_VERSION}}|${{ needs.code.outputs.task_definition_revsion }}|g' appspec.json - sed -i 's|{{TASK_DEFINITION_ARN}}|${{ needs.code.outputs.task_definition_arn }}|g' appspec.json - sed -i 's|{{CONTAINER_NAME}}|${{ steps.read-vars.outputs.project_name }}|g' appspec.json - sed -i 's|{{CONTAINER_PORT}}|${{ steps.read-vars.outputs.container_port }}|g' appspec.json - cat appspec.json + sed -i 's|{{TASK_VERSION}}|${{ needs.code.outputs.task_definition_revision }}|g' ${{ env.APP_SPEC_FILE }} + sed -i 's|{{TASK_DEFINITION_ARN}}|${{ needs.code.outputs.task_definition_arn }}|g' ${{ env.APP_SPEC_FILE }} + sed -i 's|{{CONTAINER_NAME}}|${{ steps.read-vars.outputs.project_name }}|g' ${{ env.APP_SPEC_FILE }} + sed -i 's|{{CONTAINER_PORT}}|${{ steps.read-vars.outputs.container_port }}|g' ${{ env.APP_SPEC_FILE }} + cat ${{ env.APP_SPEC_FILE }} + + - name: Upload yaml to s3 + run: aws s3 cp ${{ env.APP_SPEC_FILE }} s3://${{ needs.code.outputs.app_specs_bucket}}/${{ needs.code.outputs.task_definition_revision }}-${{ env.APP_SPEC_FILE }}" # Step 4: Create CodeDeploy Deployment - name: Create CodeDeploy Deployment @@ -67,53 +71,48 @@ jobs: GROUP_NAME: ${{ steps.read-vars.outputs.CODE_DEPLOY_GROUP_NAME }} run: | echo "Creating CodeDeploy deployment" - APP_SPEC_CONTENT=$(cat appspec.json | jq -c .) - ESCAPED_APP_SPEC_CONTENT=$(echo "$APP_SPEC_CONTENT" | sed 's/"/\\"/g') - - echo "{\"revisionType\":\"AppSpecContent\",\"appSpecContent\":{\"content\":$ESCAPED_APP_SPEC_CONTENT}}" > revision.json - aws deploy create-deployment \ --application-name "$APP_NAME" \ --deployment-group-name "$GROUP_NAME" \ - --deployment-config-name CodeDeployDefault.ECSCanary10Percent5Minutes \ - --revision "file://revision.json" \ + --deployment-config-name CodeDeployDefault.ECSAllAtOnce \ + --revision "revisionType=S3,s3Location={\"bucket\":\"${{ needs.code.outputs.app_specs_bucket}}\",\"key\":\"${{ needs.code.outputs.task_definition_revision }}-${{ env.APP_SPEC_FILE }}\",\"bundleType\":\"YAML\"}" \ --region ${{ vars.AWS_REGION }} - # Step 5: Monitor Deployment Status - - name: Monitor Deployment Status - env: - APP_NAME: ${{ steps.read-vars.outputs.CODE_DEPLOY_APP_NAME }} - GROUP_NAME: ${{ steps.read-vars.outputs.CODE_DEPLOY_GROUP_NAME }} - run: | - echo "Monitoring CodeDeploy deployment status" - DEPLOYMENT_ID=$(aws deploy list-deployments \ - --application-name "$APP_NAME" \ - --deployment-group-name "$GROUP_NAME" \ - --region ${{ vars.AWS_REGION }} \ - --max-items 1 \ - --query 'deployments[0]' --output text) + # # Step 5: Monitor Deployment Status + # - name: Monitor Deployment Status + # env: + # APP_NAME: ${{ steps.read-vars.outputs.CODE_DEPLOY_APP_NAME }} + # GROUP_NAME: ${{ steps.read-vars.outputs.CODE_DEPLOY_GROUP_NAME }} + # run: | + # echo "Monitoring CodeDeploy deployment status" + # DEPLOYMENT_ID=$(aws deploy list-deployments \ + # --application-name "$APP_NAME" \ + # --deployment-group-name "$GROUP_NAME" \ + # --region ${{ vars.AWS_REGION }} \ + # --max-items 1 \ + # --query 'deployments[0]' --output text) - if [ "$DEPLOYMENT_ID" == "None" ]; then - echo "No deployment found." - exit 1 - fi + # if [ "$DEPLOYMENT_ID" == "None" ]; then + # echo "No deployment found." + # exit 1 + # fi - echo "Deployment ID: $DEPLOYMENT_ID" + # echo "Deployment ID: $DEPLOYMENT_ID" - # Loop to check the deployment status - while true; do - STATUS=$(aws deploy get-deployment --deployment-id $DEPLOYMENT_ID --query 'deploymentInfo.status' --output text) + # # Loop to check the deployment status + # while true; do + # STATUS=$(aws deploy get-deployment --deployment-id $DEPLOYMENT_ID --query 'deploymentInfo.status' --output text) - echo "Deployment status: $STATUS" + # echo "Deployment status: $STATUS" - if [[ "$STATUS" == "Succeeded" ]]; then - echo "Deployment succeeded!" - break - elif [[ "$STATUS" == "Failed" || "$STATUS" == "Stopped" ]]; then - echo "Deployment failed!" - exit 1 - else - echo "Deployment is in progress..." - sleep 30 - fi - done \ No newline at end of file + # if [[ "$STATUS" == "Succeeded" ]]; then + # echo "Deployment succeeded!" + # break + # elif [[ "$STATUS" == "Failed" || "$STATUS" == "Stopped" ]]; then + # echo "Deployment failed!" + # exit 1 + # else + # echo "Deployment is in progress..." + # sleep 30 + # fi + # done \ No newline at end of file diff --git a/.github/workflows/init.yml b/.github/workflows/init.yml index 6ce1970..dfdd302 100644 --- a/.github/workflows/init.yml +++ b/.github/workflows/init.yml @@ -1,9 +1,9 @@ name: Init on: - # push: - # branches: - # - 'blue-green-deploy' + push: + branches: + - 'blue-green-deploy' workflow_dispatch: permissions: diff --git a/appspec.json b/appspec.json deleted file mode 100644 index d940e67..0000000 --- a/appspec.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "version": "{{TASK_VERSION}}", - "Resources": [ - { - "TargetService": { - "Type": "AWS::ECS::Service", - "Properties": { - "TaskDefinition": "{{TASK_DEFINITION_ARN}}", - "LoadBalancerInfo": { - "ContainerName": "{{CONTAINER_NAME}}", - "ContainerPort": {{CONTAINER_PORT}} - } - } - } - } - ] - } - \ No newline at end of file diff --git a/appspec.yaml b/appspec.yaml new file mode 100644 index 0000000..7e1f4f4 --- /dev/null +++ b/appspec.yaml @@ -0,0 +1,9 @@ +version: {{TASK_VERSION}} +Resources: + - TargetService: + Type: AWS::ECS::Service + Properties: + TaskDefinition: {{TASK_DEFINITION_ARN}} + LoadBalancerInfo: + ContainerName: {{CONTAINER_NAME}} + ContainerPort: {{CONTAINER_PORT}} \ No newline at end of file From 885003526f09fca3ddfe99c0973f47551ba8943c Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 1 Oct 2024 15:05:37 +0100 Subject: [PATCH 086/116] refactor --- .github/workflows/build.yml | 24 ------------------------ .github/workflows/init.yml | 36 +++++++++++++++++++++++++++++++----- 2 files changed, 31 insertions(+), 29 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 74d5468..15ab988 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -29,34 +29,10 @@ permissions: contents: read jobs: - ecr: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: aws-actions/configure-aws-credentials@v4 - with: - aws-region: ${{ inputs.aws_region }} - role-to-assume: arn:aws:iam::${{ inputs.aws_account_id }}:role/${{ inputs.aws_role }} - role-session-name: GitHubActions - - - name: Init - shell: bash - run: | - cd tf/ecr - terraform init - - - name: Deploy - shell: bash - id: deploy - run: | - cd tf/ecr - terraform apply -auto-approve -var-file=${{ github.workspace }}/tf/variables.tfvars - image: runs-on: ubuntu-latest outputs: image_uri: ${{ steps.set-image-uri.outputs.image_uri }} - needs: ecr steps: - uses: actions/checkout@v4 - uses: aws-actions/configure-aws-credentials@v4 diff --git a/.github/workflows/init.yml b/.github/workflows/init.yml index dfdd302..47dd69a 100644 --- a/.github/workflows/init.yml +++ b/.github/workflows/init.yml @@ -11,7 +11,7 @@ permissions: contents: read jobs: - check: + ecs-check: runs-on: ubuntu-latest outputs: service_exists: ${{ steps.set-output.outputs.service_exists }} @@ -30,9 +30,35 @@ jobs: shell: bash run: echo "service_exists=${{ env.SERVICE_EXISTS }}" >> $GITHUB_OUTPUT + + ecr: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: aws-actions/configure-aws-credentials@v4 + with: + aws-region: ${{ vars.aws_region }} + role-to-assume: arn:aws:iam::${{ vars.aws_account_id }}:role/${{ vars.aws_role }} + role-session-name: GitHubActions + + - name: Init + shell: bash + run: | + cd tf/ecr + terraform init + + - name: Deploy + shell: bash + id: deploy + run: | + cd tf/ecr + terraform apply -auto-approve -var-file=${{ github.workspace }}/tf/variables.tfvars + build: - needs: check - if: ${{ needs.check.outputs.service_exists == 'false' }} + needs: + - ecs-check + - ecr + if: ${{ needs.ecs-check.outputs.service_exists == 'false' }} uses: ./.github/workflows/build.yml with: aws_account_id: ${{ vars.AWS_ACCOUNT_ID }} @@ -41,9 +67,9 @@ jobs: setup: needs: - - check + - ecs-check - build - if: ${{ needs.check.outputs.service_exists == 'false' }} + if: ${{ needs.ecs-check.outputs.service_exists == 'false' }} uses: ./.github/workflows/setup.yml with: aws_account_id: ${{ vars.AWS_ACCOUNT_ID }} From 25b1701f7c7d5d7b28bc116646f3f041b8726464 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 1 Oct 2024 15:08:22 +0100 Subject: [PATCH 087/116] trigger --- .github/workflows/deploy.yml | 6 +++--- .github/workflows/init.yml | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 2fa7b2d..9211569 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -1,9 +1,9 @@ name: Deploy on: - # push: - # branches: - # - 'blue-green-deploy' + push: + branches: + - 'blue-green-deploy' workflow_dispatch: permissions: diff --git a/.github/workflows/init.yml b/.github/workflows/init.yml index 47dd69a..741085c 100644 --- a/.github/workflows/init.yml +++ b/.github/workflows/init.yml @@ -1,9 +1,9 @@ name: Init on: - push: - branches: - - 'blue-green-deploy' + # push: + # branches: + # - 'blue-green-deploy' workflow_dispatch: permissions: From 787d37b23426719562ddb78aa474fcd7e9761c30 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 1 Oct 2024 15:11:09 +0100 Subject: [PATCH 088/116] rm " --- .github/workflows/deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 9211569..f04a3fb 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -62,7 +62,7 @@ jobs: cat ${{ env.APP_SPEC_FILE }} - name: Upload yaml to s3 - run: aws s3 cp ${{ env.APP_SPEC_FILE }} s3://${{ needs.code.outputs.app_specs_bucket}}/${{ needs.code.outputs.task_definition_revision }}-${{ env.APP_SPEC_FILE }}" + run: aws s3 cp ${{ env.APP_SPEC_FILE }} s3://${{ needs.code.outputs.app_specs_bucket}}/${{ needs.code.outputs.task_definition_revision }}-${{ env.APP_SPEC_FILE }} # Step 4: Create CodeDeploy Deployment - name: Create CodeDeploy Deployment From b47fcd76881a0ff32d39c435c655aa72227a7f6e Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 1 Oct 2024 15:15:57 +0100 Subject: [PATCH 089/116] escape json --- .github/workflows/deploy.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index f04a3fb..88f42ec 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -75,9 +75,9 @@ jobs: --application-name "$APP_NAME" \ --deployment-group-name "$GROUP_NAME" \ --deployment-config-name CodeDeployDefault.ECSAllAtOnce \ - --revision "revisionType=S3,s3Location={\"bucket\":\"${{ needs.code.outputs.app_specs_bucket}}\",\"key\":\"${{ needs.code.outputs.task_definition_revision }}-${{ env.APP_SPEC_FILE }}\",\"bundleType\":\"YAML\"}" \ + --revision "{\"revisionType\":\"S3\",\"s3Location\":{\"bucket\":\"${{ needs.code.outputs.app_specs_bucket}}\",\"key\":\"${{ needs.code.outputs.task_definition_revision }}-${{ env.APP_SPEC_FILE }}\",\"bundleType\":\"YAML\"}}" \ --region ${{ vars.AWS_REGION }} - + # # Step 5: Monitor Deployment Status # - name: Monitor Deployment Status # env: From 920f4d730369b67894b38179bc53983435119079 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 1 Oct 2024 15:39:41 +0100 Subject: [PATCH 090/116] app_specs_bucket access --- .github/workflows/deploy.yml | 6 +++--- .github/workflows/init.yml | 9 ++++----- tf/service/deploy/data.tf | 16 ++++++++++++++++ tf/service/deploy/variables.tf | 4 ++++ tf/service/variables.tf | 4 ++++ tf/task/main.tf | 2 +- tf/task/variables.tf | 4 ++++ tf/variables.tfvars | 1 + 8 files changed, 37 insertions(+), 9 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 88f42ec..3eca53e 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -1,9 +1,9 @@ name: Deploy on: - push: - branches: - - 'blue-green-deploy' + # push: + # branches: + # - 'blue-green-deploy' workflow_dispatch: permissions: diff --git a/.github/workflows/init.yml b/.github/workflows/init.yml index 741085c..76ee38c 100644 --- a/.github/workflows/init.yml +++ b/.github/workflows/init.yml @@ -1,9 +1,9 @@ name: Init on: - # push: - # branches: - # - 'blue-green-deploy' + push: + branches: + - 'blue-green-deploy' workflow_dispatch: permissions: @@ -30,7 +30,6 @@ jobs: shell: bash run: echo "service_exists=${{ env.SERVICE_EXISTS }}" >> $GITHUB_OUTPUT - ecr: runs-on: ubuntu-latest steps: @@ -75,4 +74,4 @@ jobs: aws_account_id: ${{ vars.AWS_ACCOUNT_ID }} aws_region: ${{ vars.AWS_REGION }} aws_role: ${{ vars.AWS_ROLE }} - task_definition_arn: ${{ needs.build.outputs.task_definition_arn }} \ No newline at end of file + task_definition_arn: ${{ needs.build.outputs.task_definition_arn }} diff --git a/tf/service/deploy/data.tf b/tf/service/deploy/data.tf index e7ccfa5..f98a650 100644 --- a/tf/service/deploy/data.tf +++ b/tf/service/deploy/data.tf @@ -1,3 +1,7 @@ +data "aws_s3_bucket" "app_specs" { + bucket = var.app_specs_bucket +} + data "aws_iam_policy_document" "codedeploy_assume_role_policy" { statement { actions = ["sts:AssumeRole"] @@ -23,4 +27,16 @@ data "aws_iam_policy_document" "codedeploy_policy" { effect = "Allow" resources = ["*"] } + + statement { + effect = "Allow" + actions = [ + "s3:GetObject", + "s3:ListBucket" + ] + resources = [ + data.aws_s3_bucket.app_specs.arn, + "${data.aws_s3_bucket.app_specs.arn}/*" + ] + } } diff --git a/tf/service/deploy/variables.tf b/tf/service/deploy/variables.tf index 6c22b3a..ad90fbb 100644 --- a/tf/service/deploy/variables.tf +++ b/tf/service/deploy/variables.tf @@ -22,6 +22,10 @@ variable "codedeploy_group_name" { type = string } +variable "app_specs_bucket" { + type = string +} + variable "lb_listener_arn" { type = string } diff --git a/tf/service/variables.tf b/tf/service/variables.tf index e359f47..1308082 100644 --- a/tf/service/variables.tf +++ b/tf/service/variables.tf @@ -10,6 +10,10 @@ variable "codedeploy_group_name" { type = string } +variable "app_specs_bucket" { + type = string +} + variable "region" { type = string } diff --git a/tf/task/main.tf b/tf/task/main.tf index 1f42d43..298d8d6 100644 --- a/tf/task/main.tf +++ b/tf/task/main.tf @@ -1,5 +1,5 @@ resource "aws_s3_bucket" "app_specs" { - bucket = "${var.project_name}-app-specs" + bucket = var.app_specs_bucket force_destroy = true } diff --git a/tf/task/variables.tf b/tf/task/variables.tf index a845014..d3c78ba 100644 --- a/tf/task/variables.tf +++ b/tf/task/variables.tf @@ -18,6 +18,10 @@ variable "image_uri" { type = string } +variable "app_specs_bucket" { + type = string +} + variable "cpu" { type = number default = 256 diff --git a/tf/variables.tfvars b/tf/variables.tfvars index 53afc4c..0d00d59 100644 --- a/tf/variables.tfvars +++ b/tf/variables.tfvars @@ -1,6 +1,7 @@ project_name = "fargate-auto-scaled-backend" codedeploy_app_name = "fargate-auto-scaled-backend-ecs-codedeploy" codedeploy_group_name = "fargate-auto-scaled-backend-ecs-blue-green-group" +app_specs_bucket = "fargate-auto-scaled-backend-ecs-app-specs" region = "eu-west-2" private_vpc_name = "ecs-private-vpc" api_stage_name = "dev" From 246c642bf83961297d2d38ecb5c6858cc753a1ae Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 1 Oct 2024 15:49:46 +0100 Subject: [PATCH 091/116] fix --- tf/service/main.tf | 1 + 1 file changed, 1 insertion(+) diff --git a/tf/service/main.tf b/tf/service/main.tf index 0b25391..b794305 100644 --- a/tf/service/main.tf +++ b/tf/service/main.tf @@ -30,6 +30,7 @@ module "deploy" { project_name = var.project_name codedeploy_app_name = var.codedeploy_app_name codedeploy_group_name = var.codedeploy_group_name + app_specs_bucket = var.app_specs_bucket region = var.region cluster_name = module.ecs.cluster_name service_name = module.ecs.service_name From 84acc135d9143ca353690af3a65a68e6cc025cd7 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 1 Oct 2024 15:59:17 +0100 Subject: [PATCH 092/116] trigger + monitor --- .github/workflows/deploy.yml | 73 +++++++++++++++++------------------- 1 file changed, 35 insertions(+), 38 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 3eca53e..8732fca 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -1,9 +1,9 @@ name: Deploy on: - # push: - # branches: - # - 'blue-green-deploy' + push: + branches: + - 'blue-green-deploy' workflow_dispatch: permissions: @@ -52,7 +52,6 @@ jobs: echo "Extracted project_name: $PROJECT_NAME" echo "PROJECT_NAME=$PROJECT_NAME" >> $GITHUB_OUTPUT - # Step 3: Replace placeholders in the appspec.json file - name: Prepare AppSpec File run: | sed -i 's|{{TASK_VERSION}}|${{ needs.code.outputs.task_definition_revision }}|g' ${{ env.APP_SPEC_FILE }} @@ -64,7 +63,6 @@ jobs: - name: Upload yaml to s3 run: aws s3 cp ${{ env.APP_SPEC_FILE }} s3://${{ needs.code.outputs.app_specs_bucket}}/${{ needs.code.outputs.task_definition_revision }}-${{ env.APP_SPEC_FILE }} - # Step 4: Create CodeDeploy Deployment - name: Create CodeDeploy Deployment env: APP_NAME: ${{ steps.read-vars.outputs.CODE_DEPLOY_APP_NAME }} @@ -78,41 +76,40 @@ jobs: --revision "{\"revisionType\":\"S3\",\"s3Location\":{\"bucket\":\"${{ needs.code.outputs.app_specs_bucket}}\",\"key\":\"${{ needs.code.outputs.task_definition_revision }}-${{ env.APP_SPEC_FILE }}\",\"bundleType\":\"YAML\"}}" \ --region ${{ vars.AWS_REGION }} - # # Step 5: Monitor Deployment Status - # - name: Monitor Deployment Status - # env: - # APP_NAME: ${{ steps.read-vars.outputs.CODE_DEPLOY_APP_NAME }} - # GROUP_NAME: ${{ steps.read-vars.outputs.CODE_DEPLOY_GROUP_NAME }} - # run: | - # echo "Monitoring CodeDeploy deployment status" - # DEPLOYMENT_ID=$(aws deploy list-deployments \ - # --application-name "$APP_NAME" \ - # --deployment-group-name "$GROUP_NAME" \ - # --region ${{ vars.AWS_REGION }} \ - # --max-items 1 \ - # --query 'deployments[0]' --output text) + - name: Monitor Deployment Status + env: + APP_NAME: ${{ steps.read-vars.outputs.CODE_DEPLOY_APP_NAME }} + GROUP_NAME: ${{ steps.read-vars.outputs.CODE_DEPLOY_GROUP_NAME }} + run: | + echo "Monitoring CodeDeploy deployment status" + DEPLOYMENT_ID=$(aws deploy list-deployments \ + --application-name "$APP_NAME" \ + --deployment-group-name "$GROUP_NAME" \ + --region ${{ vars.AWS_REGION }} \ + --max-items 1 \ + --query 'deployments[0]' --output text) - # if [ "$DEPLOYMENT_ID" == "None" ]; then - # echo "No deployment found." - # exit 1 - # fi + if [ "$DEPLOYMENT_ID" == "None" ]; then + echo "No deployment found." + exit 1 + fi - # echo "Deployment ID: $DEPLOYMENT_ID" + echo "Deployment ID: $DEPLOYMENT_ID" - # # Loop to check the deployment status - # while true; do - # STATUS=$(aws deploy get-deployment --deployment-id $DEPLOYMENT_ID --query 'deploymentInfo.status' --output text) + # Loop to check the deployment status + while true; do + STATUS=$(aws deploy get-deployment --deployment-id $DEPLOYMENT_ID --query 'deploymentInfo.status' --output text) - # echo "Deployment status: $STATUS" + echo "Deployment status: $STATUS" - # if [[ "$STATUS" == "Succeeded" ]]; then - # echo "Deployment succeeded!" - # break - # elif [[ "$STATUS" == "Failed" || "$STATUS" == "Stopped" ]]; then - # echo "Deployment failed!" - # exit 1 - # else - # echo "Deployment is in progress..." - # sleep 30 - # fi - # done \ No newline at end of file + if [[ "$STATUS" == "Succeeded" ]]; then + echo "Deployment succeeded!" + break + elif [[ "$STATUS" == "Failed" || "$STATUS" == "Stopped" ]]; then + echo "Deployment failed!" + exit 1 + else + echo "Deployment is in progress..." + sleep 30 + fi + done \ No newline at end of file From b8a9a2311574bce24d0250627d8f22d6fd9d8b31 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 1 Oct 2024 16:15:05 +0100 Subject: [PATCH 093/116] fix destroy order --- .github/workflows/destroy.yml | 37 ++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/.github/workflows/destroy.yml b/.github/workflows/destroy.yml index 59b4b58..824afc4 100644 --- a/.github/workflows/destroy.yml +++ b/.github/workflows/destroy.yml @@ -11,10 +11,12 @@ permissions: contents: read jobs: - task: + service: runs-on: ubuntu-latest + needs: + - network env: - TF_VAR_image_uri: dummy + TF_VAR_task_definition_arn: "arn:aws:ecs:us-east-1:123456789012:task-definition/dummy-task-definition" steps: - uses: actions/checkout@v4 - name: Configure AWS Credentials @@ -27,19 +29,21 @@ jobs: - name: Init shell: bash run: | - cd tf/task + cd tf/service terraform init - name: Destroy shell: bash id: destroy run: | - cd tf/task + cd tf/service terraform destroy -auto-approve -var-file=${{ github.workspace }}/tf/variables.tfvars - ecr: - needs: task + task: + needs: service runs-on: ubuntu-latest + env: + TF_VAR_image_uri: dummy steps: - uses: actions/checkout@v4 - name: Configure AWS Credentials @@ -52,17 +56,18 @@ jobs: - name: Init shell: bash run: | - cd tf/ecr + cd tf/task terraform init - name: Destroy shell: bash id: destroy run: | - cd tf/ecr + cd tf/task terraform destroy -auto-approve -var-file=${{ github.workspace }}/tf/variables.tfvars - network: + ecr: + needs: task runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -76,22 +81,18 @@ jobs: - name: Init shell: bash run: | - cd tf/network + cd tf/ecr terraform init - name: Destroy shell: bash id: destroy run: | - cd tf/network + cd tf/ecr terraform destroy -auto-approve -var-file=${{ github.workspace }}/tf/variables.tfvars - service: + network: runs-on: ubuntu-latest - needs: - - network - env: - TF_VAR_task_definition_arn: "arn:aws:ecs:us-east-1:123456789012:task-definition/dummy-task-definition" steps: - uses: actions/checkout@v4 - name: Configure AWS Credentials @@ -104,12 +105,12 @@ jobs: - name: Init shell: bash run: | - cd tf/service + cd tf/network terraform init - name: Destroy shell: bash id: destroy run: | - cd tf/service + cd tf/network terraform destroy -auto-approve -var-file=${{ github.workspace }}/tf/variables.tfvars From 0a1caf2d2407195614afe5c39a944cf0cbe92470 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 1 Oct 2024 16:23:14 +0100 Subject: [PATCH 094/116] shorten tg name --- .github/workflows/deploy.yml | 15 +++++++++++---- .github/workflows/destroy.yml | 2 -- tf/service/load_balancer/main.tf | 4 ++-- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 8732fca..298f33a 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -1,9 +1,9 @@ name: Deploy on: - push: - branches: - - 'blue-green-deploy' + # push: + # branches: + # - 'blue-green-deploy' workflow_dispatch: permissions: @@ -98,7 +98,9 @@ jobs: # Loop to check the deployment status while true; do - STATUS=$(aws deploy get-deployment --deployment-id $DEPLOYMENT_ID --query 'deploymentInfo.status' --output text) + DEPLOYMENT_INFO=$(aws deploy get-deployment --deployment-id $DEPLOYMENT_ID --query 'deploymentInfo' --output json) + + STATUS=$(echo $DEPLOYMENT_INFO | jq -r '.status') echo "Deployment status: $STATUS" @@ -106,6 +108,11 @@ jobs: echo "Deployment succeeded!" break elif [[ "$STATUS" == "Failed" || "$STATUS" == "Stopped" ]]; then + ERROR_CODE=$(echo $DEPLOYMENT_INFO | jq -r '.errorInformation.code') + ERROR_MESSAGE=$(echo $DEPLOYMENT_INFO | jq -r '.errorInformation.message') + + echo $ERROR_CODE + echo $ERROR_MESSAGE echo "Deployment failed!" exit 1 else diff --git a/.github/workflows/destroy.yml b/.github/workflows/destroy.yml index 824afc4..b484e01 100644 --- a/.github/workflows/destroy.yml +++ b/.github/workflows/destroy.yml @@ -13,8 +13,6 @@ permissions: jobs: service: runs-on: ubuntu-latest - needs: - - network env: TF_VAR_task_definition_arn: "arn:aws:ecs:us-east-1:123456789012:task-definition/dummy-task-definition" steps: diff --git a/tf/service/load_balancer/main.tf b/tf/service/load_balancer/main.tf index 18da06b..e8c3f28 100644 --- a/tf/service/load_balancer/main.tf +++ b/tf/service/load_balancer/main.tf @@ -31,7 +31,7 @@ resource "aws_lb" "lb" { } resource "aws_lb_target_group" "tg_blue" { - name = "tg-blue" + name = "tg-b" port = var.container_port protocol = "HTTP" vpc_id = var.private_vpc_id @@ -50,7 +50,7 @@ resource "aws_lb_target_group" "tg_blue" { } resource "aws_lb_target_group" "tg_green" { - name = "tg-green" + name = "tg-g" port = var.container_port protocol = "HTTP" vpc_id = var.private_vpc_id From 260fbaf0847671e0ff41deace8acdf004a35e2cd Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 1 Oct 2024 16:41:04 +0100 Subject: [PATCH 095/116] trigger deploy --- .github/workflows/deploy.yml | 6 +++--- .github/workflows/init.yml | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 298f33a..52e87e4 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -1,9 +1,9 @@ name: Deploy on: - # push: - # branches: - # - 'blue-green-deploy' + push: + branches: + - 'blue-green-deploy' workflow_dispatch: permissions: diff --git a/.github/workflows/init.yml b/.github/workflows/init.yml index 76ee38c..8a705f9 100644 --- a/.github/workflows/init.yml +++ b/.github/workflows/init.yml @@ -1,9 +1,9 @@ name: Init on: - push: - branches: - - 'blue-green-deploy' + # push: + # branches: + # - 'blue-green-deploy' workflow_dispatch: permissions: From cf46fa7f801f3efff7992da331dbb18909cb1dd3 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 1 Oct 2024 16:57:53 +0100 Subject: [PATCH 096/116] use target group name --- .github/workflows/deploy.yml | 6 +++--- .github/workflows/init.yml | 6 +++--- tf/service/deploy/main.tf | 4 ++-- tf/service/deploy/variables.tf | 4 ++-- tf/service/load_balancer/locals.tf | 4 ++++ tf/service/load_balancer/main.tf | 4 ++-- tf/service/load_balancer/outputs.tf | 8 ++++---- tf/service/main.tf | 20 ++++++++++---------- tf/variables.tfvars | 8 ++++---- 9 files changed, 34 insertions(+), 30 deletions(-) create mode 100644 tf/service/load_balancer/locals.tf diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 52e87e4..298f33a 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -1,9 +1,9 @@ name: Deploy on: - push: - branches: - - 'blue-green-deploy' + # push: + # branches: + # - 'blue-green-deploy' workflow_dispatch: permissions: diff --git a/.github/workflows/init.yml b/.github/workflows/init.yml index 8a705f9..76ee38c 100644 --- a/.github/workflows/init.yml +++ b/.github/workflows/init.yml @@ -1,9 +1,9 @@ name: Init on: - # push: - # branches: - # - 'blue-green-deploy' + push: + branches: + - 'blue-green-deploy' workflow_dispatch: permissions: diff --git a/tf/service/deploy/main.tf b/tf/service/deploy/main.tf index db2251d..42b316f 100644 --- a/tf/service/deploy/main.tf +++ b/tf/service/deploy/main.tf @@ -53,11 +53,11 @@ resource "aws_codedeploy_deployment_group" "this" { } target_group { - name = var.lb_blue_target_group_arn + name = var.lb_blue_target_group } target_group { - name = var.lb_green_target_group_arn + name = var.lb_green_target_group } } } diff --git a/tf/service/deploy/variables.tf b/tf/service/deploy/variables.tf index ad90fbb..213624a 100644 --- a/tf/service/deploy/variables.tf +++ b/tf/service/deploy/variables.tf @@ -30,10 +30,10 @@ variable "lb_listener_arn" { type = string } -variable "lb_green_target_group_arn" { +variable "lb_green_target_group" { type = string } -variable "lb_blue_target_group_arn" { +variable "lb_blue_target_group" { type = string } \ No newline at end of file diff --git a/tf/service/load_balancer/locals.tf b/tf/service/load_balancer/locals.tf new file mode 100644 index 0000000..83ce94b --- /dev/null +++ b/tf/service/load_balancer/locals.tf @@ -0,0 +1,4 @@ +locals { + blue_target_group_name = length("${var.project_name}-tg-blue") <= 32 ? "${var.project_name}-tg-blue" : error("blue_target_group_name exceeds 32 characters") + green_target_group_name = length("${var.project_name}-tg-green") <= 32 ? "${var.project_name}-tg-green" : error("green_target_group_name exceeds 32 characters") +} \ No newline at end of file diff --git a/tf/service/load_balancer/main.tf b/tf/service/load_balancer/main.tf index e8c3f28..2f2aab3 100644 --- a/tf/service/load_balancer/main.tf +++ b/tf/service/load_balancer/main.tf @@ -31,7 +31,7 @@ resource "aws_lb" "lb" { } resource "aws_lb_target_group" "tg_blue" { - name = "tg-b" + name = local.blue_target_group_name port = var.container_port protocol = "HTTP" vpc_id = var.private_vpc_id @@ -50,7 +50,7 @@ resource "aws_lb_target_group" "tg_blue" { } resource "aws_lb_target_group" "tg_green" { - name = "tg-g" + name = local.green_target_group_name port = var.container_port protocol = "HTTP" vpc_id = var.private_vpc_id diff --git a/tf/service/load_balancer/outputs.tf b/tf/service/load_balancer/outputs.tf index eab12f6..8b23aac 100644 --- a/tf/service/load_balancer/outputs.tf +++ b/tf/service/load_balancer/outputs.tf @@ -6,10 +6,10 @@ output "listener_arn" { value = aws_lb_listener.listener.arn } -output "blue_target_group_arn" { - value = aws_lb_target_group.tg_blue.arn +output "blue_target_group" { + value = aws_lb_target_group.tg_blue.name } -output "green_target_group_arn" { - value = aws_lb_target_group.tg_green.arn +output "green_target_group" { + value = aws_lb_target_group.tg_green.name } diff --git a/tf/service/main.tf b/tf/service/main.tf index b794305..da3aaa6 100644 --- a/tf/service/main.tf +++ b/tf/service/main.tf @@ -27,16 +27,16 @@ module "load_balancer" { module "deploy" { source = "./deploy" - project_name = var.project_name - codedeploy_app_name = var.codedeploy_app_name - codedeploy_group_name = var.codedeploy_group_name - app_specs_bucket = var.app_specs_bucket - region = var.region - cluster_name = module.ecs.cluster_name - service_name = module.ecs.service_name - lb_listener_arn = module.load_balancer.listener_arn - lb_blue_target_group_arn = module.load_balancer.blue_target_group_arn - lb_green_target_group_arn = module.load_balancer.green_target_group_arn + project_name = var.project_name + codedeploy_app_name = var.codedeploy_app_name + codedeploy_group_name = var.codedeploy_group_name + app_specs_bucket = var.app_specs_bucket + region = var.region + cluster_name = module.ecs.cluster_name + service_name = module.ecs.service_name + lb_listener_arn = module.load_balancer.listener_arn + lb_blue_target_group = module.load_balancer.blue_target_group + lb_green_target_group = module.load_balancer.green_target_group } module "auto_scaling" { diff --git a/tf/variables.tfvars b/tf/variables.tfvars index 0d00d59..7640d90 100644 --- a/tf/variables.tfvars +++ b/tf/variables.tfvars @@ -1,7 +1,7 @@ -project_name = "fargate-auto-scaled-backend" -codedeploy_app_name = "fargate-auto-scaled-backend-ecs-codedeploy" -codedeploy_group_name = "fargate-auto-scaled-backend-ecs-blue-green-group" -app_specs_bucket = "fargate-auto-scaled-backend-ecs-app-specs" +project_name = "fargate-scaled-backend" +codedeploy_app_name = "fargate-scaled-backend-ecs-codedeploy" +codedeploy_group_name = "fargate-scaled-backend-ecs-blue-green-group" +app_specs_bucket = "fargate-scaled-backend-ecs-app-specs" region = "eu-west-2" private_vpc_name = "ecs-private-vpc" api_stage_name = "dev" From a4695ed3a25b22852543f4baf1cff1ee9aa2dd38 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 1 Oct 2024 19:00:32 +0100 Subject: [PATCH 097/116] repo name --- .github/actions/build_image/action.yml | 17 ++++++++++------- .github/workflows/build.yml | 2 ++ .github/workflows/destroy.yml | 1 + .github/workflows/init.yml | 2 ++ tf/ecr/main.tf | 2 +- tf/ecr/variables.tf | 4 ++++ tf/service/load_balancer/outputs.tf | 4 ++++ tf/task/data.tf | 2 +- tf/task/variables.tf | 4 ++++ 9 files changed, 29 insertions(+), 9 deletions(-) diff --git a/.github/actions/build_image/action.yml b/.github/actions/build_image/action.yml index 3fcda9c..9d01d3b 100644 --- a/.github/actions/build_image/action.yml +++ b/.github/actions/build_image/action.yml @@ -8,6 +8,9 @@ inputs: aws_region: description: 'ECR aws region' required: true + ecr_repository_name: + description: 'ECR repo name' + required: true runs: using: 'composite' @@ -23,7 +26,7 @@ runs: id: check_should_build shell: bash run: | - IMAGE_COUNT=$(aws ecr describe-images --repository-name ${{ github.event.repository.name }} --region ${{ inputs.aws_region }} --query 'imageDetails | length(@)' --output text) + IMAGE_COUNT=$(aws ecr describe-images --repository-name ${{ inputs.ecr_repository_name }} --region ${{ inputs.aws_region }} --query 'imageDetails | length(@)' --output text) echo Image count: "$IMAGE_COUNT" if [[ "${{ steps.changes.outputs.src }}" == "true" || "$IMAGE_COUNT" -eq 0 ]]; then echo "Either src changed or ECR is empty" @@ -43,7 +46,7 @@ runs: name: Set variables shell: bash run: | - echo "LOCAL_IMAGE=${{ github.event.repository.name }}:local" >> $GITHUB_ENV + echo "LOCAL_IMAGE=${{ inputs.ecr_repository_name }}:local" >> $GITHUB_ENV echo "IMAGE_TAG=$(echo $GITHUB_SHA | cut -c 1-6)" >> $GITHUB_ENV - if: env.SHOULD_BUILD == 'true' @@ -51,15 +54,15 @@ runs: shell: bash run: | docker build . -t $LOCAL_IMAGE - docker tag $LOCAL_IMAGE ${{ inputs.aws_account_id }}.dkr.ecr.${{ inputs.aws_region }}.amazonaws.com/${{ github.event.repository.name }}:$IMAGE_TAG + docker tag $LOCAL_IMAGE ${{ inputs.aws_account_id }}.dkr.ecr.${{ inputs.aws_region }}.amazonaws.com/${{ inputs.ecr_repository_name }}:$IMAGE_TAG - if: env.SHOULD_BUILD == 'true' name: Push Docker Image to ECR shell: bash run: | aws ecr get-login-password --region ${{ inputs.aws_region }} | docker login --username AWS --password-stdin ${{ inputs.aws_account_id }}.dkr.ecr.${{ inputs.aws_region }}.amazonaws.com - docker push ${{ inputs.aws_account_id }}.dkr.ecr.${{ inputs.aws_region }}.amazonaws.com/${{ github.event.repository.name }}:$IMAGE_TAG - IMAGE_URI="${{ inputs.aws_account_id }}.dkr.ecr.${{ inputs.aws_region }}.amazonaws.com/${{ github.event.repository.name }}:$IMAGE_TAG" + docker push ${{ inputs.aws_account_id }}.dkr.ecr.${{ inputs.aws_region }}.amazonaws.com/${{ inputs.ecr_repository_name }}:$IMAGE_TAG + IMAGE_URI="${{ inputs.aws_account_id }}.dkr.ecr.${{ inputs.aws_region }}.amazonaws.com/${{ inputs.ecr_repository_name }}:$IMAGE_TAG" echo "IMAGE_URI=$IMAGE_URI" >> $GITHUB_ENV echo Image:$IMAGE_URI @@ -67,8 +70,8 @@ runs: name: Get Latest ECR Image Tag shell: bash run: | - LATEST_TAG=$(aws ecr describe-images --repository-name ${{ github.event.repository.name }} \ + LATEST_TAG=$(aws ecr describe-images --repository-name ${{ inputs.ecr_repository_name }} \ --region ${{ inputs.aws_region }} --query 'sort_by(imageDetails,& imagePushedAt)[-1].imageTags[0]' --output text) - IMAGE_URI="${{ inputs.aws_account_id }}.dkr.ecr.${{ inputs.aws_region }}.amazonaws.com/${{ github.event.repository.name }}:$LATEST_TAG" + IMAGE_URI="${{ inputs.aws_account_id }}.dkr.ecr.${{ inputs.aws_region }}.amazonaws.com/${{ inputs.ecr_repository_name }}:$LATEST_TAG" echo "$IMAGE_TAG=$LATEST_TAG" >> $GITHUB_ENV echo "IMAGE_URI=$IMAGE_URI" >> $GITHUB_ENV diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 15ab988..233aefb 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -47,6 +47,7 @@ jobs: with: aws_account_id: ${{ inputs.aws_account_id }} aws_region: ${{ inputs.aws_region }} + ecr_repository_name: ${{ github.event.repository.name }} - name: Set image_uri output id: set-image-uri @@ -58,6 +59,7 @@ jobs: runs-on: ubuntu-latest env: TF_VAR_image_uri: ${{ needs.image.outputs.image_uri }} + TF_VAR_ecr_repository_name: ${{ github.event.repository.name }} outputs: task_definition_arn: ${{ steps.set-envs.outputs.TASK_DEFINITION_ARN }} task_definition_revision: ${{ steps.set-envs.outputs.TASK_DEFINITION_REVISION }} diff --git a/.github/workflows/destroy.yml b/.github/workflows/destroy.yml index b484e01..75236c9 100644 --- a/.github/workflows/destroy.yml +++ b/.github/workflows/destroy.yml @@ -42,6 +42,7 @@ jobs: runs-on: ubuntu-latest env: TF_VAR_image_uri: dummy + TF_VAR_ecr_repository_name: ${{ github.event.repository.name }} steps: - uses: actions/checkout@v4 - name: Configure AWS Credentials diff --git a/.github/workflows/init.yml b/.github/workflows/init.yml index 76ee38c..b25dd64 100644 --- a/.github/workflows/init.yml +++ b/.github/workflows/init.yml @@ -32,6 +32,8 @@ jobs: ecr: runs-on: ubuntu-latest + env: + TF_VAR_ecr_repository_name: ${{ github.event.repository.name }} steps: - uses: actions/checkout@v4 - uses: aws-actions/configure-aws-credentials@v4 diff --git a/tf/ecr/main.tf b/tf/ecr/main.tf index b46a239..4aa5990 100644 --- a/tf/ecr/main.tf +++ b/tf/ecr/main.tf @@ -36,7 +36,7 @@ resource "aws_vpc_endpoint" "gateway_s3" { } resource "aws_ecr_repository" "this" { - name = var.project_name + name = var.ecr_repository_name image_tag_mutability = "MUTABLE" force_delete = true diff --git a/tf/ecr/variables.tf b/tf/ecr/variables.tf index 660f0f5..7790ff8 100644 --- a/tf/ecr/variables.tf +++ b/tf/ecr/variables.tf @@ -2,6 +2,10 @@ variable "project_name" { type = string } +variable "ecr_repository_name" { + type = string +} + variable "region" { type = string } diff --git a/tf/service/load_balancer/outputs.tf b/tf/service/load_balancer/outputs.tf index 8b23aac..fb8fb97 100644 --- a/tf/service/load_balancer/outputs.tf +++ b/tf/service/load_balancer/outputs.tf @@ -6,6 +6,10 @@ output "listener_arn" { value = aws_lb_listener.listener.arn } +output "blue_target_group_arn" { + value = aws_lb_target_group.tg_blue.arn +} + output "blue_target_group" { value = aws_lb_target_group.tg_blue.name } diff --git a/tf/task/data.tf b/tf/task/data.tf index 3983a4f..ae46c5d 100644 --- a/tf/task/data.tf +++ b/tf/task/data.tf @@ -1,5 +1,5 @@ data "aws_ecr_repository" "this" { - name = var.project_name + name = var.ecr_repository_name } data "aws_iam_policy_document" "assume_role" { diff --git a/tf/task/variables.tf b/tf/task/variables.tf index d3c78ba..dca94aa 100644 --- a/tf/task/variables.tf +++ b/tf/task/variables.tf @@ -2,6 +2,10 @@ variable "project_name" { type = string } +variable "ecr_repository_name" { + type = string +} + variable "region" { type = string } From eb86c480041edbb1534323ded1938fdc5c505eeb Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 1 Oct 2024 19:04:19 +0100 Subject: [PATCH 098/116] TF_VAR_ecr_repository_name --- .github/workflows/destroy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/destroy.yml b/.github/workflows/destroy.yml index 75236c9..60930d5 100644 --- a/.github/workflows/destroy.yml +++ b/.github/workflows/destroy.yml @@ -5,6 +5,7 @@ on: env: TF_VAR_load_balancer_listener_arn: "arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/dummy-target-group/1234567890123456" + TF_VAR_ecr_repository_name: ${{ github.event.repository.name }} permissions: id-token: write @@ -42,7 +43,6 @@ jobs: runs-on: ubuntu-latest env: TF_VAR_image_uri: dummy - TF_VAR_ecr_repository_name: ${{ github.event.repository.name }} steps: - uses: actions/checkout@v4 - name: Configure AWS Credentials From ccb1c7854770172c427ee6ae1e6f8a0cf89e20bc Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 1 Oct 2024 19:09:52 +0100 Subject: [PATCH 099/116] trigger --- .github/workflows/init.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/init.yml b/.github/workflows/init.yml index b25dd64..0e2147b 100644 --- a/.github/workflows/init.yml +++ b/.github/workflows/init.yml @@ -76,4 +76,4 @@ jobs: aws_account_id: ${{ vars.AWS_ACCOUNT_ID }} aws_region: ${{ vars.AWS_REGION }} aws_role: ${{ vars.AWS_ROLE }} - task_definition_arn: ${{ needs.build.outputs.task_definition_arn }} + task_definition_arn: ${{ needs.build.outputs.task_definition_arn }} \ No newline at end of file From 0c1dc950587b690dc90aba851c58b3e1b5fbb93b Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 1 Oct 2024 19:19:39 +0100 Subject: [PATCH 100/116] depl trigger --- .github/workflows/deploy.yml | 6 +++--- .github/workflows/init.yml | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 298f33a..52e87e4 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -1,9 +1,9 @@ name: Deploy on: - # push: - # branches: - # - 'blue-green-deploy' + push: + branches: + - 'blue-green-deploy' workflow_dispatch: permissions: diff --git a/.github/workflows/init.yml b/.github/workflows/init.yml index 0e2147b..4f665bd 100644 --- a/.github/workflows/init.yml +++ b/.github/workflows/init.yml @@ -1,9 +1,9 @@ name: Init on: - push: - branches: - - 'blue-green-deploy' + # push: + # branches: + # - 'blue-green-deploy' workflow_dispatch: permissions: From f54d22323d8ca743c79aa95f72f707a9cf7587c6 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 1 Oct 2024 20:09:27 +0100 Subject: [PATCH 101/116] codedeploy iams --- .github/workflows/deploy.yml | 6 +++--- .github/workflows/init.yml | 6 +++--- tf/service/deploy/data.tf | 16 +++++++++++++--- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 52e87e4..298f33a 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -1,9 +1,9 @@ name: Deploy on: - push: - branches: - - 'blue-green-deploy' + # push: + # branches: + # - 'blue-green-deploy' workflow_dispatch: permissions: diff --git a/.github/workflows/init.yml b/.github/workflows/init.yml index 4f665bd..0e2147b 100644 --- a/.github/workflows/init.yml +++ b/.github/workflows/init.yml @@ -1,9 +1,9 @@ name: Init on: - # push: - # branches: - # - 'blue-green-deploy' + push: + branches: + - 'blue-green-deploy' workflow_dispatch: permissions: diff --git a/tf/service/deploy/data.tf b/tf/service/deploy/data.tf index f98a650..4557944 100644 --- a/tf/service/deploy/data.tf +++ b/tf/service/deploy/data.tf @@ -18,11 +18,21 @@ data "aws_iam_policy_document" "codedeploy_assume_role_policy" { data "aws_iam_policy_document" "codedeploy_policy" { statement { actions = [ + "ecs:CreateTaskSet", "ecs:UpdateService", "ecs:DescribeServices", - "elasticloadbalancing:*", - "autoscaling:*", - "codedeploy:*" + "ecs:DeleteTaskSet", + "ecs:DescribeTaskSets", + "ecs:UpdateTaskSet", + "elasticloadbalancing:ModifyListener", + "elasticloadbalancing:ModifyTargetGroup", + "elasticloadbalancing:DeregisterTargets", + "elasticloadbalancing:RegisterTargets", + "autoscaling:DescribeAutoScalingGroups", + "autoscaling:UpdateAutoScalingGroup", + "codedeploy:CreateDeployment", + "codedeploy:GetDeployment", + "codedeploy:StopDeployment" ] effect = "Allow" resources = ["*"] From 07ea8963a8b3f835fc63f1c86c72d37503843b40 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 1 Oct 2024 20:28:10 +0100 Subject: [PATCH 102/116] deploy --- .github/workflows/deploy.yml | 6 +++--- .github/workflows/init.yml | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 298f33a..52e87e4 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -1,9 +1,9 @@ name: Deploy on: - # push: - # branches: - # - 'blue-green-deploy' + push: + branches: + - 'blue-green-deploy' workflow_dispatch: permissions: diff --git a/.github/workflows/init.yml b/.github/workflows/init.yml index 0e2147b..4f665bd 100644 --- a/.github/workflows/init.yml +++ b/.github/workflows/init.yml @@ -1,9 +1,9 @@ name: Init on: - push: - branches: - - 'blue-green-deploy' + # push: + # branches: + # - 'blue-green-deploy' workflow_dispatch: permissions: From 3220935fb82a3b6e79be50db2b67cd92ec5f5957 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 1 Oct 2024 20:40:57 +0100 Subject: [PATCH 103/116] iam fixes --- tf/service/deploy/data.tf | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/tf/service/deploy/data.tf b/tf/service/deploy/data.tf index 4557944..e975316 100644 --- a/tf/service/deploy/data.tf +++ b/tf/service/deploy/data.tf @@ -18,21 +18,21 @@ data "aws_iam_policy_document" "codedeploy_assume_role_policy" { data "aws_iam_policy_document" "codedeploy_policy" { statement { actions = [ - "ecs:CreateTaskSet", + "elasticloadbalancing:RegisterTargets", + "elasticloadbalancing:ModifyTargetGroup", + "elasticloadbalancing:ModifyListener", + "elasticloadbalancing:DeregisterTargets", + "ecs:UpdateTaskSet", "ecs:UpdateService", + "ecs:DescribeTaskSets", "ecs:DescribeServices", "ecs:DeleteTaskSet", - "ecs:DescribeTaskSets", - "ecs:UpdateTaskSet", - "elasticloadbalancing:ModifyListener", - "elasticloadbalancing:ModifyTargetGroup", - "elasticloadbalancing:DeregisterTargets", - "elasticloadbalancing:RegisterTargets", - "autoscaling:DescribeAutoScalingGroups", - "autoscaling:UpdateAutoScalingGroup", - "codedeploy:CreateDeployment", + "ecs:CreateTaskSet", + "codedeploy:StopDeployment", "codedeploy:GetDeployment", - "codedeploy:StopDeployment" + "codedeploy:CreateDeployment", + "autoscaling:UpdateAutoScalingGroup", + "autoscaling:DescribeAutoScalingGroups" ] effect = "Allow" resources = ["*"] From 6876a6e693a5bb31bd996be41dbbbd12720c784d Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Tue, 1 Oct 2024 20:52:59 +0100 Subject: [PATCH 104/116] get id --- .github/workflows/deploy.yml | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 52e87e4..b359b82 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -64,35 +64,28 @@ jobs: run: aws s3 cp ${{ env.APP_SPEC_FILE }} s3://${{ needs.code.outputs.app_specs_bucket}}/${{ needs.code.outputs.task_definition_revision }}-${{ env.APP_SPEC_FILE }} - name: Create CodeDeploy Deployment + id: create-deployment env: APP_NAME: ${{ steps.read-vars.outputs.CODE_DEPLOY_APP_NAME }} GROUP_NAME: ${{ steps.read-vars.outputs.CODE_DEPLOY_GROUP_NAME }} run: | echo "Creating CodeDeploy deployment" - aws deploy create-deployment \ + DEPLOYMENT_OUTPUT=$(aws deploy create-deployment \ --application-name "$APP_NAME" \ --deployment-group-name "$GROUP_NAME" \ --deployment-config-name CodeDeployDefault.ECSAllAtOnce \ --revision "{\"revisionType\":\"S3\",\"s3Location\":{\"bucket\":\"${{ needs.code.outputs.app_specs_bucket}}\",\"key\":\"${{ needs.code.outputs.task_definition_revision }}-${{ env.APP_SPEC_FILE }}\",\"bundleType\":\"YAML\"}}" \ - --region ${{ vars.AWS_REGION }} + --region ${{ vars.AWS_REGION }}) + DEPLOYMENT_ID=$(echo "$DEPLOYMENT_OUTPUT" | jq -r '.deploymentId') + echo "DEPLOYMENT_ID=$DEPLOYMENT_ID" >> $GITHUB_OUTPUT - name: Monitor Deployment Status env: APP_NAME: ${{ steps.read-vars.outputs.CODE_DEPLOY_APP_NAME }} GROUP_NAME: ${{ steps.read-vars.outputs.CODE_DEPLOY_GROUP_NAME }} + DEPLOYMENT_ID: ${{ steps.create-deployment.outputs.DEPLOYMENT_ID }} run: | echo "Monitoring CodeDeploy deployment status" - DEPLOYMENT_ID=$(aws deploy list-deployments \ - --application-name "$APP_NAME" \ - --deployment-group-name "$GROUP_NAME" \ - --region ${{ vars.AWS_REGION }} \ - --max-items 1 \ - --query 'deployments[0]' --output text) - - if [ "$DEPLOYMENT_ID" == "None" ]; then - echo "No deployment found." - exit 1 - fi echo "Deployment ID: $DEPLOYMENT_ID" From 50d9b02fd7ff86ca2ba810563e8740534df05a58 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Wed, 2 Oct 2024 09:23:12 +0100 Subject: [PATCH 105/116] allow code deploy ecs task access --- tf/service/deploy/data.tf | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tf/service/deploy/data.tf b/tf/service/deploy/data.tf index e975316..9b61040 100644 --- a/tf/service/deploy/data.tf +++ b/tf/service/deploy/data.tf @@ -49,4 +49,17 @@ data "aws_iam_policy_document" "codedeploy_policy" { "${data.aws_s3_bucket.app_specs.arn}/*" ] } + + statement { + effect = "Allow" + actions = [ + "iam:PassRole" + ] + resources = ["*"] + condition { + test = "StringLike" + variable = "iam:PassedToService" + values = ["ecs-tasks.amazonaws.com"] + } + } } From a9f21132fe85fe8187dece8e57f5b7ddfd52ed98 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Wed, 2 Oct 2024 09:27:59 +0100 Subject: [PATCH 106/116] trig --- .github/workflows/deploy.yml | 6 +++--- .github/workflows/init.yml | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index b359b82..ba58f25 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -1,9 +1,9 @@ name: Deploy on: - push: - branches: - - 'blue-green-deploy' + # push: + # branches: + # - 'blue-green-deploy' workflow_dispatch: permissions: diff --git a/.github/workflows/init.yml b/.github/workflows/init.yml index 4f665bd..0e2147b 100644 --- a/.github/workflows/init.yml +++ b/.github/workflows/init.yml @@ -1,9 +1,9 @@ name: Init on: - # push: - # branches: - # - 'blue-green-deploy' + push: + branches: + - 'blue-green-deploy' workflow_dispatch: permissions: From 7b74da8e23a1425c1e9e227b8e6490e05622f0e1 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Wed, 2 Oct 2024 11:39:36 +0100 Subject: [PATCH 107/116] minor --- tf/service/deploy/main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tf/service/deploy/main.tf b/tf/service/deploy/main.tf index 42b316f..ec09069 100644 --- a/tf/service/deploy/main.tf +++ b/tf/service/deploy/main.tf @@ -4,7 +4,7 @@ resource "aws_codedeploy_app" "ecs_app" { } resource "aws_iam_role" "this" { - name = "${var.project_name}-codedeploy_role" + name = "${var.project_name}-codedeploy-role" assume_role_policy = data.aws_iam_policy_document.codedeploy_assume_role_policy.json } From 834af8281b2b880befc68550d346b12fe0b7427c Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Wed, 2 Oct 2024 12:56:02 +0100 Subject: [PATCH 108/116] lock down codedeploy iam --- .github/workflows/deploy.yml | 3 -- tf/service/auto_scaling/outputs.tf | 7 +++ tf/service/deploy/data.tf | 81 ++++++++++++++++++++++++++--- tf/service/deploy/locals.tf | 3 ++ tf/service/deploy/variables.tf | 24 +++++++++ tf/service/ecs/outputs.tf | 4 ++ tf/service/load_balancer/outputs.tf | 8 +++ tf/service/main.tf | 26 +++++---- 8 files changed, 135 insertions(+), 21 deletions(-) create mode 100644 tf/service/auto_scaling/outputs.tf create mode 100644 tf/service/deploy/locals.tf diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index ba58f25..eee0cdc 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -1,9 +1,6 @@ name: Deploy on: - # push: - # branches: - # - 'blue-green-deploy' workflow_dispatch: permissions: diff --git a/tf/service/auto_scaling/outputs.tf b/tf/service/auto_scaling/outputs.tf new file mode 100644 index 0000000..583db12 --- /dev/null +++ b/tf/service/auto_scaling/outputs.tf @@ -0,0 +1,7 @@ +output "scale_up_arn" { + value = aws_appautoscaling_policy.scale_up.arn +} + +output "scale_down_arn" { + value = aws_appautoscaling_policy.scale_down.arn +} diff --git a/tf/service/deploy/data.tf b/tf/service/deploy/data.tf index 9b61040..4c620be 100644 --- a/tf/service/deploy/data.tf +++ b/tf/service/deploy/data.tf @@ -1,3 +1,5 @@ +data "aws_caller_identity" "current" {} + data "aws_s3_bucket" "app_specs" { bucket = var.app_specs_bucket } @@ -19,31 +21,90 @@ data "aws_iam_policy_document" "codedeploy_policy" { statement { actions = [ "elasticloadbalancing:RegisterTargets", + "elasticloadbalancing:DeregisterTargets", "elasticloadbalancing:ModifyTargetGroup", + "elasticloadbalancing:DescribeTargetGroups", + "elasticloadbalancing:CreateListener", + "elasticloadbalancing:DeleteListener", "elasticloadbalancing:ModifyListener", - "elasticloadbalancing:DeregisterTargets", + "elasticloadbalancing:DescribeListeners", + "elasticloadbalancing:DescribeLoadBalancers", + "elasticloadbalancing:DescribeTargetHealth", + "elasticloadbalancing:CreateRule", + "elasticloadbalancing:DeleteRule", + "elasticloadbalancing:ModifyRule", + "elasticloadbalancing:DescribeRules" + ] + effect = "Allow" + + resources = [ + var.load_balancer_arn, + var.lb_green_target_group_arn, + var.lb_blue_target_group_arn + ] + } + + statement { + actions = [ "ecs:UpdateTaskSet", "ecs:UpdateService", "ecs:DescribeTaskSets", "ecs:DescribeServices", "ecs:DeleteTaskSet", "ecs:CreateTaskSet", + "ecs:UpdateServicePrimaryTaskSet" + ] + effect = "Allow" + + resources = [ + var.cluster_arn, + local.ecs_service_arn + ] + } + + statement { + actions = [ "codedeploy:StopDeployment", "codedeploy:GetDeployment", - "codedeploy:CreateDeployment", - "autoscaling:UpdateAutoScalingGroup", - "autoscaling:DescribeAutoScalingGroups" + "codedeploy:CreateDeployment" + ] + effect = "Allow" + + resources = [ + aws_codedeploy_app.ecs_app.arn, + aws_codedeploy_deployment_group.this.arn ] - effect = "Allow" - resources = ["*"] } statement { + actions = [ + "autoscaling:DescribeAutoScalingGroups", + "autoscaling:UpdateAutoScalingGroup", + "autoscaling:DescribeScalingActivities", + "autoscaling:DescribePolicies", + "autoscaling:PutScalingPolicy", + "autoscaling:ExecutePolicy", + "autoscaling:CompleteLifecycleAction", + "autoscaling:DescribeScheduledActions", + "autoscaling:TerminateInstanceInAutoScalingGroup" + ] effect = "Allow" + + resources = [ + local.ecs_service_arn, + var.appautoscaling_policy_scale_up_arn, + var.appautoscaling_policy_scale_down_arn + ] + } + + statement { actions = [ "s3:GetObject", "s3:ListBucket" ] + + effect = "Allow" + resources = [ data.aws_s3_bucket.app_specs.arn, "${data.aws_s3_bucket.app_specs.arn}/*" @@ -51,11 +112,15 @@ data "aws_iam_policy_document" "codedeploy_policy" { } statement { - effect = "Allow" actions = [ "iam:PassRole" ] - resources = ["*"] + + effect = "Allow" + + resources = [ + "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/*" + ] condition { test = "StringLike" variable = "iam:PassedToService" diff --git a/tf/service/deploy/locals.tf b/tf/service/deploy/locals.tf new file mode 100644 index 0000000..18b944c --- /dev/null +++ b/tf/service/deploy/locals.tf @@ -0,0 +1,3 @@ +locals { + ecs_service_arn = "arn:aws:ecs:${var.region}:${data.aws_caller_identity.current.account_id}:service/${var.cluster_name}/${var.service_name}" +} \ No newline at end of file diff --git a/tf/service/deploy/variables.tf b/tf/service/deploy/variables.tf index 213624a..92f4a23 100644 --- a/tf/service/deploy/variables.tf +++ b/tf/service/deploy/variables.tf @@ -10,6 +10,10 @@ variable "cluster_name" { type = string } +variable "cluster_arn" { + type = string +} + variable "service_name" { type = string } @@ -26,14 +30,34 @@ variable "app_specs_bucket" { type = string } +variable "load_balancer_arn" { + type = string +} + variable "lb_listener_arn" { type = string } +variable "lb_green_target_group_arn" { + type = string +} + +variable "lb_blue_target_group_arn" { + type = string +} + variable "lb_green_target_group" { type = string } variable "lb_blue_target_group" { type = string +} + +variable "appautoscaling_policy_scale_up_arn" { + type = string +} + +variable "appautoscaling_policy_scale_down_arn" { + type = string } \ No newline at end of file diff --git a/tf/service/ecs/outputs.tf b/tf/service/ecs/outputs.tf index f2ce207..4c2f62e 100644 --- a/tf/service/ecs/outputs.tf +++ b/tf/service/ecs/outputs.tf @@ -5,3 +5,7 @@ output "cluster_name" { output "service_name" { value = aws_ecs_service.ecs.name } + +output "cluster_arn" { + value = aws_ecs_cluster.cluster.arn +} diff --git a/tf/service/load_balancer/outputs.tf b/tf/service/load_balancer/outputs.tf index fb8fb97..e9104d6 100644 --- a/tf/service/load_balancer/outputs.tf +++ b/tf/service/load_balancer/outputs.tf @@ -2,6 +2,10 @@ output "security_group_id" { value = aws_security_group.lb_sg.id } +output "load_balancer_arn" { + value = aws_lb.lb.arn +} + output "listener_arn" { value = aws_lb_listener.listener.arn } @@ -17,3 +21,7 @@ output "blue_target_group" { output "green_target_group" { value = aws_lb_target_group.tg_green.name } + +output "green_target_group_arn" { + value = aws_lb_target_group.tg_green.arn +} diff --git a/tf/service/main.tf b/tf/service/main.tf index da3aaa6..5440702 100644 --- a/tf/service/main.tf +++ b/tf/service/main.tf @@ -27,16 +27,22 @@ module "load_balancer" { module "deploy" { source = "./deploy" - project_name = var.project_name - codedeploy_app_name = var.codedeploy_app_name - codedeploy_group_name = var.codedeploy_group_name - app_specs_bucket = var.app_specs_bucket - region = var.region - cluster_name = module.ecs.cluster_name - service_name = module.ecs.service_name - lb_listener_arn = module.load_balancer.listener_arn - lb_blue_target_group = module.load_balancer.blue_target_group - lb_green_target_group = module.load_balancer.green_target_group + project_name = var.project_name + appautoscaling_policy_scale_up_arn = module.auto_scaling.scale_up_arn + appautoscaling_policy_scale_down_arn = module.auto_scaling.scale_down_arn + codedeploy_app_name = var.codedeploy_app_name + codedeploy_group_name = var.codedeploy_group_name + app_specs_bucket = var.app_specs_bucket + region = var.region + cluster_name = module.ecs.cluster_name + cluster_arn = module.ecs.cluster_arn + service_name = module.ecs.service_name + load_balancer_arn = module.load_balancer.load_balancer_arn + lb_listener_arn = module.load_balancer.listener_arn + lb_blue_target_group = module.load_balancer.blue_target_group + lb_blue_target_group_arn = module.load_balancer.blue_target_group_arn + lb_green_target_group = module.load_balancer.green_target_group + lb_green_target_group_arn = module.load_balancer.green_target_group_arn } module "auto_scaling" { From 3283d8b49d9048122620a7a1e9b6e4656437395d Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Wed, 2 Oct 2024 13:36:04 +0100 Subject: [PATCH 109/116] individual policies --- tf/service/deploy/data.tf | 20 ++++++------ tf/service/deploy/main.tf | 68 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 76 insertions(+), 12 deletions(-) diff --git a/tf/service/deploy/data.tf b/tf/service/deploy/data.tf index 4c620be..293302b 100644 --- a/tf/service/deploy/data.tf +++ b/tf/service/deploy/data.tf @@ -17,7 +17,7 @@ data "aws_iam_policy_document" "codedeploy_assume_role_policy" { } } -data "aws_iam_policy_document" "codedeploy_policy" { +data "aws_iam_policy_document" "elb_policy" { statement { actions = [ "elasticloadbalancing:RegisterTargets", @@ -36,14 +36,15 @@ data "aws_iam_policy_document" "codedeploy_policy" { "elasticloadbalancing:DescribeRules" ] effect = "Allow" - resources = [ var.load_balancer_arn, var.lb_green_target_group_arn, var.lb_blue_target_group_arn ] } +} +data "aws_iam_policy_document" "ecs_policy" { statement { actions = [ "ecs:UpdateTaskSet", @@ -55,13 +56,14 @@ data "aws_iam_policy_document" "codedeploy_policy" { "ecs:UpdateServicePrimaryTaskSet" ] effect = "Allow" - resources = [ var.cluster_arn, local.ecs_service_arn ] } +} +data "aws_iam_policy_document" "codedeploy_policy" { statement { actions = [ "codedeploy:StopDeployment", @@ -69,13 +71,14 @@ data "aws_iam_policy_document" "codedeploy_policy" { "codedeploy:CreateDeployment" ] effect = "Allow" - resources = [ aws_codedeploy_app.ecs_app.arn, aws_codedeploy_deployment_group.this.arn ] } +} +data "aws_iam_policy_document" "autoscaling_policy" { statement { actions = [ "autoscaling:DescribeAutoScalingGroups", @@ -89,35 +92,34 @@ data "aws_iam_policy_document" "codedeploy_policy" { "autoscaling:TerminateInstanceInAutoScalingGroup" ] effect = "Allow" - resources = [ local.ecs_service_arn, var.appautoscaling_policy_scale_up_arn, var.appautoscaling_policy_scale_down_arn ] } +} +data "aws_iam_policy_document" "s3_policy" { statement { actions = [ "s3:GetObject", "s3:ListBucket" ] - effect = "Allow" - resources = [ data.aws_s3_bucket.app_specs.arn, "${data.aws_s3_bucket.app_specs.arn}/*" ] } +} +data "aws_iam_policy_document" "passrole_policy" { statement { actions = [ "iam:PassRole" ] - effect = "Allow" - resources = [ "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/*" ] diff --git a/tf/service/deploy/main.tf b/tf/service/deploy/main.tf index ec09069..c365803 100644 --- a/tf/service/deploy/main.tf +++ b/tf/service/deploy/main.tf @@ -8,11 +8,73 @@ resource "aws_iam_role" "this" { assume_role_policy = data.aws_iam_policy_document.codedeploy_assume_role_policy.json } -resource "aws_iam_role_policy" "codedeploy_role_policy" { - role = aws_iam_role.this.id - policy = data.aws_iam_policy_document.codedeploy_policy.json +resource "aws_iam_policy" "elb_policy" { + name = "${var.project_name}-ELBPolicy" + description = "Policy for ELB actions" + policy = data.aws_iam_policy_document.elb_policy.json } +resource "aws_iam_policy" "ecs_policy" { + name = "${var.project_name}-ECSPolicy" + description = "Policy for ECS actions" + policy = data.aws_iam_policy_document.ecs_policy.json +} + +resource "aws_iam_policy" "codedeploy_policy" { + name = "${var.project_name}-CodeDeployPolicy" + description = "Policy for CodeDeploy actions" + policy = data.aws_iam_policy_document.codedeploy_policy.json +} + +resource "aws_iam_policy" "autoscaling_policy" { + name = "${var.project_name}-AutoScalingPolicy" + description = "Policy for Auto Scaling actions" + policy = data.aws_iam_policy_document.autoscaling_policy.json +} + +resource "aws_iam_policy" "s3_policy" { + name = "${var.project_name}-S3Policy" + description = "Policy for S3 actions" + policy = data.aws_iam_policy_document.s3_policy.json +} + +resource "aws_iam_policy" "passrole_policy" { + name = "${var.project_name}-PassRolePolicy" + description = "Policy for IAM PassRole action" + policy = data.aws_iam_policy_document.passrole_policy.json +} + +resource "aws_iam_role_policy_attachment" "attach_elb_policy" { + role = aws_iam_role.this.name + policy_arn = aws_iam_policy.elb_policy.arn +} + +resource "aws_iam_role_policy_attachment" "attach_ecs_policy" { + role = aws_iam_role.this.name + policy_arn = aws_iam_policy.ecs_policy.arn +} + +resource "aws_iam_role_policy_attachment" "attach_codedeploy_policy" { + role = aws_iam_role.this.name + policy_arn = aws_iam_policy.codedeploy_policy.arn +} + +resource "aws_iam_role_policy_attachment" "attach_autoscaling_policy" { + role = aws_iam_role.this.name + policy_arn = aws_iam_policy.autoscaling_policy.arn +} + +resource "aws_iam_role_policy_attachment" "attach_s3_policy" { + role = aws_iam_role.this.name + policy_arn = aws_iam_policy.s3_policy.arn +} + +resource "aws_iam_role_policy_attachment" "attach_passrole_policy" { + role = aws_iam_role.this.name + policy_arn = aws_iam_policy.passrole_policy.arn +} + + resource "aws_codedeploy_deployment_group" "this" { app_name = aws_codedeploy_app.ecs_app.name # Shifts 10% of the traffic in the first increment, then shifts the remaining 90% after 5 minutes From a9cc84ed1a07577a377b794226a21bcd7e5d4634 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Wed, 2 Oct 2024 13:36:11 +0100 Subject: [PATCH 110/116] rm l --- tf/service/deploy/main.tf | 1 - 1 file changed, 1 deletion(-) diff --git a/tf/service/deploy/main.tf b/tf/service/deploy/main.tf index c365803..35bfcb5 100644 --- a/tf/service/deploy/main.tf +++ b/tf/service/deploy/main.tf @@ -74,7 +74,6 @@ resource "aws_iam_role_policy_attachment" "attach_passrole_policy" { policy_arn = aws_iam_policy.passrole_policy.arn } - resource "aws_codedeploy_deployment_group" "this" { app_name = aws_codedeploy_app.ecs_app.name # Shifts 10% of the traffic in the first increment, then shifts the remaining 90% after 5 minutes From 1f8be53686c0e7347fc4e43c8c0596c56df922e2 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Wed, 2 Oct 2024 14:20:36 +0100 Subject: [PATCH 111/116] elb iam fix --- tf/service/deploy/data.tf | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/tf/service/deploy/data.tf b/tf/service/deploy/data.tf index 293302b..fe00e97 100644 --- a/tf/service/deploy/data.tf +++ b/tf/service/deploy/data.tf @@ -21,19 +21,14 @@ data "aws_iam_policy_document" "elb_policy" { statement { actions = [ "elasticloadbalancing:RegisterTargets", - "elasticloadbalancing:DeregisterTargets", "elasticloadbalancing:ModifyTargetGroup", - "elasticloadbalancing:DescribeTargetGroups", - "elasticloadbalancing:CreateListener", - "elasticloadbalancing:DeleteListener", + "elasticloadbalancing:ModifyRule", "elasticloadbalancing:ModifyListener", - "elasticloadbalancing:DescribeListeners", - "elasticloadbalancing:DescribeLoadBalancers", - "elasticloadbalancing:DescribeTargetHealth", - "elasticloadbalancing:CreateRule", + "elasticloadbalancing:DeregisterTargets", "elasticloadbalancing:DeleteRule", - "elasticloadbalancing:ModifyRule", - "elasticloadbalancing:DescribeRules" + "elasticloadbalancing:DeleteListener", + "elasticloadbalancing:CreateRule", + "elasticloadbalancing:CreateListener" ] effect = "Allow" resources = [ @@ -42,6 +37,18 @@ data "aws_iam_policy_document" "elb_policy" { var.lb_blue_target_group_arn ] } + + statement { + actions = [ + "elasticloadbalancing:DescribeListeners", + "elasticloadbalancing:DescribeLoadBalancers", + "elasticloadbalancing:DescribeTargetHealth", + "elasticloadbalancing:DescribeTargetGroups", + "elasticloadbalancing:DescribeRules" + ] + effect = "Allow" + resources = ["*"] + } } data "aws_iam_policy_document" "ecs_policy" { From 51fe5239c8101766981f610bb693bab535825524 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Wed, 2 Oct 2024 14:49:21 +0100 Subject: [PATCH 112/116] add task set to iams --- tf/service/deploy/data.tf | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tf/service/deploy/data.tf b/tf/service/deploy/data.tf index fe00e97..c8eeb88 100644 --- a/tf/service/deploy/data.tf +++ b/tf/service/deploy/data.tf @@ -65,7 +65,8 @@ data "aws_iam_policy_document" "ecs_policy" { effect = "Allow" resources = [ var.cluster_arn, - local.ecs_service_arn + local.ecs_service_arn, + local.task_set_arn ] } } From a0acc7535a43ffdcd01e2a42055aa9ab900dae77 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Wed, 2 Oct 2024 14:49:48 +0100 Subject: [PATCH 113/116] pass in dep config name --- .github/workflows/deploy.yml | 7 ++++++- tf/service/deploy/locals.tf | 1 + tf/service/deploy/main.tf | 3 +-- tf/service/deploy/variables.tf | 5 +++++ tf/service/main.tf | 1 + tf/service/variables.tf | 4 ++++ tf/variables.tfvars | 3 ++- 7 files changed, 20 insertions(+), 4 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index eee0cdc..0f26894 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -49,6 +49,10 @@ jobs: echo "Extracted project_name: $PROJECT_NAME" echo "PROJECT_NAME=$PROJECT_NAME" >> $GITHUB_OUTPUT + DEPLOYMENT_CONFIG=$(grep 'deployment_config' "${{ env.TF_VAR_FILE }}" | sed 's/.*= "\(.*\)"/\1/') + echo "Extracted deployment_confi: $DEPLOYMENT_CONFIG" + echo "DEPLOYMENT_CONFIG=$DEPLOYMENT_CONFIG" >> $GITHUB_OUTPUT + - name: Prepare AppSpec File run: | sed -i 's|{{TASK_VERSION}}|${{ needs.code.outputs.task_definition_revision }}|g' ${{ env.APP_SPEC_FILE }} @@ -65,12 +69,13 @@ jobs: env: APP_NAME: ${{ steps.read-vars.outputs.CODE_DEPLOY_APP_NAME }} GROUP_NAME: ${{ steps.read-vars.outputs.CODE_DEPLOY_GROUP_NAME }} + DEPLOYMENT_CONFIG: ${{ steps.read-vars.outputs.DEPLOYMENT_CONFIG }} run: | echo "Creating CodeDeploy deployment" DEPLOYMENT_OUTPUT=$(aws deploy create-deployment \ --application-name "$APP_NAME" \ --deployment-group-name "$GROUP_NAME" \ - --deployment-config-name CodeDeployDefault.ECSAllAtOnce \ + --deployment-config-name $DEPLOYMENT_CONFIG \ --revision "{\"revisionType\":\"S3\",\"s3Location\":{\"bucket\":\"${{ needs.code.outputs.app_specs_bucket}}\",\"key\":\"${{ needs.code.outputs.task_definition_revision }}-${{ env.APP_SPEC_FILE }}\",\"bundleType\":\"YAML\"}}" \ --region ${{ vars.AWS_REGION }}) DEPLOYMENT_ID=$(echo "$DEPLOYMENT_OUTPUT" | jq -r '.deploymentId') diff --git a/tf/service/deploy/locals.tf b/tf/service/deploy/locals.tf index 18b944c..5e096e0 100644 --- a/tf/service/deploy/locals.tf +++ b/tf/service/deploy/locals.tf @@ -1,3 +1,4 @@ locals { ecs_service_arn = "arn:aws:ecs:${var.region}:${data.aws_caller_identity.current.account_id}:service/${var.cluster_name}/${var.service_name}" + task_set_arn = "arn:aws:ecs:${var.region}:${data.aws_caller_identity.current.account_id}:task-set/${var.cluster_name}/${var.service_name}/*" } \ No newline at end of file diff --git a/tf/service/deploy/main.tf b/tf/service/deploy/main.tf index 35bfcb5..3751e80 100644 --- a/tf/service/deploy/main.tf +++ b/tf/service/deploy/main.tf @@ -76,8 +76,7 @@ resource "aws_iam_role_policy_attachment" "attach_passrole_policy" { resource "aws_codedeploy_deployment_group" "this" { app_name = aws_codedeploy_app.ecs_app.name - # Shifts 10% of the traffic in the first increment, then shifts the remaining 90% after 5 minutes - deployment_config_name = "CodeDeployDefault.ECSCanary10Percent5Minutes" + deployment_config_name = var.deployment_config_name deployment_group_name = var.codedeploy_group_name service_role_arn = aws_iam_role.this.arn diff --git a/tf/service/deploy/variables.tf b/tf/service/deploy/variables.tf index 92f4a23..1ce991f 100644 --- a/tf/service/deploy/variables.tf +++ b/tf/service/deploy/variables.tf @@ -6,6 +6,11 @@ variable "region" { type = string } +variable "deployment_config_name" { + description = "The deployment configuration strategy for CodeDeploy." + type = string +} + variable "cluster_name" { type = string } diff --git a/tf/service/main.tf b/tf/service/main.tf index 5440702..988af9a 100644 --- a/tf/service/main.tf +++ b/tf/service/main.tf @@ -32,6 +32,7 @@ module "deploy" { appautoscaling_policy_scale_down_arn = module.auto_scaling.scale_down_arn codedeploy_app_name = var.codedeploy_app_name codedeploy_group_name = var.codedeploy_group_name + deployment_config_name = var.codedeploy_deployment_config_name app_specs_bucket = var.app_specs_bucket region = var.region cluster_name = module.ecs.cluster_name diff --git a/tf/service/variables.tf b/tf/service/variables.tf index 1308082..6b4141a 100644 --- a/tf/service/variables.tf +++ b/tf/service/variables.tf @@ -2,6 +2,10 @@ variable "project_name" { type = string } +variable "codedeploy_deployment_config_name" { + type = string +} + variable "codedeploy_app_name" { type = string } diff --git a/tf/variables.tfvars b/tf/variables.tfvars index 7640d90..4580519 100644 --- a/tf/variables.tfvars +++ b/tf/variables.tfvars @@ -5,4 +5,5 @@ app_specs_bucket = "fargate-scaled-backend-ecs-app-specs" region = "eu-west-2" private_vpc_name = "ecs-private-vpc" api_stage_name = "dev" -container_port = 3000 \ No newline at end of file +container_port = 3000 +deployment_config = "CodeDeployDefault.ECSAllAtOnce" \ No newline at end of file From a3d77f1b9e3025cf152943d83a4b5abf29830757 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Wed, 2 Oct 2024 15:00:37 +0100 Subject: [PATCH 114/116] speed up feedback --- .github/workflows/deploy.yml | 2 +- tf/service/deploy/main.tf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 0f26894..6ed2fee 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -112,6 +112,6 @@ jobs: exit 1 else echo "Deployment is in progress..." - sleep 30 + sleep 10 fi done \ No newline at end of file diff --git a/tf/service/deploy/main.tf b/tf/service/deploy/main.tf index 3751e80..daf6d7f 100644 --- a/tf/service/deploy/main.tf +++ b/tf/service/deploy/main.tf @@ -92,7 +92,7 @@ resource "aws_codedeploy_deployment_group" "this" { terminate_blue_instances_on_deployment_success { action = "TERMINATE" - termination_wait_time_in_minutes = 5 + termination_wait_time_in_minutes = 1 } } From c71fbb9686c5f312ac273c3f15523ddcc5784a53 Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Wed, 2 Oct 2024 15:05:58 +0100 Subject: [PATCH 115/116] fix --- tf/service/deploy/data.tf | 2 +- tf/service/deploy/main.tf | 2 +- tf/variables.tfvars | 18 +++++++++--------- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/tf/service/deploy/data.tf b/tf/service/deploy/data.tf index c8eeb88..6a108fe 100644 --- a/tf/service/deploy/data.tf +++ b/tf/service/deploy/data.tf @@ -46,7 +46,7 @@ data "aws_iam_policy_document" "elb_policy" { "elasticloadbalancing:DescribeTargetGroups", "elasticloadbalancing:DescribeRules" ] - effect = "Allow" + effect = "Allow" resources = ["*"] } } diff --git a/tf/service/deploy/main.tf b/tf/service/deploy/main.tf index daf6d7f..36db38a 100644 --- a/tf/service/deploy/main.tf +++ b/tf/service/deploy/main.tf @@ -75,7 +75,7 @@ resource "aws_iam_role_policy_attachment" "attach_passrole_policy" { } resource "aws_codedeploy_deployment_group" "this" { - app_name = aws_codedeploy_app.ecs_app.name + app_name = aws_codedeploy_app.ecs_app.name deployment_config_name = var.deployment_config_name deployment_group_name = var.codedeploy_group_name service_role_arn = aws_iam_role.this.arn diff --git a/tf/variables.tfvars b/tf/variables.tfvars index 4580519..f2f4ee7 100644 --- a/tf/variables.tfvars +++ b/tf/variables.tfvars @@ -1,9 +1,9 @@ -project_name = "fargate-scaled-backend" -codedeploy_app_name = "fargate-scaled-backend-ecs-codedeploy" -codedeploy_group_name = "fargate-scaled-backend-ecs-blue-green-group" -app_specs_bucket = "fargate-scaled-backend-ecs-app-specs" -region = "eu-west-2" -private_vpc_name = "ecs-private-vpc" -api_stage_name = "dev" -container_port = 3000 -deployment_config = "CodeDeployDefault.ECSAllAtOnce" \ No newline at end of file +project_name = "fargate-scaled-backend" +codedeploy_app_name = "fargate-scaled-backend-ecs-codedeploy" +codedeploy_group_name = "fargate-scaled-backend-ecs-blue-green-group" +app_specs_bucket = "fargate-scaled-backend-ecs-app-specs" +region = "eu-west-2" +private_vpc_name = "ecs-private-vpc" +api_stage_name = "dev" +container_port = 3000 +codedeploy_deployment_config_name = "CodeDeployDefault.ECSAllAtOnce" \ No newline at end of file From e560d6699e01bdd31668e2c1d62325e02b9a124a Mon Sep 17 00:00:00 2001 From: chrispsheehan Date: Wed, 2 Oct 2024 16:12:14 +0100 Subject: [PATCH 116/116] ModifyListener iam for lb --- tf/service/deploy/data.tf | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tf/service/deploy/data.tf b/tf/service/deploy/data.tf index 6a108fe..23e9951 100644 --- a/tf/service/deploy/data.tf +++ b/tf/service/deploy/data.tf @@ -38,6 +38,16 @@ data "aws_iam_policy_document" "elb_policy" { ] } + statement { + actions = [ + "elasticloadbalancing:ModifyListener" + ] + effect = "Allow" + resources = [ + var.lb_listener_arn + ] + } + statement { actions = [ "elasticloadbalancing:DescribeListeners",