오늘의 인기 글
최근 글
최근 댓글
Today
Total
11-24 10:55
관리 메뉴

우노

[Terraform] Terraform 구성 요소 본문

DevOps/Terraform

[Terraform] Terraform 구성 요소

운호(Noah) 2023. 1. 6. 14:09

Terraform이란?

  • 테라폼(Terraform)은 코드로 인프라를 관리하는 IaC(Infrastructure as Code)도구입니다.
    • IaC는 작성용이성, 재사용성, 유지보수 등의 장점을 가집니다.
  • 하시코프(HashiCorp)가 제공하는 프로젝트 중 하나이며, AWS, Azure, GCP 같은 다양한 서비스들을 지원합니다.
    • 하시코프는 인프라스트럭처와 관련된 다양한 오픈소스 프로젝트를 운영하는 회사입니다.
    • 대표적으로, 개발 환경을 관리하는 Vagrant, 서비스 디스커버리 도구 Consul, 비밀 정보 관리 도구 Vault와 같은 프로젝트들이 있습니다.
  • 테라폼은 HCL이라는 언어로 .tf 파일에 인프라스트럭쳐를 선언적으로 작성합니다.

주요 구성 요소

  • provider
  • resource
  • state
  • locals
  • variable
  • output
  • data
  • module

provider

  • 테라폼으로 생성할 인프라의 종류를 의미합니다.

  • 일반적으로 provider.tf 파일에 정의합니다.

      provider "aws" {
    
        region = "ap-northeast-2"
        version = "~> 3.0"
    
      }

resource

  • 테라폼으로 생성할 실제 인프라 자원을 의미합니다.

  • 일반적으로 main.tf 파일에 정의합니다.

      # 테라폼으로 AWS의 VPC를 생성하는 코드입니다.
      # resource "리소스의 이름", "생성명"
      resource "aws_vpc" "example" {
    
        cidr_block = "10.0.0.0/16"
    
      }

state

  • 테라폼 명령어를 실행한 결과값을 의미합니다.

    • 현재 인프라의 상태는 아닙니다.
  • terraform.tfstate 파일에 정의됩니다.

    • 현재 인프라의 상태와 tfstate 파일의 내용을 동일하게 유지하는게 중요합니다.
    • 일반적으로 테라폼 작업은 여러 사람들이 진행하므로, state 파일은 원격 저장소에 저장하며, 이를 backend라고 합니다.
  • .tfstate 파일 내부는 아래와 같이 구성되어 있습니다.

      {
              "version" : 4,
              "terraform_version" : "0.12.24",
              "serial" : 3,
              "lineage" : "3c77XXXX-2de4-7736-1447-038974a3c187",
              "outputs" : {},
              "resources" : [
                {...},
                {...}
                      ]
      }
  • 아래 명령어를 통해, 현재 state 파일이 가지고 있는 리소스 정보들을 확인할 수도 있습니다.

    • terraform state list

locals

  • locals 변수는, 현재 실행 파일에서 사용되는 지역 변수를 의미합니다.

  • 보통 locals.tf 파일에 정의됩니다.

  • 보안 문제가 없는 변수들을 공통적인 네이밍 규칙을 통해 정의할 때 사용합니다.

  • 정의 방법

      locals {
        date        = "2021.01.09"
        common_tags = {
          group   = "developer"
          created = local.date
        }
      }
  • 사용 방법

      resource "aws_iam_user" "example1" {
        name = "test1"
        tags = local.common_tags
      }

variable

  • 모듈에서 사용할 변수를 정의할 때 사용됩니다. (입력 변수)

  • 보통 variables.tf 파일에 정의됩니다.

  • 보안 문제로 인해 locals에 변수값을 정의하지 않았다면,

    • module로 가져가서 정의하거나,
    • terraform.tfvars 파일 내부에 Variable = Value 형식으로 정의하거나,
    • CLI 명령 시 파라미터로 정의하거나,
    • plan시 직접 입력할 수도 있습니다.
  • 정의 방법

      variable "http_port" {
          description = "This is the http_port"
          default     = 80
      }
  • 사용 방법

      resource "aws_security_group" "web_sg" {
        name = "standalone_web_sg"
        ingress {
              # var."변수명"
          from_port   = var.http_port
          to_port     = var.http_port
          protocol    = "tcp"
          cidr_blocks = ["${var.cidr_blocks["cidr_all"]}"]
        }
      }

output

  • 테라폼으로 만든 자원을, state 파일에 변수 형태로 저장하는 것을 의미합니다. (출력 변수)

  • 보통 outputs.tf 파일에 정의됩니다.

  • 일반적으로, 동일한 워크스페이스에서 서로 다른 모듈 간 리소스를 참고해야 할 때 사용됩니다.

    • 모듈A에서 만든 aws_vpc 정보를 모듈B에서 사용해야할 때,
    • 모듈A에 output을 정의하면, 해당 output 값이 state 파일에 기록되며,
    • 모듈B는 모듈A의 리소스 정보를 사용할 수 있게 됩니다.
  • 정의 방법 (모듈A)

      # 모듈A에 특정 리소스 생성
      resource "aws_vpc" "default" {
          cidr_block = "10.0.0.0/16"
      }
    
      # 모듈A에서 만든 aws_vpc 정보를 state 파일에 저장
      output "vpc_id" {
          value = aws_vpc.default.id
      }
  • 사용 방법 (모듈B)

      moodule.<MODULE NAME>.<OUTPUT NAME>
      # module."모듈A".vpc_id

data

  • 다양한 출처로부터 이미 생성 되어있는 리소스 정보를 가져오거나,

    • provider(GCP, AWS, etc)
  • 특정 워크스페이스의 리소스 정보를 가져와야 할 때 사용됩니다.

    • remote state
  • 사용 예제 1 (AWS 리소스 정보 가져오기)

      data "aws_availability_zones" "available" {
        state = "available"
      }
      resource "aws_subnet" "primary" {
        availability_zone = data.aws_availability_zones.available.names[0]
      }
  • 사용 예제 2 (특정 워크스페이스의 리소스 정보 가져오기)

      data "tfe_outputs" "사용자지정" {
        organization = "사용자지정"
        workspace = "사용자지정"
      }
      locals {
           특정변수 = data.tfe_outputs."사용자지정".values."특정변수"
      }

output과 data의 차이

  • output
    • 일반적으로, 동일한 워크스페이스에서 서로 다른 모듈 간 리소스를 참고해야 할 때 사용됩니다.
  • data
    • 다양한 출처로부터 이미 생성 되어있는 리소스 정보를 가져오거나,
    • 특정 워크스페이스의 리소스 정보를 가져와야 할 때 사용됩니다.

module

  • resource를 기반으로 작성된 변수들을 상속 받아, 필요한 부분을 override해서 사용하는 기능입니다.
  • module은 크게 두가지로 나눌 수 있습니다.
    • Root module : Terraform 커맨드가 실행 되고 있는 module
    • Child module : Root module에서 리소스를 생성하기 위해 참조하고 있는 module

module 사용 예제

  • 디렉토리 예제

      terraform
      ├── main.tf
      ├── locals.tf
      └── vpc_module
          ├── vpc.tf
          └── variables.tf
  • child module인 vpc_module/vpc.tf와 vpc_module/variable.tf 작성

      # vpc_module/vpc.tf
    
      resource "aws_vpc" "vpc" {
        cidr_block = var.cidr_vpc
        instance_tenancy = "default"
        tags = {
          Name = "ingnoh-VPC"
        }
      }
      # vpc_module/variable.tf
    
      variable "cidr_vpc" {
        type = string
      }
  • root module인 main.tf, locals.tf 작성

      # main.tf
    
      module "network" {
          # 모듈로 사용할 파일들이 저장된 디렉토리를 명시
        source = "./vpc_module"
    
          ...
        cidr_vpc = local.cidr_vpc
          ...
    
      }
      # locals.tf
    
      locals {
    
        cidr_vpc = "???"
    
      }

기본적인 디렉터리 구조 예제

├── README.md

├── provider.tf

├── main.tf

├── variables.tf

├── outputs.tf

기본 명령어

  • terraform init
    • 테라폼 명령어 사용을 위한 각종 설정을 진행하며, 프로젝트를 초기화하는 명령어입니다.
      • 실행한 경로에 .terraform 파일이 생성되며,
      • provider에 맞는 플러그인을 다운받고,
      • 기존 인프라 상태를 가져올 수 있는지 확인하게 됩니다.
      • Root Module을 수정할 때마다 terraform init을 진행해야합니다.
  • terraform plan
    • 작성한 테라폼 코드로 실제 인프라가 어떻게 생성될지에 대한 예측 결과를 보여주는 명령어입니다.
      • 테라폼 코드와 실제 인프라의 diff를 출력해줍니다.
      • 실제로 가장 많이 쓰이는 명령어입니다.
      • 기본적으로 plan에 문제가 없어야 apply에 문제가 없을 확률이 높습니다.
  • terraform apply
    • 작성한 테라폼 코드로 실제 인프라를 생성하는 명령어입니다.
      • 실제 인프라에 영향을 끼치는 명령어이므로 주의 깊게 실행 해야합니다.
  • terraform import
    • 이미 만들어져있는 자원을 테라폼 state 파일로 옮겨주는 명령어입니다.
  • terraform state
    • 테라폼 state 파일을 다루는 명령어입니다.
    • 하위 명령어로 mv, push와 같은 명령어가 있습니다.
  • terraform destroy
    • 생성된 자원들을 state 파일 기준으로 모두 삭제하는 명령어입니다.

명령어 실행 구조

참고

Comments