diff --git a/README.md b/README.md index df17792a..b210375c 100644 --- a/README.md +++ b/README.md @@ -431,6 +431,7 @@ The following inputs can be used as `step.with` keys | `aws_ecs_service_launch_type`| String | Configuration type. Could be `EC2`, `FARGATE` or `EXTERNAL`. Defaults to `FARGATE`. | | `aws_ecs_task_type`| String | Configuration type. Could be `EC2`, `FARGATE` or empty. Will default to `aws_ecs_service_launch_type` if none defined. (Blank if `EXTERNAL`). | | `aws_ecs_task_name`| String | Elastic Container Service task name. If task is defined with a JSON file, should be the same as the container name. | +| `aws_ecs_task_ignore_definition`| Boolean | Toggle to ignore task definition changes after first deployment. Useful when using external tools to manage the task definition. Default: `false`. | | `aws_ecs_task_execution_role`| String | Elastic Container Service task execution role name from IAM. Defaults to `ecsTaskExecutionRole`. | | `aws_ecs_task_json_definition_file`| String | Name of the json file containing task definition. Overrides every other input. | | `aws_ecs_task_network_mode`| String | Network type to use in task definition. One of `none`, `bridge`, `awsvpc`, and `host`. | diff --git a/action.yaml b/action.yaml index 39c798ca..31a72466 100644 --- a/action.yaml +++ b/action.yaml @@ -808,6 +808,9 @@ inputs: aws_ecs_task_name: description: 'Elastic Container Service task name' required: false + aws_ecs_task_ignore_definition: + description: 'Toggle to ignore task definition changes after first deployment. Useful when using external tools to manage the task definition.' + required: false aws_ecs_task_execution_role: description: 'Elastic Container Service task execution role name from IAM. Defaults to "ecsTaskExecutionRole"' required: false @@ -1438,6 +1441,7 @@ runs: AWS_ECS_SERVICE_LAUNCH_TYPE : ${{ inputs.aws_ecs_service_launch_type }} AWS_ECS_TASK_TYPE : ${{ inputs.aws_ecs_task_type }} AWS_ECS_TASK_NAME: ${{ inputs.aws_ecs_task_name }} + AWS_ECS_TASK_IGNORE_DEFINITION: ${{ inputs.aws_ecs_task_ignore_definition }} AWS_ECS_TASK_EXECUTION_ROLE: ${{ inputs.aws_ecs_task_execution_role }} AWS_ECS_TASK_JSON_DEFINITION_FILE: ${{ inputs.aws_ecs_task_json_definition_file }} AWS_ECS_TASK_NETWORK_MODE: ${{ inputs.aws_ecs_task_network_mode }} diff --git a/operations/_scripts/generate/generate_vars_terraform.sh b/operations/_scripts/generate/generate_vars_terraform.sh index ec6a693d..9c3165ca 100644 --- a/operations/_scripts/generate/generate_vars_terraform.sh +++ b/operations/_scripts/generate/generate_vars_terraform.sh @@ -317,6 +317,7 @@ if [[ $(alpha_only "$AWS_ECS_ENABLE") == true ]]; then aws_ecs_service_launch_type=$(generate_var aws_ecs_service_launch_type $AWS_ECS_SERVICE_LAUNCH_TYPE) aws_ecs_task_type=$(generate_var aws_ecs_task_type $AWS_ECS_TASK_TYPE) aws_ecs_task_name=$(generate_var aws_ecs_task_name $AWS_ECS_TASK_NAME) + aws_ecs_task_ignore_definition=$(generate_var aws_ecs_task_ignore_definition $AWS_ECS_TASK_IGNORE_DEFINITION) aws_ecs_task_execution_role=$(generate_var aws_ecs_task_execution_role $AWS_ECS_TASK_EXECUTION_ROLE) aws_ecs_task_json_definition_file=$(generate_var aws_ecs_task_json_definition_file $AWS_ECS_TASK_JSON_DEFINITION_FILE) aws_ecs_task_network_mode=$(generate_var aws_ecs_task_network_mode $AWS_ECS_TASK_NETWORK_MODE) @@ -665,6 +666,7 @@ $aws_ecs_cluster_name $aws_ecs_service_launch_type $aws_ecs_task_type $aws_ecs_task_name +$aws_ecs_task_ignore_definition $aws_ecs_task_execution_role $aws_ecs_task_json_definition_file $aws_ecs_task_network_mode diff --git a/operations/deployment/terraform/aws/aws_variables.tf b/operations/deployment/terraform/aws/aws_variables.tf index 49c9541a..af39e0a1 100644 --- a/operations/deployment/terraform/aws/aws_variables.tf +++ b/operations/deployment/terraform/aws/aws_variables.tf @@ -1349,6 +1349,12 @@ variable "aws_ecs_task_name" { default = "" } +variable "aws_ecs_task_ignore_definition" { + type = bool + description = "Toggle ignoring changes to the task definition" + default = false +} + variable "aws_ecs_task_execution_role" { type = string description = "Elastic Container Service task execution role name." diff --git a/operations/deployment/terraform/aws/bitovi_main.tf b/operations/deployment/terraform/aws/bitovi_main.tf index 1c4a4ebb..5667207d 100644 --- a/operations/deployment/terraform/aws/bitovi_main.tf +++ b/operations/deployment/terraform/aws/bitovi_main.tf @@ -468,6 +468,7 @@ module "aws_ecs" { aws_ecs_service_launch_type = var.aws_ecs_service_launch_type aws_ecs_task_type = var.aws_ecs_task_type aws_ecs_task_name = var.aws_ecs_task_name + aws_ecs_task_ignore_definition = var.aws_ecs_task_ignore_definition aws_ecs_task_execution_role = var.aws_ecs_task_execution_role aws_ecs_task_json_definition_file = var.aws_ecs_task_json_definition_file aws_ecs_task_network_mode = var.aws_ecs_task_network_mode diff --git a/operations/deployment/terraform/modules/aws/ecs/aws_ecs.tf b/operations/deployment/terraform/modules/aws/ecs/aws_ecs.tf index d3a70518..4ea5ebf3 100644 --- a/operations/deployment/terraform/modules/aws/ecs/aws_ecs.tf +++ b/operations/deployment/terraform/modules/aws/ecs/aws_ecs.tf @@ -25,7 +25,7 @@ locals { } resource "aws_ecs_task_definition" "ecs_task" { - count = length(local.aws_ecs_app_image) + count = var.aws_ecs_task_ignore_definition ? 0 : length(local.aws_ecs_app_image) family = var.aws_ecs_task_name != "" ? local.aws_ecs_task_name[count.index] : "${local.aws_ecs_task_name[count.index]}${count.index}" network_mode = local.aws_ecs_task_network_mode[count.index] requires_compatibilities = [local.aws_ecs_task_type[count.index]] @@ -63,7 +63,7 @@ resource "aws_ecs_task_definition" "ecs_task" { } resource "aws_ecs_task_definition" "ecs_task_from_json" { - count = length(local.aws_ecs_task_json_definition_file) + count = var.aws_ecs_task_ignore_definition ? 0 : length(local.aws_ecs_task_json_definition_file) family = var.aws_ecs_task_name != "" ? local.aws_ecs_task_name[count.index + length(local.aws_ecs_app_image)] : "${local.aws_ecs_task_name[count.index + length(local.aws_ecs_app_image)]}${count.index+length(local.aws_ecs_app_image)}" network_mode = local.aws_ecs_task_network_mode[count.index + length(local.aws_ecs_app_image)] requires_compatibilities = ["${local.aws_ecs_task_type[count.index +length(local.aws_ecs_app_image)]}"] @@ -73,13 +73,63 @@ resource "aws_ecs_task_definition" "ecs_task_from_json" { container_definitions = sensitive(file("../../ansible/clone_repo/app/${var.app_repo_name}/${local.aws_ecs_task_json_definition_file[count.index]}")) } +resource "aws_ecs_task_definition" "aws_ecs_task_ignore_definition" { + count = var.aws_ecs_task_ignore_definition ? 1 : 0 + family = var.aws_ecs_task_name != "" ? local.aws_ecs_task_name[count.index] : "${local.aws_ecs_task_name[count.index]}${count.index}" + network_mode = local.aws_ecs_task_network_mode[count.index] + requires_compatibilities = [local.aws_ecs_task_type[count.index]] + cpu = local.aws_ecs_task_cpu[count.index] + memory = local.aws_ecs_task_mem[count.index] + execution_role_arn = local.ecsTaskExecutionRole + container_definitions = sensitive(jsonencode([ + { + "name": var.aws_ecs_task_name != "" ? local.aws_ecs_task_name[count.index] : "${local.aws_ecs_task_name[count.index]}${count.index}", + "image": "nginx:alpine", + "essential": true, + "portMappings": [ + { + "containerPort": 80, + "protocol": "tcp", + "hostPort": 80, + "appProtocol": "http" + } + ] + } + ])) + lifecycle { + ignore_changes = [container_definitions] + } +} + locals { - tasks_arns = concat(aws_ecs_task_definition.ecs_task[*].arn,aws_ecs_task_definition.ecs_task_from_json[*].arn) - tasks_count = length(local.aws_ecs_app_image) + length(local.aws_ecs_task_json_definition_file) + tasks_arns = concat(aws_ecs_task_definition.ecs_task[*].arn,aws_ecs_task_definition.ecs_task_from_json[*].arn,aws_ecs_task_definition.aws_ecs_task_ignore_definition[*].arn) + tasks_count = var.aws_ecs_task_ignore_definition ? 1 : length(local.aws_ecs_app_image) + length(local.aws_ecs_task_json_definition_file) } resource "aws_ecs_service" "ecs_service" { - count = local.tasks_count + count = var.aws_ecs_task_ignore_definition ? 0 : local.tasks_count + name = var.aws_ecs_service_name != "" ? "${var.aws_ecs_service_name}${count.index}" : "${var.aws_resource_identifier}-${count.index}-service" + cluster = aws_ecs_cluster.cluster.id + task_definition = local.tasks_arns[count.index] + + desired_count = local.aws_ecs_node_count[count.index] + launch_type = var.aws_ecs_service_launch_type + + network_configuration { + security_groups = [aws_security_group.ecs_sg.id] + subnets = var.aws_selected_subnets + assign_public_ip = var.aws_ecs_assign_public_ip + } + + load_balancer { + target_group_arn = aws_alb_target_group.lb_targets[count.index].id + container_name = var.aws_ecs_task_name != "" ? local.aws_ecs_task_name[count.index] : "${local.aws_ecs_task_name[count.index]}${count.index}" + container_port = local.aws_ecs_container_port[count.index] + } +} + +resource "aws_ecs_service" "ecs_service_ignore_definition" { + count = var.aws_ecs_task_ignore_definition ? 1 : 0 name = var.aws_ecs_service_name != "" ? "${var.aws_ecs_service_name}${count.index}" : "${var.aws_resource_identifier}-${count.index}-service" cluster = aws_ecs_cluster.cluster.id task_definition = local.tasks_arns[count.index] @@ -98,6 +148,10 @@ resource "aws_ecs_service" "ecs_service" { container_name = var.aws_ecs_task_name != "" ? local.aws_ecs_task_name[count.index] : "${local.aws_ecs_task_name[count.index]}${count.index}" container_port = local.aws_ecs_container_port[count.index] } + + lifecycle { + ignore_changes = [task_definition] + } } # Cloudwatch config diff --git a/operations/deployment/terraform/modules/aws/ecs/aws_ecs_networking.tf b/operations/deployment/terraform/modules/aws/ecs/aws_ecs_networking.tf index 3811f382..4b22bdd2 100644 --- a/operations/deployment/terraform/modules/aws/ecs/aws_ecs_networking.tf +++ b/operations/deployment/terraform/modules/aws/ecs/aws_ecs_networking.tf @@ -45,6 +45,11 @@ resource "aws_alb" "ecs_lb" { } } +data "aws_alb" "selected_lb" { + name = var.aws_resource_identifier_supershort + depends_on = [ aws_alb.ecs_lb ] +} + resource "aws_alb_target_group" "lb_targets" { count = length(local.aws_ecs_container_port) name = "${var.aws_resource_identifier_supershort}${count.index}" @@ -233,7 +238,8 @@ output "load_balancer_protocol" { } output "load_balancer_zone_id" { - value = aws_alb.ecs_lb.zone_id + #value = aws_alb.ecs_lb.zone_id + value = data.aws_alb.selected_lb.zone_id } output "load_balancer_arn" { diff --git a/operations/deployment/terraform/modules/aws/ecs/aws_ecs_vars.tf b/operations/deployment/terraform/modules/aws/ecs/aws_ecs_vars.tf index 15a907a9..e7dafbc3 100644 --- a/operations/deployment/terraform/modules/aws/ecs/aws_ecs_vars.tf +++ b/operations/deployment/terraform/modules/aws/ecs/aws_ecs_vars.tf @@ -3,6 +3,7 @@ variable "aws_ecs_cluster_name" {} variable "aws_ecs_service_launch_type" {} variable "aws_ecs_task_type" {} variable "aws_ecs_task_name" {} +variable "aws_ecs_task_ignore_definition" {} variable "aws_ecs_task_execution_role" {} variable "aws_ecs_task_json_definition_file" {} variable "aws_ecs_task_network_mode" {}