Devops/Terraform
[테라폼] 테라폼(Terraform) 완전 정복: AWS 인프라를 Terraform으로 완전 자동화하기 - 1
일요일좋아하는사람
2025. 4. 19. 21:57
728x90
반응형
들어가며
AWS 인프라를 손으로 클릭해서 구성하던 시대는 끝났습니다. Terraform을 사용하면 VPC, IAM, EC2, S3, RDS, EKS, ECS, Fargate 등 모든 AWS 인프라 리소스를 코드 한 줄로 정의하고 배포할 수 있습니다.
이 글에서는 Terraform을 사용하여 AWS 인프라를 어떻게 구성할 수 있는지, 실제 코드 예제와 함께 상세히 안내합니다. 시작해볼까요?
목차
- Terraform이 AWS에서 하는 역할
- 프로젝트 구조 잡기
- VPC 생성
- IAM 사용자 및 역할 생성
- EC2 인스턴스 생성
- S3 버킷 생성
- RDS(MySQL) 생성
- EKS 클러스터 구성
- ECS + Fargate 구성
- Terraform 모듈과 공개 모듈 활용법
- 정리 및 추천 모듈
Terraform이 AWS에서 하는 역할
Terraform은 HashiCorp가 만든 오픈소스 도구로, AWS의 다양한 서비스를 코드로 자동화할 수 있게 해줍니다. 일반적으로 아래 리소스들을 자동으로 관리할 수 있습니다.
서비스 Terraform 리소스명
EC2 | aws_instance |
S3 | aws_s3_bucket |
VPC | aws_vpc |
Subnet | aws_subnet |
IAM | aws_iam_role, aws_iam_user 등 |
RDS | aws_db_instance |
EKS | aws_eks_cluster |
ECS | aws_ecs_cluster, aws_ecs_task_definition |
Lambda | aws_lambda_function |
Terraform은 공식 AWS provider 문서를 통해 상세히 정리되어 있으며, 지속적으로 업데이트됩니다.
프로젝트 구조 잡기
우선 Terraform 프로젝트 디렉토리를 아래와 같이 구성합니다.
aws-terraform-project/
├── main.tf
├── variables.tf
├── outputs.tf
├── provider.tf
├── terraform.tfvars
├── modules/
│ ├── vpc/
│ ├── ec2/
│ ├── iam/
│ ├── eks/
│ ├── rds/
│ └── ecs/
모듈을 쓰면 재사용성과 가독성이 좋아집니다. 하나씩 살펴봅시다.
VPC 생성
provider.tf
provider "aws" {
region = var.aws_region
}
variables.tf
variable "aws_region" {
default = "ap-northeast-2"
}
modules/vpc/main.tf
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
tags = {
Name = "terraform-vpc"
}
}
resource "aws_subnet" "public" {
count = 2
cidr_block = cidrsubnet("10.0.0.0/16", 8, count.index)
vpc_id = aws_vpc.main.id
availability_zone = element(data.aws_availability_zones.available.names, count.index)
map_public_ip_on_launch = true
tags = {
Name = "public-subnet-${count.index}"
}
}
data "aws_availability_zones" "available" {}
IAM 사용자 및 역할 생성
modules/iam/main.tf
resource "aws_iam_user" "admin" {
name = "terraform-admin"
}
resource "aws_iam_access_key" "admin_key" {
user = aws_iam_user.admin.name
}
resource "aws_iam_policy" "full_access" {
name = "TerraformFullAccess"
policy = data.aws_iam_policy_document.admin.json
}
data "aws_iam_policy_document" "admin" {
statement {
actions = ["*"]
resources = ["*"]
}
}
resource "aws_iam_user_policy_attachment" "attach" {
user = aws_iam_user.admin.name
policy_arn = aws_iam_policy.full_access.arn
}
EC2 인스턴스 생성
modules/ec2/main.tf
resource "aws_instance" "web" {
ami = var.ami_id
instance_type = "t3.micro"
subnet_id = var.subnet_id
associate_public_ip_address = true
tags = {
Name = "web-server"
}
}
variables.tf
variable "ami_id" {}
variable "subnet_id" {}
서울 리전에서 가장 많이 쓰이는 Ubuntu AMI는 ami-0c55b159cbfafe1f0입니다.
S3 버킷 생성
resource "aws_s3_bucket" "example" {
bucket = "my-terraform-s3-${random_id.rand.hex}"
acl = "private"
tags = {
Environment = "dev"
Terraform = "true"
}
}
resource "random_id" "rand" {
byte_length = 4
}
RDS(MySQL) 생성
resource "aws_db_instance" "mysql" {
allocated_storage = 20
engine = "mysql"
engine_version = "8.0"
instance_class = "db.t3.micro"
name = "mydb"
username = "admin"
password = var.db_password
parameter_group_name = "default.mysql8.0"
skip_final_snapshot = true
vpc_security_group_ids = [var.sg_id]
db_subnet_group_name = aws_db_subnet_group.db_subnet.name
}
resource "aws_db_subnet_group" "db_subnet" {
name = "mydb-subnet-group"
subnet_ids = var.subnet_ids
}
terraform.tfvars에 비밀번호 등을 넣습니다:
db_password = "strongpassword123"
EKS 클러스터 구성
공식 모듈 사용:
module "eks" {
source = "terraform-aws-modules/eks/aws"
cluster_name = "my-eks-cluster"
cluster_version = "1.28"
subnets = var.subnet_ids
vpc_id = var.vpc_id
eks_managed_node_groups = {
dev = {
desired_size = 2
max_size = 3
min_size = 1
instance_types = ["t3.medium"]
}
}
}
공식 모듈 문서: terraform-aws-modules/eks/aws
ECS + Fargate 구성
클러스터
resource "aws_ecs_cluster" "main" {
name = "fargate-cluster"
}
Task Definition
resource "aws_ecs_task_definition" "app" {
family = "fargate-task"
requires_compatibilities = ["FARGATE"]
network_mode = "awsvpc"
cpu = "256"
memory = "512"
execution_role_arn = var.execution_role_arn
container_definitions = jsonencode([
{
name = "my-app"
image = "nginx"
portMappings = [{ containerPort = 80, hostPort = 80 }]
}
])
}
서비스 생성
resource "aws_ecs_service" "app" {
name = "fargate-service"
cluster = aws_ecs_cluster.main.id
task_definition = aws_ecs_task_definition.app.arn
launch_type = "FARGATE"
network_configuration {
subnets = var.subnet_ids
security_groups = [var.sg_id]
assign_public_ip = true
}
}
Terraform 모듈과 공개 모듈 활용법
Terraform 공식 모듈은 모든 AWS 자원을 간편하게 구성할 수 있게 도와주는 템플릿입니다.
- terraform-aws-modules/vpc/aws
- terraform-aws-modules/ec2-instance/aws
- terraform-aws-modules/security-group/aws
예:
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "5.0.0"
name = "my-vpc"
cidr = "10.0.0.0/16"
azs = ["ap-northeast-2a", "ap-northeast-2c"]
public_subnets = ["10.0.1.0/24", "10.0.2.0/24"]
enable_nat_gateway = true
single_nat_gateway = true
}
정리 및 추천 모듈
Terraform으로 AWS 인프라를 완전히 자동화하는 데 필요한 요소들은 대부분 공식 모듈로 손쉽게 사용할 수 있습니다.
추천 모듈:
- VPC: terraform-aws-modules/vpc/aws
- EKS: terraform-aws-modules/eks/aws
- EC2: terraform-aws-modules/ec2-instance/aws
- Security Group: terraform-aws-modules/security-group/aws
- S3: 직접 구현 or community module
728x90
반응형