AWS 콘솔을 이용해 EFS 생성하는 방법: [AWS] EFS 파일 시스템 생성
VPC
와 서브넷
, 인터넷 게이트웨이
, 라우팅 테이블
을 생성하고, 라우팅 테이블과 서브넷을 연결
, 네트워크 인터페이스와 서브넷을 연결
합니다.
# VPC 생성
resource "aws_vpc" "test_hyeob_vpc" {
cidr_block = "10.0.0.0/16"
instance_tenancy = "default"
# 인스턴스에 public DNS가 표시되도록 하는 속성
enable_dns_hostnames = true
enable_dns_support = true
tags = local.tags
}
# 서브넷 생성
resource "aws_subnet" "test_hyeob_subnet" {
vpc_id = aws_vpc.test_hyeob_vpc.id
cidr_block = "10.0.1.0/24"
availability_zone = "ap-northeast-2a"
tags = local.tags
}
# 인터넷 게이트웨이 생성 후 VPC에 연결
resource "aws_internet_gateway" "gw" {
vpc_id = aws_vpc.test_hyeob_vpc.id
tags = local.tags
}
# 라우팅 테이블 생성 후 igw에 연결
resource "aws_route_table" "rt" {
vpc_id = aws_vpc.test_hyeob_vpc.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.gw.id
}
tags = local.tags
}
# 서브넷과 라우팅 테이블 연결
resource "aws_route_table_association" "rta" {
subnet_id = aws_subnet.test_hyeob_subnet.id
route_table_id = aws_route_table.rt.id
}
# 네트워크 인터페이스를 서브넷에 연결
resource "aws_network_interface" "ni" {
subnet_id = aws_subnet.test_hyeob_subnet.id
private_ips = ["10.0.1.10"]
security_groups = [aws_security_group.test_hyeob_sg.id]
tags = local.tags
}
앞서 생성한 VPC와 연결될 보안 그룹을 총 2개
생성합니다. 하나는 인스턴스에 연결될 보안 그룹이고, 다른 하나는 탑재 대상에 연결될 보안 그룹입니다. 인스턴스에 연결될 보안 그룹
의 경우 SSH, HTTP 통신을 위해 22
, 80
번 인바운드 포트를 열어줍니다. 탑재 대상에 연결될 보안 그룹
에는 NFS 통신을 위해 2049
번 인바운드 포트를 열어줍니다.
# 인스턴스에 연결할 보안 그룹 생성
resource "aws_security_group" "test_hyeob_sg" {
name = "test_hyeob_sg"
description = "Allow SSH inbound traffic"
vpc_id = aws_vpc.test_hyeob_vpc.id
# 인바운드: ingress
ingress {
description = "SSH from VPC"
# 포트 범위: from_port ~ to_port
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
description = "HTTP"
# 포트 범위: from_port ~ to_port
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
# 아웃바운드: egress
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = local.tags
}
# EFS 탑재 대상에 연결할 보안 그룹을 생성
resource "aws_security_group" "efs_sg" {
name = "tf-test-hyeob-efs_sg"
description = "Allow SSH inbound traffic"
vpc_id = aws_vpc.test_hyeob_vpc.id
# 인바운드: ingress
ingress {
description = "SSH from VPC"
# 포트 범위: from_port ~ to_port
from_port = 2049
to_port = 2049
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
# 아웃바운드: egress
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = local.tags
}
EFS 파일 시스템을 생성합니다. 원존 클래스를 이용할 경우 별도로 availability_zone_name
속성을 이용해 특정 가용 영역 한 개를 지정합니다. encrypted
속성은 유휴 시 데이터 암호화와 관련된 속성입니다. 암호화를 활성화하고 싶다면 true
를 입력하시면 됩니다. 성능 모드(performance_mode
)와 처리량 모드(throughput_mode
)를 지정해주고, IA 스토리지를 사용하고 싶다면 수명 주기 관리(lifecycle_policy
)를 지정합니다.
# EFS 파일 시스템 생성
resource "aws_efs_file_system" "efs" {
# 원존 클래스를 이용할 경우
# availability_zone_name = "ap-northeast-2a"
# 유휴 시 데이터 암호화
encrypted = true
# KMS에서 관리형 키를 이용하려면 kms_key_id 속성을 붙여줍니다.
# 성능 모드: generalPurpose(범용 모드), maxIO(최대 IO 모드)
performance_mode = "generalPurpose"
# 버스팅 처리량 모드
throughput_mode = "bursting"
# 프로비저닝 처리량 모드
# throughput_mode = "provisioned"
# provisioned_throughput_in_mibps = 100
# 수명 주기 관리
lifecycle_policy {
transition_to_ia = "AFTER_30_DAYS"
}
}
탑재 대상을 수동으로 생성해줍니다. AWS 콘솔에서 작업하면 이러한 탑재 대상을 표준 클래스의 경우 모든 가용 영역에 자동으로 생성해주지만, 테라폼을 이용하게 되면 모두 수동으로 생성
해주어야 합니다. 탑재 대상에 2049
번 포트를 허용하는 보안 그룹을 연결
합니다.
# 표준 클래스로 EFS를 생성하더라도 탑재 대상은 모든 가용영역에 수동으로 지정해주어야 합니다.
resource "aws_efs_mount_target" "mount" {
file_system_id = aws_efs_file_system.efs.id
subnet_id = aws_subnet.test_hyeob_subnet.id
security_groups = [aws_security_group.efs_sg.id]
}
인스턴스를 생성합니다. 인스턴스는 의도적으로 의존성을 주어 탑재 대상(aws_efs_mount_target
) 리소스가 모두 생성 완료되면 인스턴스가 생성되도록 설정합니다(depends_on
). 앞서 생성한 네트워크 인터페이스를 붙여줍니다. 보안 그룹은 이전에 VPC 생성 단계에서 네트워크 인터페이스를 생성할 때 붙여주었으므로 인스턴스 생성 과정에서 중복으로 속성을 주어 연결할 필요가 없습니다. 네트워크 인터페이스를 연결하면 자동으로 보안 그룹과도 연결됩니다. user_data
를 이용해서 인스턴스 생성 후 마운트 폴더를 생성하고, EFS 파일 시스템을 마운트하는 작업까지 프로비저닝하도록 스크립트 내용을 작성하였습니다.
resource "aws_instance" "test_hyeob_instance" {
ami = data.aws_ami.amazon-linux-2.id
instance_type = "t2.micro"
network_interface {
network_interface_id = aws_network_interface.ni.id
device_index = 0
}
# network_interface를 인스턴스에 붙이지 않는다면 아래 속성으로 보안 그룹을 붙여줍니다.
# vpc_security_group_ids = [aws_security_group.test_hyeob_sg.id]
# 키 파일을 이용해 생성
key_name = aws_key_pair.kp.key_name
root_block_device {
volume_size = 30
volume_type = "gp3"
}
tags = local.tags
user_data = <<EOF
#!/bin/bash
sudo mkdir -p efs
sudo mount -t nfs4 -o nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport ${aws_efs_file_system.efs.dns_name}:/ efs
EOF
depends_on = [
aws_efs_mount_target.mount
]
}
# amazon linux 2 이미지 불러오기
data "aws_ami" "amazon-linux-2" {
most_recent = true
owners = ["amazon"]
filter {
name = "name"
values = ["amzn2-ami-hvm-*-x86_64-ebs"]
}
}
# 탄력적 IP 붙여주기
resource "aws_eip" "lb" {
instance = aws_instance.test_hyeob_instance.id
vpc = true
}
프라이빗 키를 생성(tls_private_key
)하고, 키 페어 파일을 생성(aws_key_pair
)해서 로컬에 다운로드까지 수행(local_file
)하는 코드입니다.
# RSA 알고리즘을 이용해 private 키 생성.
resource "tls_private_key" "pk" {
algorithm = "RSA"
rsa_bits = 4096
}
# private 키를 가지고 keypair 파일 생성.
resource "aws_key_pair" "kp" {
key_name = "test_hyeob_keypair"
public_key = tls_private_key.pk.public_key_openssh
}
# 키 파일을 생성하고 로컬에 다운로드.
resource "local_file" "ssh_key" {
filename = "${aws_key_pair.kp.key_name}.pem"
content = tls_private_key.pk.private_key_pem
}