How do I pull the public IP address assigned to a container of an AWS ECS cluster/service?
For testing purposes I do not want to spin up an ALB, so I just added service to a public subnet. The best I was able to come up with so far is to use aws cli to pull the IP address. I am wondering if there's a way to pull this somehow using Terraform attributes.
resource "aws_ecs_cluster" "this" {
name = "${lower(var.app_name)}-${lower(var.app_environment)}-cluster"
}
resource "aws_ecs_task_definition" "this" {
family = "${lower(var.app_name)}-${lower(var.app_environment)}-task"
execution_role_arn = aws_iam_role.ecs_task_execution_role.arn
container_definitions = jsonencode([{
name = "${lower(var.app_name)}-${lower(var.app_environment)}-container"
image = "nginx:latest"
portMappings = [{ containerPort = 80 }]
}])
memory = 3072
cpu = 1024
requires_compatibilities = ["FARGATE"]
network_mode = "awsvpc"
runtime_platform {
operating_system_family = "LINUX"
cpu_architecture = "X86_64"
}
}
resource "aws_ecs_service" "this" {
name = "${lower(var.app_name)}-${lower(var.app_environment)}-service"
cluster = aws_ecs_cluster.this.id
task_definition = aws_ecs_task_definition.this.arn
desired_count = 1
# Assign an Elastic IP address to the task
network_configuration {
assign_public_ip = true
subnets = [module.vpc100.public_subnet1_id,module.vpc100.public_subnet2_id]
security_groups = [aws_security_group.this.id]
}
# Configure the service to use Fargate
launch_type = "FARGATE"
tags = {
Name = "${lower(var.app_name)}-${lower(var.app_environment)}-container"
}
}
# My hack to pull the public IP address
resource "terraform_data" "publicip" {
provisioner "local-exec" {
command = <<EOF
clustername=${lower(var.app_name)}-${lower(var.app_environment)}-cluster
taskid=$(aws ecs list-tasks --cluster $clustername --query "taskArns[0]" --output text)
eni=$(aws ecs describe-tasks --tasks $taskid --cluster example6-dev-cluster --query "tasks[0].attachments[0].details[?name=='networkInterfaceId'].value" --output text)
publicip=$(aws ec2 describe-network-interfaces --query "NetworkInterfaces[?NetworkInterfaceId=='$eni'].Association.PublicIp" --output text)
echo "$publicip"
EOF
}
depends_on = [
aws_ecs_service.this
]
}
You can't do that with Terraform. Terraform just knows that it told AWS to create a service. It doesn't know anything about any current tasks that are being managed by the service. You'll need to run something like an AWS CLI command after your terraform apply
is complete.