기록

AWS 프리티어로 ECS on EC2 구성하기 (CloudFormation 기반 자동화) 본문

DevOps

AWS 프리티어로 ECS on EC2 구성하기 (CloudFormation 기반 자동화)

zyin 2025. 4. 1. 00:00

프리티어는 t2.micro 인스턴스 한 대를 무료로 제공해 주기 때문에, 간단한 서비스나 테스트 용도로 사용하기에 꽤 유용하다. 하지만 단점도 있다. 계정마다 리소스 한도가 제한되어 있기 때문에, 여러 개의 계정을 운영하거나 계정 간에 인프라를 동일하게 구성해야 할 일이 자주 생긴다.
이럴 때 매번 콘솔을 통해 수동으로 VPC를 만들고, 서브넷과 라우팅 테이블, EC2 인스턴스를 구성하는 일은 번거롭고 시간이 많이 든다.
그래서 이를 코드화해두면 여러 계정에서도 복사-붙여넣기만으로 동일한 인프라를 쉽게 구축할 수 있다. 이번 글에서는 AWS CloudFormation 템플릿을 통해 프리티어 기반의 ECS(EC2 LaunchType) 인프라를 구성하는 과정을 소개한다.

1. 네트워크 구성 - VPC, 퍼블릭 서브넷, 인터넷 연결

AWS에서 인프라를 구성할 때는 항상 네트워크부터 시작하게 된다.
아래 코드는 단일 VPC와 퍼블릭 서브넷을 정의하고, EC2 인스턴스가 외부와 통신할 수 있도록 인터넷 게이트웨이(IGW)와 라우팅 테이블을 연결하는 부분이다.

VPC:
  Type: AWS::EC2::VPC
  Properties:
    CidrBlock: 10.0.0.0/16
    EnableDnsSupport: true
    EnableDnsHostnames: true

PublicSubnet:
  Type: AWS::EC2::Subnet
  Properties:
    VpcId: !Ref VPC
    CidrBlock: 10.0.1.0/24
    MapPublicIpOnLaunch: true
    AvailabilityZone: ap-northeast-2a

 

이 구성은 서울 리전의 가용영역 ap-northeast-2a를 기준으로 퍼블릭 서브넷 하나만 생성하며, MapPublicIpOnLaunch: true 옵션을 통해 EC2 인스턴스가 퍼블릭 IP를 자동으로 받도록 설정한다.

InternetGateway:
  Type: AWS::EC2::InternetGateway

AttachGateway:
  Type: AWS::EC2::VPCGatewayAttachment
  Properties:
    VpcId: !Ref VPC
    InternetGatewayId: !Ref InternetGateway

PublicRouteTable:
  Type: AWS::EC2::RouteTable
  Properties:
    VpcId: !Ref VPC

PublicRoute:
  Type: AWS::EC2::Route
  DependsOn: AttachGateway
  Properties:
    RouteTableId: !Ref PublicRouteTable
    DestinationCidrBlock: 0.0.0.0/0
    GatewayId: !Ref InternetGateway

PublicSubnetRouteTableAssociation:
  Type: AWS::EC2::SubnetRouteTableAssociation
  Properties:
    SubnetId: !Ref PublicSubnet
    RouteTableId: !Ref PublicRouteTable

 

인터넷 게이트웨이와 퍼블릭 서브넷을 라우팅 테이블로 연결해, 해당 서브넷의 EC2 인스턴스가 외부 인터넷과 통신할 수 있게 만든다.


2. 보안 그룹 설정

이제 네트워크 위에 EC2를 띄우려면, 인바운드 트래픽을 허용할 보안 그룹이 필요하다.
SSH(22번 포트)와 HTTP(80번 포트)를 열어 EC2에 접속하고 웹 서버를 운영할 수 있게 한다.

EC2SecurityGroup:
  Type: AWS::EC2::SecurityGroup
  Properties:
    GroupDescription: ECS EC2 SG
    VpcId: !Ref VPC
    SecurityGroupIngress:
      - IpProtocol: tcp
        FromPort: 22
        ToPort: 22
        CidrIp: 0.0.0.0/0
      - IpProtocol: tcp
        FromPort: 80
        ToPort: 80
        CidrIp: 0.0.0.0/0

 

보안상 운영 환경에서는 CidrIp를 특정 IP 대역으로 제한해야 하지만, 테스트나 학습 목적에서는 전체 오픈으로 두기도 한다.


3. IAM 역할 및 ECS 클러스터 구성

ECS에서 EC2 인스턴스를 사용할 경우, 해당 인스턴스가 ECS 클러스터에 자동으로 등록되기 위해 적절한 IAM Role이 필요하다.
또한, SSM으로 원격 접속할 수 있도록 권한도 추가한다.

ECSInstanceRole:
  Type: AWS::IAM::Role
  Properties:
    AssumeRolePolicyDocument:
      Version: "2012-10-17"
      Statement:
        - Effect: Allow
          Principal:
            Service: ec2.amazonaws.com
          Action: sts:AssumeRole
    ManagedPolicyArns:
      - arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role
      - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore

ECSInstanceProfile:
  Type: AWS::IAM::InstanceProfile
  Properties:
    Roles:
      - !Ref ECSInstanceRole

 

이 IAM 역할은 Launch Template과 연결되어, 인스턴스가 부팅 시 ECS Agent를 통해 클러스터에 등록되도록 한다.

ECSCluster:
  Type: AWS::ECS::Cluster

 

단순히 ECS 클러스터를 하나 생성하는 리소스다. 이후에 TaskDefinition을 등록하고 Service를 붙이면, 이 클러스터를 통해 컨테이너가 실행된다.


4. Launch Template 및 EC2 Auto Scaling Group 구성

EC2 인스턴스를 직접 만들지 않고, Launch Template을 통해 EC2 설정을 정의한 후 Auto Scaling Group으로 1대를 유지하는 구조로 만든다.

ECSLaunchTemplate:
  Type: AWS::EC2::LaunchTemplate
  Properties:
    LaunchTemplateName: ecs-launch-template
    LaunchTemplateData:
      InstanceType: t2.micro
      ImageId:
        Fn::Sub: '{{resolve:ssm:/aws/service/ecs/optimized-ami/amazon-linux-2/recommended/image_id}}'
      IamInstanceProfile:
        Name: !Ref ECSInstanceProfile
      NetworkInterfaces:
        - AssociatePublicIpAddress: true
          DeviceIndex: 0
          Groups:
            - !Ref EC2SecurityGroup
      UserData:
        Fn::Base64: !Sub |
          #!/bin/bash
          echo ECS_CLUSTER=${ECSCluster} >> /etc/ecs/ecs.config
  • t2.micro는 프리티어 조건을 만족하는 인스턴스 타입이다.
  • ImageId는 하드코딩하지 않고 SSM Parameter Store에서 ECS 최적화 Amazon Linux 2 AMI를 가져온다.
  • UserData에는 ECS 클러스터 이름을 설정해 클러스터에 자동 등록되도록 한다.
ECSAutoScalingGroup:
  Type: AWS::AutoScaling::AutoScalingGroup
  Properties:
    VPCZoneIdentifier:
      - !Ref PublicSubnet
    LaunchTemplate:
      LaunchTemplateId: !Ref ECSLaunchTemplate
      Version: !GetAtt ECSLaunchTemplate.LatestVersionNumber
    MinSize: '1'
    MaxSize: '1'
    DesiredCapacity: '1'

 

Auto Scaling Group은 인스턴스를 항상 1대 유지하도록 설정되어 있다. 이후 블루/그린 배포를 구현할 때는 DesiredCapacity를 2로 잠깐 늘렸다가, 교체 후 1로 줄이는 식으로 구성할 수 있다.

 

Comments