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
- Session Manager에 대한 필수 권한 :
- 엔드포인트에 대한 HTTPS(포트 443) 트래픽 허용 필요
- ec2messages.
region
.amazonaws.com - ssm.
region
.amazonaws.com - ssmmessages.
region
.amazonaws.com
- ec2messages.
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
'Language > Terraform' 카테고리의 다른 글
(Terraform) AWS SES(Simple Email Service) 도메인 인증 프로비저닝 (0) | 2024.09.19 |
---|---|
(Terraform) Backend 구현(S3, DynamoDB) (0) | 2024.04.04 |