ECS EC2사용

문학적인유사성·2023년 6월 30일
0

AWS

목록 보기
59/64
post-thumbnail

저번에 ecs fargate를 이용해서 생성해봤는데 다른 방식으로 한번 해보려고 한다.

이미지 생성

python을 이용해 간단하게 플라스크 도커 이미지 만들기
동일하게 저번처럼 이미지 만들어주고...

Dockerfile

[root@ip-10-1-8-104 ecs]# cat Dockerfile
vi Dockerfile
FROM python:3.9-slim
COPY . /app
RUN pip3 install flask
WORKDIR /app
CMD ["python3", "-m", "flask", "run", "--host=0.0.0.0"]

app.py

[root@ip-10-1-8-104 ecs]# cat app.py
from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello_yusa():
    return 'hello yusa!!!'

if __name__ == '__main__':
    app.run(debug=True)

도커 빌드후 ecr push

docker build -t yusapython:latest .
docker tag
docker push ${ECR repo}

ecs cluster 생성

launch template 생성

  1. 이름 넣기
  2. ecs-optimized ami 골라서 넣기
  • amzn-ami-2018.03.20230406-amazon-ecs-optimized, ami-0a94cc3e3653bd73c 사용
  1. 인스턴스 타입넣기
  2. key Pair 넣기 ( ec2에 접속해서 확인 할수 있어야함. )
  3. 세큐리티 그룹 넣기
  • http 80 허용
  1. IAM롤 ecsInastanceRole 넣기
  2. userdata 넣기
#!/bin/bash
cat <<'EOF' >> /etc/ecs/ecs.config
ECS_CLUSTER=${ecs 클러스터 이름}
ECS_LOGLEVEL=debug
ECS_ENABLE_TASK_IAM_ROLE=true
EOF

ASG 생성

  1. 이름넣기
  2. launch template 위에서 생성한 그대로 선택
  3. VPC, 서브넷 선택
  • private으로만 선택했음.
  1. No load balancer 선택

Loadbalancer 생성

  1. ALB 선택
  2. Internet-facing 선택
  3. VPC 선택
  4. SG 선택
  • http 80 허용
  1. Listener 추가
  • TG 생성시 IP로 선택하고, 아무것도 등록하지않는다.

ecs cluster 생성

  1. 이름 넣기 ( user data에 넣은 것과 동일한 이름을 넣어야함 )
  2. VPC 및 subnet 선택
  3. Infrastructure에 amazone ec2 instance 선택
  4. 기존에 생성한 ASG선택

ec2등록 확인

이렇게 ec2가 잘 등록이 되어있는지 확인 할 것

svc 생성

  1. capacity provider strategy에 custom 으로 선택해서 ec2만 넣어줬음.
  2. 서비스 생성은 fargate생성과 동일하게 적용
  3. networking 설정
  • vpc, subnet설정
  • task 세큐리티그룹을 넣어준다 custom TCP 5000 0.0.0.0/0 (for flask container)
  1. LB 설정
  • 위에서 생성한 LB, TG설정

결과

테라폼으로 구축하기

일단 리소스로 하드코딩하면서 필요한 내용 익혀두고, 모듈화 시작
IAM 일단 급하게 만들어서, IAM따로 코딩하거나, 모듈로 만들때는 넣어야겠따

locals {
  name   = "yusa-test-ecs"

  vpc_id     = data.terraform_remote_state.vpc.outputs.vpc_id
  pub_subnet = data.terraform_remote_state.vpc.outputs.public_subnets
  priv_subnet =  data.terraform_remote_state.vpc.outputs.private_subnets
  azs      = data.terraform_remote_state.vpc.outputs.azs
  app_count = 1
  container_name = "hello-yusa"
  container_port = 5000
  protect_from_scale_in = false

  tags = merge(
    data.aws_default_tags.aws_dt.tags,
    { Owner = "yusa" }
    )
}

# locals
data "aws_iam_role" "ecs_task_execution_role" {
  name = "ecsTaskExecutionRole"
}

resource "aws_security_group" "lb_sg" {
  name        = "ecs-test-yusa-alb-sg"
  vpc_id      = local.vpc_id

  ingress {
    protocol    = "tcp"
    from_port   = 80
    to_port     = 80
    cidr_blocks = ["0.0.0.0/0"]
  }

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

resource "aws_security_group" "ec2_sg" {
  name        = "ecs-test-yusa-ssh-sg"
  vpc_id      = local.vpc_id

  ingress {
    protocol    = "tcp"
    from_port   = 80
    to_port     = 80
    cidr_blocks = ["0.0.0.0/0"]
  }
  ingress {
    protocol    = "tcp"
    from_port   = 22
    to_port     = 22
    cidr_blocks = ["0.0.0.0/0"]
  }

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

resource "aws_lb" "default" {
  name            = "ecs-test-yusa-lb"
  subnets         = local.pub_subnet
  security_groups = [aws_security_group.lb_sg.id]
}

resource "aws_lb_target_group" "hello_yusa" {
  name        = "ecs-test-yusa-target-group"
  port        = 80
  protocol    = "HTTP"
  vpc_id      = local.vpc_id
  target_type = "ip"
}

resource "aws_lb_listener" "hello_yusa" {
  load_balancer_arn = aws_lb.default.id
  port              = "80"
  protocol          = "HTTP"

  default_action {
    target_group_arn = aws_lb_target_group.hello_yusa.id
    type             = "forward"
  }
}

resource "aws_launch_template" "ecs-test-ec2" {
  name_prefix   = "ecs-test-ec2"
  image_id      = "ami-0a94cc3e3653bd73c"
  instance_type = "t3.medium"
  vpc_security_group_ids = ["${aws_security_group.ec2_sg.id}"]
  iam_instance_profile {
    arn= "${ecsInstanceRole arn 넣기}"
  }
  user_data = filebase64("./user_data.sh")
}

resource "aws_autoscaling_group" "ecs-asg-group" {
  desired_capacity   = 1
  max_size           = 1
  min_size           = 1
  vpc_zone_identifier = local.priv_subnet

  launch_template {
    id      = aws_launch_template.ecs-test-ec2.id
    version = "$Latest"
  }
}

resource "aws_ecs_task_definition" "hello_yusa" {
  family                   = local.container_name
  network_mode             = "awsvpc"
  requires_compatibilities = ["EC2"]
  cpu                      = 1024
  memory                   = 2048
  execution_role_arn       = "${data.aws_iam_role.ecs_task_execution_role.arn}" # for Using ECR

  container_definitions = <<DEFINITION
[
  {
    "image": "{필요한 이미지 넣기}",
    "cpu": 1024,
    "memory": 2048,
    "name": "hello-yusa",
    "networkMode": "awsvpc",
    "portMappings": [
      {
        "containerPort": 5000,
        "hostPort": 5000
      }
    ]
  }
]
DEFINITION
}


resource "aws_security_group" "hello_yusa_task" {
  name        = "ecs-test-yusa-task-security-group" # for flask
  vpc_id      = local.vpc_id

  ingress {
    protocol        = "tcp"
    from_port       = 5000
    to_port         = 5000
    security_groups = [aws_security_group.lb_sg.id]
  }

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

resource "aws_ecs_cluster" "main" {
  name = local.name
}

resource "aws_ecs_cluster_capacity_providers" "example" {
  cluster_name = aws_ecs_cluster.main.name

  capacity_providers = [aws_ecs_capacity_provider.asg.name]

  default_capacity_provider_strategy {
    base              = 1
    weight            = 100
    capacity_provider = aws_ecs_capacity_provider.asg.name
  }
}

resource "aws_ecs_capacity_provider" "asg" {
  name = aws_autoscaling_group.ecs-asg-group.name

  auto_scaling_group_provider {
    auto_scaling_group_arn         = aws_autoscaling_group.ecs-asg-group.arn
    managed_termination_protection = local.protect_from_scale_in ? "ENABLED" : "DISABLED"

    managed_scaling {
      maximum_scaling_step_size = 1
      minimum_scaling_step_size = 1
      status                    = "ENABLED"
      target_capacity           = 1
    }
  }
}

resource "aws_ecs_service" "hello_yusa" {
  name            = "hello-yusa-service"
  cluster         = aws_ecs_cluster.main.id
  task_definition = aws_ecs_task_definition.hello_yusa.arn
  desired_count   = local.app_count
  launch_type     = "EC2"

  network_configuration {
    security_groups = [aws_security_group.hello_yusa_task.id]
    subnets         = local.priv_subnet
  }

  load_balancer {
    target_group_arn = aws_lb_target_group.hello_yusa.id
    container_name   = local.container_name
    container_port   = local.container_port
  }

  depends_on = [aws_lb_listener.hello_yusa]
}
profile
유사 IT 항해

0개의 댓글