Search code examples
amazon-web-servicesamazon-ec2terraformamazon-ecsecs-taskdefinition

Unable to register task to ec2-instance


I am unable to deploy the container inside ec2 instance, when I ssh into the instance I see no container and have no clue why this is happening. I am using execution_role_arn in the task main.tf but unable to deply wordpress container to ec2 instance, I am attaching the IAM roles that I have created for task execution and container service role for ec2. Everything else is working fine, task, service and cluster are created by the script but only the container is not deployed to the ec2 intance

Autoscaling:

resource "aws_launch_configuration" "ec2" {
  image_id             = var.image_id
  instance_type        = var.instance_type
  name                 = "ec2-${terraform.workspace}"
  user_data            = <<EOF
#!/bin/bash
echo 'ECS_CLUSTER=${var.cluster_name.name}' >> /etc/ecs/ecs.config
echo 'ECS_DISABLE_PRIVILEGED=true' >> /etc/ecs/ecs.config
EOF
  key_name             = var.key_name
  iam_instance_profile = var.instance_profile
  security_groups      = [aws_security_group.webserver.id]

}

resource "aws_autoscaling_group" "asg" {
  vpc_zone_identifier       = var.public_subnet
  desired_capacity          = 2
  max_size                  = 2
  min_size                  = 2
  health_check_grace_period = 300
  launch_configuration      = aws_launch_configuration.ec2.name
  target_group_arns         = [var.tg.arn]

}

resource "aws_security_group" "webserver" {
  name        = "webserver-${terraform.workspace}"
  description = "Allow internet traffic"
  vpc_id      = var.vpc_id

  ingress {
    description = "incoming for ec2-instance"
    from_port   = 0
    to_port     = 0
    protocol    = -1
    security_groups = [var.alb_sg]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
  tags = {
    Name = "webserver-sg"
  }

}
output "ec2_sg" {
  value = aws_security_group.webserver.id
}

Cluster:

resource "aws_ecs_cluster" "cluster" {
  name = "wordpress-${terraform.workspace}"
}
output "cluster" {
  value = aws_ecs_cluster.cluster.id
}
output "cluster1" {
  value = aws_ecs_cluster.cluster
}

Service:

resource "aws_ecs_service" "wordpress" {
  name                = "Wordpress-${terraform.workspace}"
  cluster             = var.cluster
  task_definition     = var.task.id
  desired_count       = 2
  scheduling_strategy = "REPLICA"

  load_balancer {
    target_group_arn = var.tg.arn
    container_name   = "wordpress"
    container_port   = 80
  }
  deployment_controller {
    type = "ECS"
  }
}

Task:


data "template_file" "init" {
  template = "${file("${path.module}/template/containerdef.json")}"
  vars = {
    rds_endpoint = "${var.rds_endpoint}"
    name         = "${var.name}"
    username     = "${var.username}"
    password     = "${var.password}"
  }
}
resource "aws_ecs_task_definition" "task" {
  family                   = "wordpress"
  container_definitions    = "${data.template_file.init.rendered}"
  network_mode             = "bridge"
  requires_compatibilities = ["EC2"]
  memory                   = "1GB"
  cpu                      = "1 vCPU"
  execution_role_arn            = var.task_execution.arn
}

Container definition.json

[
    {
        "name": "wordpress",
        "image": "wordpress:latest",
        "essential": true,
        "environment": [
            {
                "Name": "WORDPRESS_DB_HOST",
                "Value": "${rds_endpoint}"
            },
            {
                "Name": "WORDPRESS_DB_USER",
                "Value": "${username}"
            },
            {
                "Name": "WORDPRESS_DB_PASSWORD",
                "Value": "${password}"
            },
            {
                "Name": "WORDPRESS_DB_NAME",
                "Value": "${name}"
            }
        ],
        "portMappings": [
            {
                "containerPort": 80,
                "hostPort": 80
            }
        ]
    }
]

main.tf

data "aws_availability_zones" "azs" {}

data "aws_ssm_parameter" "name" {
  name = "Dbname"
}
data "aws_ssm_parameter" "password" {
  name = "db_password"
}

module "my_vpc" {
  source            = "./modules/vpc"
  vpc_cidr          = var.vpc_cidr
  public_subnet     = var.public_subnet
  private_subnet    = var.private_subnet
  availability_zone = data.aws_availability_zones.azs.names
}

module "db" {
  source            = "./modules/rds"
  ec2_sg            = "${module.autoscaling.ec2_sg}"
  allocated_storage = var.db_allocated_storage
  storage_type      = var.db_storage_type
  engine            = var.db_engine
  engine_version    = var.db_engine_version
  instance_class    = var.db_instance_class
  name              = data.aws_ssm_parameter.name.value
  username          = data.aws_ssm_parameter.name.value
  password          = data.aws_ssm_parameter.password.value
  vpc_id            = "${module.my_vpc.vpc_id}"
  public_subnet     = "${module.my_vpc.public_subnets_ids}"
}
module "alb" {
  source        = "./modules/alb"
  vpc_id        = "${module.my_vpc.vpc_id}"
  public_subnet = "${module.my_vpc.public_subnets_ids}"
}
module "task" {
  source         = "./modules/task"
  name           = data.aws_ssm_parameter.name.value
  username       = data.aws_ssm_parameter.name.value
  password       = data.aws_ssm_parameter.password.value
  rds_endpoint   = "${module.db.rds_endpoint}"
  task_execution = "${module.role.task_execution}"
}
module "autoscaling" {
  source = "./modules/autoscaling"
  vpc_id = "${module.my_vpc.vpc_id}"
  #public_subnet = "${module.my_vpc.public_subnets_ids}"
  tg               = "${module.alb.tg}"
  image_id         = var.image_id
  instance_type    = var.instance_type
  alb_sg           = "${module.alb.alb_sg}"
  public_subnet    = "${module.my_vpc.public_subnets_ids}"
  instance_profile = "${module.role.instance_profile}"
  key_name         = var.key_name
  cluster_name     = "${module.cluster.cluster1}"
}
module "role" {
  source = "./modules/Iam_role"
}
module "cluster" {
  source = "./modules/Ecs-cluster"
}
module "service" {
  source  = "./modules/services"
  cluster = "${module.cluster.cluster}"
  tg      = "${module.alb.tg}"
  task    = "${module.task.task}"
}

roles:

resource "aws_iam_role" "task_execution" {
  name = "task_execuution-${terraform.workspace}"

  assume_role_policy = <<EOF
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
              "Service": "ecs-tasks.amazonaws.com"
              },
            "Action": "sts:AssumeRole"            
        }
    ]
}
EOF

  tags = {
    tag-key = "tag-value"
  }
}
resource "aws_iam_role_policy_attachment" "ecs-task-permissions" {
  role       = aws_iam_role.task_execution.name
  policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"
}


resource "aws_iam_role_policy" "ecr-access" {

  name = "ecs-access-${terraform.workspace}"

  role = aws_iam_role.task_execution.name

  policy = <<EOF
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "2",
            "Effect": "Allow",
            "Action": [
                "ecr:BatchGetImage",
                "ecr:GetAuthorizationToken",
                "ecr:GetDownloadUrlForLayer"
            ],
            "Resource": "*"
        }
    ]
}
EOF

}

resource "aws_iam_role" "container_instance" {
  name               = "container_instance-${terraform.workspace}"
  assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Effect": "Allow"
    }
  ]
}
EOF

  tags = {
    tag-key = "tag-value"
  }

}
resource "aws_iam_instance_profile" "ec2_instance_role" {
  name = "iam_instance_profile-${terraform.workspace}"
  role = aws_iam_role.container_instance.name
}
resource "aws_iam_role_policy_attachment" "ec2_instance" {
  role       = aws_iam_role.container_instance.name
  policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role"
}
output "task_execution" {
  value = aws_iam_role.task_execution
}
output "instance_profile" {
  value = aws_iam_instance_profile.ec2_instance_role
}

Screenshot: enter image description here enter image description here


Solution

  • Based on the chat discussion.

    The issue was due to the fact that the instances used were t2.micro and the tasks were set to require 1GB of RAM. Since t2.micro has only 1GB of memory itself, it was not enough to run the tasks.

    The solution was to reduce the task RAM requirement to "0.5GB".