728x90

AWS의 Systems Manager (SSM)을 활용하면 프라이빗 서브넷에 위치한 EC2 인스턴스에 SSH 없이 안전하게 접근할 수 있습니다.
Terraform을 사용하여 프라이빗 EC2 서버를 프로비저닝하고, SSM을 통해 접근하는 방법을 단계별로 설명합니다.

1. AWS Systems Manager - Session Manager(SSM)

AWS Systems Manager (SSM)은 AWS 리소스 관리와 운영을 자동화하는 서비스로 Session Manager 는 EC2 인스턴스에 대한 안전하고 감사 가능한 접근환경을 제공합니다.

Session Manager 특징

  • SSH 키를 관리할 필요가 없습니다.
  • 인터넷 접근없이 프라이빗 환경으로 인스턴스 접근 가능
  • Bastion 호스트를 사용하지 않습니다.
  • 세션 활동의 로깅 및 감사 가능

Session Manager Prerequisites

  • 지원 운영체제 확인 (AWS Linux OS는 모두 기본 탑재되어 있음)
  • 인스턴스에서 작업 수행을 위한 권한 부여 (AWS Systems Manager는 기본적으로 인스턴스에서 작업을 수행할 권한이 없습니다.)
    • Session Manager에 대한 필수 권한 : AmazonSSMManagedInstanceCore
  • 엔드포인트에 대한 HTTPS(포트 443) 트래픽 허용 필요
    • ec2messages.region.amazonaws.com
    • ssm.region.amazonaws.com
    • ssmmessages.region.amazonaws.com

2. 아키텍처 구성도

다음은 SSM을 통해 EC2 인스턴스에 접근하기 위한 구성도 입니다.

2.1. VPC 및 서브넷 구성

프라이빗 서브넷을 포함한 VPC를 생성합니다.


# VPC 생성
resource "aws_vpc" "main" {
  cidr_block           = "10.0.0.0/16"
  enable_dns_hostnames = true
  enable_dns_support   = true

  tags = {
    Name = "VPC"
  }
}

# Subnet 생성
resource "aws_subnet" "main" {
  vpc_id            = aws_vpc.main.id
  cidr_block        = "10.0.1.0/24"
  availability_zone = "ap-northeast-2a"

  tags = {
    Name = "Subnet"
  }
}

# Route Table 생성
resource "aws_route_table" "main" {
  vpc_id = aws_vpc.main.id

  tags = {
    Name = "Route Table"
  }
}

# Route Table 연결
resource "aws_route_table_association" "main" {
  subnet_id      = aws_subnet.main.id
  route_table_id = aws_route_table.main.id
}

2.2. IAM 역할 및 정책 설정

SSM을 사용하기 위해 EC2 인스턴스에 연결할 IAM 역할과 정책(AmazonSSMManagedInstanceCore)을 설정합니다.


# IAM Role 생성
data "aws_iam_policy_document" "assume_role" {
  statement {
    effect = "Allow"

    principals {
      type        = "Service"
      identifiers = ["ec2.amazonaws.com"]
    }

    actions = ["sts:AssumeRole"]
  }

}

# EC2 역할 생성
resource "aws_iam_role" "ec2-role" {
  name               = "RoleForEC2"
  assume_role_policy = data.aws_iam_policy_document.assume_role.json
  description        = "Role for EC2 Instance"
}

# Manged Policy 연결(AmazonSSMManagedInstanceCore)
resource "aws_iam_role_policy_attachment" "AmazonSSMManagedInstanceCore" {
  policy_arn = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
  role       = aws_iam_role.ec2-role.name
}

# EC2 인스턴스 프로필 생성
resource "aws_iam_instance_profile" "ec2_instance_profile" {
  name = "ec2-instance-profile-for-ssm"
  role = aws_iam_role.ec2-role.name
}

2.3. Security Group 및 VPC Endpoint 설정

VPC EndPoint 연동을 위한 433 포트를 오픈하기 위한 보안그룹 설정과 VPC Endpoint를 생성합니다.


# EC2 Security Group 생성
resource "aws_security_group" "ec2_group" {
  name        = "ec2-SG"
  description = "Allow SSH inbound traffic and all outbound traffic"
  vpc_id      = aws_vpc.main.id

  tags = {
    Name = "EC2-SG"
  }
}

# 아웃바운드 트래픽 설정
resource "aws_vpc_security_group_egress_rule" "ec2_group" {
  security_group_id = aws_security_group.ec2_group.id
  cidr_ipv4         = "0.0.0.0/0"
  ip_protocol       = -1
}

# Endpoint Security Group 생성
resource "aws_security_group" "vpc_endpoint_group" {
  name        = "endpoint-SG"
  description = "Allow TLS inbound traffic and all outbound traffic"
  vpc_id      = aws_vpc.main.id

  tags = {
    Name = "VPC-Endpoint-SG"
  }

}

# 인바운드 트래픽 설정
resource "aws_vpc_security_group_ingress_rule" "vpc_endpoint" {
  security_group_id = aws_security_group.vpc_endpoint_group.id
  cidr_ipv4         = "0.0.0.0/0"
  from_port         = 443
  ip_protocol       = "tcp"
  to_port           = 443
  description       = "Allow Access SSL"
}

# 아웃바운드 트래픽 설정
resource "aws_vpc_security_group_egress_rule" "vpc_endpoint" {
  security_group_id = aws_security_group.vpc_endpoint_group.id
  cidr_ipv4         = "0.0.0.0/0"
  ip_protocol       = -1

}

# VPC Endpoint 생성
resource "aws_vpc_endpoint" "ssm_endpoint" {
  vpc_id              = aws_vpc.main.id
  service_name        = "com.amazonaws.${var.region}.ssm"
  vpc_endpoint_type   = "Interface"
  security_group_ids  = [aws_security_group.vpc_endpoint_group.id]
  subnet_ids          = [aws_subnet.main.id]
  private_dns_enabled = true

  tags = {
    Name = "SSM-Endpoint"

  }
}

resource "aws_vpc_endpoint" "ssmmessages_endpoint" {
  vpc_id              = aws_vpc.main.id
  service_name        = "com.amazonaws.${var.region}.ssmmessages"
  vpc_endpoint_type   = "Interface"
  security_group_ids  = [aws_security_group.vpc_endpoint_group.id]
  subnet_ids          = [aws_subnet.main.id]
  private_dns_enabled = true

  tags = {
    Name = "SSM-Messages-Endpoint"
  }
}

resource "aws_vpc_endpoint" "ec2messages_endpoint" {
  vpc_id              = aws_vpc.main.id
  service_name        = "com.amazonaws.${var.region}.ec2messages"
  vpc_endpoint_type   = "Interface"
  security_group_ids  = [aws_security_group.vpc_endpoint_group.id]
  subnet_ids          = [aws_subnet.main.id]
  private_dns_enabled = true

  tags = {
    Name = "EC2-Messages-Endpoint"
  }
}

2.4. EC2 인스턴스 생성

인터넷으로 접근되지 않도록 외부에 오픈 되어 있지 않는 보안그룹에 연결하고, 인스턴스를 생성합니다.

# EC2 인스턴스 생성
resource "aws_instance" "main" {
  ami           = "ami-04ea5b2d3c8ceccf8"
  instance_type = "t2.micro"
  subnet_id     = aws_subnet.main.id

  vpc_security_group_ids = [aws_security_group.ec2_group.id]

  iam_instance_profile = aws_iam_instance_profile.ec2_instance_profile.name

  tags = {
    Name = "EC2-Server"
  }
}

2.5. (결과) AWS SystemManager - Session Manager

프로비저닝 구성이 완료되면 AWS SystemManager > Session Manager 탭에서 생성 결과를 확인할 수 있습니다.

2.6. EC2에 접속하기

AWS Console과 CLI를 통해 접속할 수 있습니다.

AWS Management Console를 통한 접속

Console을 통해 SSM 세션을 접속합니다.

AWS CLI를 통한 접속

다음 명령어를 통해 SSM 세션을 시작합니다.

aws ssm start-session --target <instance-id>

2.7. 결과

AWS Systems Manager (SSM)과 Session Manager를 활용하여 프라이빗 EC2 서버를 프로비저닝하고, SSM을 통해 안전하게 접근하는 방법을 다루었습니다. 이를 통해 SSH 키 관리의 번거로움을 줄이고, 보안을 강화할 수 있습니다. SSM과 Session Manager를 사용하면 원격 명령 실행, 파일 전송 등 다양한 기능을 활용할 수 있으므로, 이를 적극적으로 활용해보시기 바랍니다.

Reference

728x90
반응형

+ Recent posts