Devops/Terraform

[테라폼] 테라폼(Terraform) 완전 정복: AWS 인프라를 Terraform으로 완전 자동화하기 - 1

일요일좋아하는사람 2025. 4. 19. 21:57
728x90
반응형

Terraform + aws

들어가며

AWS 인프라를 손으로 클릭해서 구성하던 시대는 끝났습니다. Terraform을 사용하면 VPC, IAM, EC2, S3, RDS, EKS, ECS, Fargate 등 모든 AWS 인프라 리소스를 코드 한 줄로 정의하고 배포할 수 있습니다.

이 글에서는 Terraform을 사용하여 AWS 인프라를 어떻게 구성할 수 있는지, 실제 코드 예제와 함께 상세히 안내합니다. 시작해볼까요?


목차

  1. Terraform이 AWS에서 하는 역할
  2. 프로젝트 구조 잡기
  3. VPC 생성
  4. IAM 사용자 및 역할 생성
  5. EC2 인스턴스 생성
  6. S3 버킷 생성
  7. RDS(MySQL) 생성
  8. EKS 클러스터 구성
  9. ECS + Fargate 구성
  10. Terraform 모듈과 공개 모듈 활용법
  11. 정리 및 추천 모듈

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 자원을 간편하게 구성할 수 있게 도와주는 템플릿입니다.

예:

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
반응형