상세 컨텐츠

본문 제목

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

DevOps/Terraform

by rakyun 2025. 8. 23. 19:43

본문

IAM

# EC2 인스턴스가 ECR과 CloudWatch에 접근할 수 있도록 하는 IAM 역할
# IAM 역할을 통해 EC2는 AWS 서비스에 안전하게 접근할 수 있습니다

# EC2용 IAM 역할 생성
resource "aws_iam_role" "ec2_role" {
  # 역할 이름 - 프로젝트명-환경-ec2-role 형식
  name = "${var.project_name}-${var.environment}-ec2-role"

  # AssumeRole 정책 - EC2 서비스가 이 역할을 사용할 수 있도록 허용
  # EC2 인스턴스가 이 역할을 "assume"(가정)할 수 있게 해줍니다
  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = "sts:AssumeRole"      # AssumeRole 액션 허용
        Effect = "Allow"                # 허용
        Principal = {
          Service = "ec2.amazonaws.com" # EC2 서비스만 이 역할 사용 가능
        }
      }
    ]
  })

  # 리소스 태그
  tags = {
    Name        = "${var.project_name}-${var.environment}-ec2-role"
    Environment = var.environment
    Project     = var.project_name
    ManagedBy   = "Terraform"
  }
}
  • ec2에 iam role을 설정 (role)
  • assume_role_policy 
    • 이 IAM 역할을 누가 사용할 것인지 정의하는 부분
    • 이 iam role을 ec2가 사용할 수 있도록 정의함

# ECR 접근 권한 정책 연결
# EC2가 ECR에서 Docker 이미지를 pull할 수 있도록 하는 권한
resource "aws_iam_role_policy" "ecr_policy" {
  name = "${var.project_name}-${var.environment}-ecr-policy"
  role = aws_iam_role.ec2_role.id  # 위에서 생성한 역할에 연결

  # ECR 접근 권한 정책
  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Effect = "Allow"
        Action = [
          "ecr:GetAuthorizationToken",        # ECR 로그인 토큰 발급
          "ecr:BatchCheckLayerAvailability",  # 레이어 가용성 확인
          "ecr:GetDownloadUrlForLayer",       # 레이어 다운로드 URL 획득
          "ecr:BatchGetImage",                # 이미지 다운로드
          "ecr:ListImages",                   # 이미지 목록 조회
          "ecr:DescribeImages",               # 이미지 상세 정보 조회
          "ecr:DescribeRepositories"          # 리포지토리 정보 조회
        ]
        Resource = "*"  # 모든 ECR 리포지토리 (필요시 특정 리포지토리로 제한 가능)
      }
    ]
  })
}
  • ecr에 접근할 수 있는 권한 (policy)
  • ecr에 이미지를 올리고 다운 받고 이미지의 상세 정보를 조회하는 등 ecr에 접근할 수 있는 권한을 준다.
  • Resource를 *로 두면 모든 ecr 레포에서 가져올 수 있고 특정 ecr의 이름을 정해 그 ecr에 대한 권한만 주는 것도 가능하다.

# SSM (Systems Manager) 정책 연결 (선택사항)
# Session Manager를 통한 브라우저 기반 SSH 접속 가능
resource "aws_iam_role_policy_attachment" "ssm_policy" {
  count      = var.enable_ssm ? 1 : 0  # enable_ssm이 true일 때만 생성
  role       = aws_iam_role.ec2_role.name
  policy_arn = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"  # AWS 관리형 정책
}

# EC2 인스턴스 프로파일 생성
# EC2 인스턴스가 IAM 역할을 사용할 수 있도록 하는 프로파일
resource "aws_iam_instance_profile" "ec2_profile" {
  name = "${var.project_name}-${var.environment}-ec2-profile"
  role = aws_iam_role.ec2_role.name  # IAM 역할 연결

  tags = {
    Name        = "${var.project_name}-${var.environment}-ec2-profile"
    Environment = var.environment
    Project     = var.project_name
    ManagedBy   = "Terraform"
  }
}
  • aws_iam_role_policy_attachment
    • iam 역할에 정책을 붙이는 리소스
  • aws_iam_instance_profile 
    • 인스턴스 프로파일을 만드는 리소스
    • EC2는 역할을 직접 가질 수 없으므로 프로파일이라는 포장지를 통해 받을 수 있음

SSM Session Manager

AWS의 인프라를 확인하고 제어하며 자동화할 수 있는 통합 관리 서비스
  • 보안 강화: 기존의 SSH 방식처럼 EC2 인스턴스의 22번 포트를 외부에 열어둘 필요가 없음 인터넷에 노출되는 지점이 사라져 보안이 크게 향상
  • 접근 관리 용이: SSH 키 파일을 개별적으로 관리하고 배포할 필요 없이, 오직 IAM 권한만으로 인스턴스 접근을 제어 가능
  • 감사 및 로깅: 모든 접속 세션에 대한 로그를 기록할 수 있어 누가, 언제, 어떤 명령어를 실행했는지 추적하기 쉬움
  • 편리함: AWS 웹 콘솔(브라우저)에서 클릭 몇 번으로 바로 인스턴스의 터미널에 접속 가능

원래는 ec2 인스턴스의 22번 포트를 열어놓고 pem키를 만든다음 아래의 명령어를 쳐서 들어가야 했다.

ssh -i {pem키 경로} {사용자명@public ip 주소}

 

이는 보안에 큰 문제가 생긴다. 해커들의 ssh brute force 공격(ec2에 무작위로 팸키를 대입해보는 공격)을 당할 수 있기 때문이다.

그런데 ssm을 사용하면 22번 포트를 막아놓고 ssm을 통해 ec2에 접근하므로 brute force 공격에 노출되지 않는다.

관련글 더보기