Terraform을 활용한 인프라 프로비저닝 기초

Chanmin, Kim·2022년 4월 27일
0

IAC

목록 보기
1/1

산학협력 R&D를 수행하는 회사에서 DR을 위한 AWS 기반 아키텍처를 구성하는 업무를 새로 맡게 되었는데요, 이번 기회에 IAC를 적극 활용해보고 싶었습니다.

인프라 설정을 위한 IAC 툴로 AWS CloudFormation과 테라폼(Terraform) 사이에서 고민하던 중, AWS 외에도 다양한 클라우드 벤더를 지원한다는 점에 매력을 느껴 최종적으로는 테라폼을 선택하게 되었습니다.

이번 글에서는 테라폼 기초 및 테라폼을 통해 AWS 리소스를 프로비저닝하는 방법을 정리합니다.

공급자 설정하기

IAC 구성을 위해 제일 먼저 사용할 서비스의 공급자(Provider)를 설정해줘야 하는데요, 사용하고자 하는 클라우드 서비스가 공급자 목록 에 있는지 확인해야 합니다.

AWS 공급자 문서를 따라 다음과 같이 .tf 확장자의 테라폼 코드를 작성합니다.

Terraform 0.13 버전을 전후로 공급자를 설정하는 코드가 업데이트되었습니다.
본 글에서는 공식 문서 를 기반으로 업데이트된 방법을 사용합니다.

// main.tf

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 3.0"
    }
  }
}

provider "aws" {
  region     = "ap-northeast-2"
  access_key = <AWS 계정 액세스 키>
  secret_key = <AWS 계정 시크릿 키>
}

공급자 설정을 마치면, terraform init 커맨드를 통해 사용할 프로바이더를 로컬에 등록하고 관련 플러그인을 설치합니다.

VSCode의 HashiCorp Terraform 익스텐션을 사용하면, 등록된 프로바이더가 제공하는 리소스들의 자동완성을 지원합니다.

리소스 생성 및 삭제하기

이제 AWS의 리소스를 사용할 것임을 테라폼에 알려줬으니 본격적으로 리소스를 생성할 차례입니다.

리소스(Ex. EC2 인스턴스, VPC 등)의 구체적인 설정 값은 리소스마다 다르지만 공통적으로는 아래 형식을 따릅니다.

resource "<공급자명>_<리소스명>" "<리소스 구분자>" {1: "값 1"2: "값 2"
  ...
}

이제 첫 번째 EC2 리소스를 생성해 볼 텐데요, "aws_instance" 라는 리소스를 사용하면 테라폼에서 인스턴스를 생성할 수 있습니다.

resource "aws_instance" "web-server" {
  ami           = "ami-0454bb2fefc7de534" // 우분투 20(x86)용 AMI ID
  instance_type = "t2.micro"
  
  // 태그
  tags = {
    "Name" = "Created_By_Terraform"
  }
}

ec2 리소스의 이름이 "aws_ec2" 라고 예상했을 수도 있는데요, 생각했던 것과 실제 이름("aws_instance")이 다른 경우가 잦으니 항상 공식 문서를 참고해야 합니다.

이제 terraform apply 를 입력한 후, EC2 콘솔에 들어가보면 테라폼에서 명시한 설정과 동일한 인스턴스가 생성된 것을 확인할 수 있습니다.

또한, 이렇게 생성한 리소스들은 terraform destroy 커맨드를 통해 안전하게 제거할 수도 있습니다.

리소스 수정하기

테라폼이 스크립트 언어와 다른 점이자 가장 큰 특징은, 테라폼 코드는 "구축하고자 하는 인프라의 최종 상태 (Desired State)" 를 의미하는 것이라는 점입니다.

즉 테라폼은 terraform apply 를 통해 주어진 코드를 실행할 때마다 인프라를 프로비저닝하는 것이 아니라, 코드와 실제 인프라(Ex. AWS)의 상태를 비교한 후 해당 상태를 최대한 구현합니다.

한번 지금까지 작성한 HCL 코드에서 태그만 바꾼 후, 다시 terraform apply 를 실행해 보겠습니다.

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 3.0"
    }
  }
}

# Configure the AWS Provider
provider "aws" {
  region     = "ap-northeast-2"
  access_key = "<IAM 액세스 키>"
  secret_key = "<IAM 시크릿 키>"
}



resource "aws_instance" "web-server" {
  ami           = "ami-0454bb2fefc7de534"
  instance_type = "t2.micro"
  tags = {
    // 태그명을 "Created_By_Terraform" 에서 "ubuntu-server" 로 변경합니다.
    "Name" = "ubuntu-server"
  }
}

커맨드를 입력한 후 조금 기다리면 AWS에 적용이 완료될 텐데요, 새로운 인스턴스가 생성되지 않고 이전에 생성한 인스턴스의 태그만 변경된 것을 확인할 수 있습니다.

리소스 참조하기

AWS 서비스 중에는 독립적으로 사용할 수 없고 꼭 다른 서비스와 함께 사용되어야 하는 것들이 있습니다.

예를 들면 반드시 VPC에 속해 있어야 하는 서브넷이나 EC2 인스턴스들을 타겟 그룹으로 하는 ELB가 있겠는데요, 이렇게 다른 리소스를 참조하는 방법도 존재합니다.

resource "공급자_리소스명 A" "리소스 식별자 A" {=}

resource "공급자_리소스명 B" "리소스 식별자 B" {
  // 리소스에서 다른 리소스를 참조하는 방법= <공급자_리소스명 A>.<리소스 식별자 A>.id
}

id 속성은 명시적으로 정의하지 않았더라도 테라폼으로 생성한 리소스라면 누구든 갖고 있는 속성인데요, 한번 다른 리소스를 참조하는 실제 예시를 살펴 보도록 하겠습니다.

  • Name = development 태그를 갖는 VPC를 생성하는 코드
resource "aws_vpc" "vpc-development" {
  cidr_block = "10.0.0.0/16"
  
  tags = {
    Name = "development"
  }
}
  • Name = "development" VPC에 속하는 서브넷을 생성하는 코드
resource "aws_subnet" "subnet-01" {
  vpc_id     = aws_vpc.vpc-development.id
  cidr_block = "10.0.1.0/24"

  tags = {
    Name = "subnet-01"
  }
}

VPC와 서브넷의 포함 관계 역시 테라폼으로 나타낼 수 있는 모습입니다!
이제 terraform apply 를 실행하면, VPC와 서브넷이 지정한 CIDR 범위를 갖고 생성된 모습입니다.

이 때, 서브넷을 생성하는 코드를 VPC를 생성하는 코드보다 위에 작성하더라도 테라폼은 똑똑하게 VPC를 먼저 생성한 다음 서브넷을 생성합니다.

profile
Public Cloud 및 Cloud Native 기술에 관심이 많습니다.

0개의 댓글