상세 컨텐츠

본문 제목

Terraform 기본 사용법

DevOps/Terraform

by rakyun 2025. 8. 20. 09:56

본문

이 글은 inflearn의 "처음 시작하는 Infrastructure as Code: AWS & 테라폼" 강의를 바탕으로 작성되었습니다!

IaC 란?

  • Infrastructure as Code의 줄임말로 코드로 인프라를 구축하는 것을 말한다.
  • 코드이기에 재사용성, 유지보수 등의 장점을 가진다.

Terraform 이란?

  • IaC를 구축하기 위한 도구
  • 현재 업계에서 가장 많이 쓰이는 IaC 도구

Terraform 구성요소

  • provider : 테라폼으로 생성할 인프라의 종류
  • resource : 테라폼으로 실제로 생성할 인프라 자원
  • state : 테라폼을 통해 생성한 자원의 상태
  • output : 테라폼으로 만든 자원을 변수 형태로 state에 저장하는 것
  • module : 공통적으로 활용할 수 있는 코드를 문자 그대로 모듈 형태로 정의하는 것
  • remote : 다른 경로의 state를 참조하는 것, output 변수를 불러올때 주로 사용

Terraform 기본 명령어

  • init : 테라폼 명령어 사용을 위해 각종 설정을 하는 명령어
  • plan : 테라폼으로 작성한 코드가 실제로 어떻게 만들어질지에 대한 예측 결과를 보는 명령어
  • apply : 테라폼 코드로 실제 인프라를 생성하는 명령어
  • import : 이미 만들어진 자원을 테라폼 state 파일로 옮겨주는 명령어
  • state : 테라폼 state를 다루는 명령어, 하위 명령어로 mv, push가 있음
  • destroy : 생성된 자원들 state 파일 모두 삭제하는 명령어

 

테라폼 명령어 프로세스는 다음과 같이 진행된다.

init   -->   plan   -->   apply

1. 작성한 코드에서 init 명령으로 내부적으로 설정 되어 있는 provider와 state, module 설정들을 진행한다.
2. 실제로 작성한 테라폼 코드가 어떻게 만들어질지에 대한 예측 결과를 본다. plan에 문제가 없어야 apply에 문제가 없을 확률이 높다.
     항상 plan 명령어를 습관화 해야 한다.
3. 실제로 작성한 코드로 명령어를 생성하는 명령어이다. 주의깊게 실행해야 함

Terraform으로 VPC 생성

aws vpc 란?

  • 아마존에서 제공하는 Private 네트워크 망 서비스
  • AWS 안에 나만의 가상 네트워크를 만드는 서비스
  • 서브넷
    • VPC의 IP 주소 범위
  • 라우팅 테이블
    • 네트워크 트래픽을 전달할 위치를 결정하는 데 사용되는 라우팅 규칙
  • 인터넷 게이트웨이
    • VPC의 리소스와 인터넷 간의 통신을 활성화하기 위해 VPC에 연결하는 게이트웨이
  • NAT 게이트웨이
    • 네트워크 주소 변환을 통해 프라이빗 서브넷에서 인터넷 또는 기타 AWS 서비스에 연결하는 게이트웨이
    • 라우팅 테이블에서 외부로 나가는 서비스가 인터넷 게이트웨이를 통하면 public 서브넷,
      NAT 게이트웨이를 통하면 private 서브넷 
  • 시큐리티 그룹
    • 보안 그룹은 인스턴스에 대한 인바운드 및 아웃바운드 트래픽을 제어하는 가상 방화벽 역할

terraform VPC 생성 Code

provider "aws" {
  region  = "ap-northeast-2"
}

resource "aws_vpc" "main" {
  cidr_block       = "10.0.0.0/16"

  tags = {
    Name = "terraform-101"
  }
}

resource "aws_subnet" "first_subnet" {
  vpc_id     = aws_vpc.main.id
  cidr_block = "10.0.1.0/24"

  availability_zone = "ap-northeast-2a"

  tags = {
    Name = "101subnet-1"
  }
}


resource "aws_subnet" "second_subnet" {
  vpc_id     = aws_vpc.main.id
  cidr_block = "10.0.2.0/24"

  availability_zone = "ap-northeast-2b"

  tags = {
    Name = "101subnet-2"
  }
}
  • 항상 provider로 생성할 인프라의 종류를 정의해줘야 한다. 
  • resource로 vpc를 생성하고 cidr을 설정한다.
  • vpc에서 사용할 subnet을 정의한다. 이렇게만 해놓으면 기본 라우팅 테이블에 연결 되게 된다.
    • 기본 라우팅 테이블은 gateway가 따로 설정되어 있지 않으므로 private이든, public이든 그냥 모두 닫혀있는 상태가 된다.

terraform으로 iam role, policy 생성

특정 역할(EC2, Lambda, ECS 등 실행 주체)이 AWS 리소스에 어떤 행동을 할 수 있는지를 정의한 권한 규칙
iam role은 권한을 주는 역할을 하고 policy는 권한에 대한 구체적인 내용이 들어간다.

 

role 생성

resource "aws_iam_role" "hello" {
    name = "hello-iam-role"
    path = "/"
    assume_role_policy = <<EOF
    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Sid": "",
                "Effect": "Allow",
                "Principal": {
                    "Service": "ec2.amazonaws.com"

                },
                "Action": "sts:AssumeRole"
            }
        ]
    }
    EOF
}
  • name = "hello-iam-role"
    계정 내에서 유일한 역할 이름 (최대 64자, 계정 단위 고유)
  • path = "/"
    역할의 “폴더” 개념. 기본이 /이고 조직적으로 /outsourcing/ 같은 경로를 쓸 수 있음. 경로 기준으로 권한 정책을 제한할 때 유용.
  • assume_role_policy (신뢰 정책, Trust Policy)
    누가 이 역할을 맡을 수 있는지(assume)”를 정의. 여기선:
    • Principal.Service = "ec2.amazonaws.com" → EC2 서비스만 이 역할을 맡을 수 있음
    • Action = "sts:AssumeRole" → STS를 통해 Role Assume 허용
    • Effect = "Allow" → 허용
    • Version = "2012-10-17" → IAM 정책 문법 버전(항상 이 값 사용)

핵심: 신뢰 정책(assume_role_policy)은 “주체(누가 맡나)”를 정의하고,
권한 정책(permissions policy)은 “권한(뭘 할 수 있나)”을 정의한다.
지금 리소스는 누가 맡나만 정의했기 때문에, 권한 정책을 추가로 붙여야 실제로 무언가를 할 수 있다.


policy

resource "aws_iam_role_policy" "hello_s3" {
  name   = "hello-s3-download"
  role   = aws_iam_role.hello.id
  policy = <<EOF
{
  "Statement": [
    {
      "Sid": "AllowAppArtifactsReadAccess",
      "Action": [
        "s3:*"
      ],
      "Resource": [
        "*"
      ],
      "Effect": "Allow"
    }
  ]
}
EOF

}

 

  • hello-iam-role 역할에 인라인(Inline) 정책을 붙여서 S3에 대한 권한을 부여.
  • 현재 JSON은 S3의 모든 액션(s3:*)을 모든 리소스(*)에 허용

인스턴스화

resource "aws_iam_instance_profile" "hello" {
  name = "hello-profile"
  role = aws_iam_role.hello.name
}
  • 만들어진 권한을 인스턴스화 해야지 나중에 ec2에서 가져다 사용이 가능하다.

terraform variable

테라폼이 사용하는 값들을 변수로 만들어서 유지 보수가 쉽게 만들어준다. 구조가 같은 두 개의 아키텍쳐라면 구조는 그대로 두고 안의 변수만 tfvars 파일의 값을 바꾸면서 사용이 가능하다.
variables.tf

variable "iam_user_list" {
  type = list(string)
}
  • 먼저 위와 같이 변수의 타입을 정의해준다.
terraform.tfvars

iam_user_list = ["test"]
  • 그리고 변수에 값을 넣어주고
resource "aws_iam_group" "devops_group" {
    name = "devops"

}

resource "aws_iam_group_membership" "devops" {
  name = aws_iam_group.devops_group.name

  users = var.iam_user_list

  group = aws_iam_group.devops_group.name
}
  • var.iam_user_lilst 처럼 variable에서 값을 가져온다고 명시해서 변수에 넣어주면 된다.

관련글 더보기