상세 컨텐츠

본문 제목

Terraform으로 EC2에 백엔드 서버 배포 (with ECR) 2장 ECR 모듈

DevOps/Terraform

by rakyun 2025. 8. 20. 11:59

본문

ECR

  • ecr은 registry로 docker image를 저장하고 관리하는 역할을 한다.
# 백엔드를 위한 ECR 리포지토리
# ECR은 AWS의 Docker 컨테이너 레지스트리 서비스입니다

resource "aws_ecr_repository" "backend" {
  # 리포지토리 이름 - 프로젝트명-backend-환경 형식
  name                 = "${var.project_name}-backend-${var.environment}"
  
  # 이미지 태그 변경 가능 여부 - MUTABLE: 같은 태그로 덮어쓰기 가능
  image_tag_mutability = "MUTABLE"

  # 이미지 스캔 설정 - 보안 취약점 자동 검사
  image_scanning_configuration {
    scan_on_push = true  # 이미지 푸시할 때마다 자동 스캔
  }

  # 암호화 설정
  encryption_configuration {
    encryption_type = "AES256"  # AES256 암호화 사용
  }

  # 리소스 태그
  tags = {
    Name        = "${var.project_name}-backend-${var.environment}"
    Environment = var.environment
    Project     = var.project_name
    ManagedBy   = "Terraform"
  }
}
  • ecr repository를 생성하는 terraform 코드이다.
  • image_scanning_configuration에 scaon_on_push = true로 설정해두면 ecr에서 이미지의 취약점을 검사하고 CI/CD 파이프라인에서 자동으로 보안 검사 단계를 통합할 수 있다.
  • 마지막 암호화 설정은 도커 이미지 파일을 암호화 하는 것
    • 누군가 AWS 데이터센터 스토리지에 접근하여도 이미지가 암호화 되어 있기에 원본 파일의 내용을 알아볼 수 없음
    • encryption_type = "AES256"  이렇게 설정해두면 AWS가 ecr에 올라가는 이미지를 자동으로 암호화  하고 pull 받을때는 자동으로 복호화 해준다.
# ECR 라이프사이클 정책 - 오래된 이미지 자동 삭제
# 스토리지 비용 절감을 위해 오래된 이미지를 자동으로 정리합니다
resource "aws_ecr_lifecycle_policy" "backend_policy" {
  repository = aws_ecr_repository.backend.name

  policy = jsonencode({
    rules = [
      {
        rulePriority = 1  # 규칙 우선순위 (낮은 숫자가 높은 우선순위)
        description  = "Remove untagged images after 7 days"
        selection = {
          tagStatus     = "untagged"         # 태그 없는 이미지만
          countType     = "sinceImagePushed"  # 푸시된 후 경과 시간 기준
          countUnit     = "days"              # 일 단위
          countNumber   = 7                   # 7일 후
        }
        action = {
          type = "expire"  # 삭제
        }
      },
      {
        rulePriority = 10  # tagStatus=any는 가장 낮은 우선순위 필요
        description  = "Keep only ${var.image_count_limit} recent images"
        selection = {
          tagStatus     = "any"                    # 태그 있는/없는 모든 이미지
          countType     = "imageCountMoreThan"     # 개수 기준
          countNumber   = var.image_count_limit    # 보관할 이미지 개수 (기본 10개)
        }
        action = {
          type = "expire"  # 만료(삭제) 액션
        }
      }
    ]
  })
}
  • ecr이 이미지를 관리하는 lifecycle을 정의해놓은 곳
  • rules 1 :  태그 없는 이미지 정리, untagged 즉 고아 이미지를 대상으로 하는 규칙
    • 푸시된 지 7일이 지나면 삭제
  • rules 2 : 태그와 상관없이 모든 이미지를 대상으로 함
    • 이미지를 보관하는 개수는 총 10개이며 10개 이상이 될 경우 가장 오래된 이미지부터 순서대로 삭제
# ECR 리포지토리 정책 - EC2 인스턴스가 이미지를 pull할 수 있도록 허용
resource "aws_ecr_repository_policy" "backend_policy" {
  repository = aws_ecr_repository.backend.name

  policy = jsonencode({
    Version = "2008-10-17"
    Statement = [
      {
        Sid    = "AllowPull"  # Statement ID
        Effect = "Allow"      # 허용
        Principal = {
          AWS = var.allowed_account_ids  # 허용할 AWS 계정 ID 목록
        }
        Action = [
          "ecr:GetDownloadUrlForLayer",       # 레이어 다운로드 URL 획득
          "ecr:BatchGetImage",                # 이미지 다운로드
          "ecr:BatchCheckLayerAvailability"   # 레이어 가용성 확인
        ]
      }
    ]
  })
}
  • ECR 리파지토리에 접근할 수 있는 권한을 정의하는 곳
  • 등록해놓은 AWS 계정만 ecr에서 이미지를 pull 받을 수 있음
  • Action ec2에서 ecr에 올라간 이미지를 pull 하기 위해서는 아래 3개의 권한이 필요하다.
    • ecr:GeDownloadUrlForLayer  -->  이미지의 각 구성 요소를 다운로드 할 수 있는 URL을 얻는 권한
    • ecr:BatchGetImage  -->  실제 이미지 메니페스트와 설정 정보를 가져오는 권한
    • ecr:BatchCheckLayerAvailability  -->  이미지를 pull하기 전에 필요한 레이어가 모두 존재하는지 확인하는 권한
iam과 security group에 대한 설명은 다음장에 있습니다!

관련글 더보기