nayoungs
항상 끈기있게
nayoungs
  • 분류 전체보기 (274)
    • Cloud (21)
      • AWS (15)
      • Azure (3)
      • NCP (2)
      • GCP (1)
    • DevOps (68)
      • Docker (16)
      • Kubernetes (50)
      • CICD (2)
    • IaC (25)
      • Ansible (17)
      • Terraform (8)
    • Certification (4)
    • 금융 IT (5)
    • AI (3)
    • Linux (47)
    • 미들웨어 (5)
    • Programming (7)
      • GoLang (3)
      • Spring (4)
    • CS (25)
      • 네트워크 (17)
      • 운영체제 (5)
      • Web (1)
      • 개발 상식 (2)
      • 데이터베이스 (0)
    • Algorithm (59)
      • 프로그래머스 (36)
      • 백준 (18)
      • 알고리즘 정리 (5)
    • ETC (5)

블로그 메뉴

  • 홈
  • 방명록

공지사항

인기 글

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
nayoungs

항상 끈기있게

IaC/Terraform

[Terraform] Terraform 개요 및 설치

2022. 4. 21. 20:41
728x90

📌INDEX

  • Terraform이란?
  • Terraform 설치
  • Terraform 구성 파일
  • Terraform 실행 순서
  • Terraform 입력 변수
  • 실습해보기



✔️ Terraform이란?

  • hashicorp/terraform: Terraform 깃허브 저장소
  • What is Terraform?
  • terraform은 배포를 위한 것 => 새로운 것을 만들어내는 것 , 라이프사이클(변경, 삭제, 생성 등) 담당
    • ansible은 새로운 것을 만들어내는 것이 아닌 주로 구성을 관리하기 위한 것
  • terraform은 IaC(Infrastructure as Code) 도구
  • provider를 통해 액세스 가능한 API를 통해 거의 모든 플랫폼 또는 서비스와 함께 작동할 수 있음
  • HCL(Hashicorp Configuration Language) 사용 <--- DSL(Domain Specific Language)

❕ Workflow 

  • 코드 작성(Write) : HCL 사용
  • 계획(Plan) : ansible의 --check옵션과 유사(시뮬레이션)
  • 적용(Apply) : provider에게 provisioning



✔️ Terraform 설치

Terraform Downloads

$ sudo yum install -y yum-utils
$ sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo
$ sudo yum -y install terraform
$ terraform --version

AWS-CLI Downloads

  • 참고) AWS CLI 없이 환경 변수로도 설정 가능 : Setting AWS_ACCESS_KEY_ID
  • AWS IAM 사용자 생성 과정
    • administratoraccess 권한이 있는 그룹 생성
    • 사용자 생성(프로그래밍 방식)
    • 앞서 생성한 administratoraccess 권한이 있는 그룹에 사용자 추가
    • 키파일.csv 다운로드 : 'aws configure' 명령 시 액세스 키(access key) 사용
$ cd ~
$ curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" 
$ sudo yum install -y unzip
$ unzip awscliv2.zip 
$ sudo ./aws/install
$ aws --version
$ aws configure
$ aws sts get-caller-identity

선택사항: ntp 시간 설정

$ sudo vi /etc/chrony.conf
$ sudo systemctl restart chronyd
$ timedatectl set-ntp true
$ sudo timedatectl set-timezone Asia/Seoul
$ chronyc sources -v



✔️ Terraform 구성 파일

Terraform Configure File

  • .tf
  • .tf.json

인코딩 : Unicode

현재 작업 디렉토리 위치에 따라 해당 디렉토리의 .tf, .tf.json 모두 읽어서 실행 => 어떤 디렉토리에서 진행하는지가 중요

참고) 버전 0.11,0.12는 0.13,0.14.1.xx 과 호환 안됨, 0.13,0.14,1.xx는 서로 호환됨

 

Block

Terraform 파일은 Block으로 구성

항상 중괄호로 시작해서 중괄호로 끝남 { }

<BLOCK TYPE> <BLOCK LABEL> ... {
	ARGUMENT
	KEY = VALUE
}
  • BLOCK LABEL은 여러개 올 수 있음

 

Terraform Block

  • 공급자를 지정
  • 버전에 관련된 지정이 필요없다면 작성이 필수는 아님
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 3.27"                   #aws provider버전이 3.27보다 커야함,별도로 지정하지 않으면 최신버전 설치
    }
  }

  required_version = ">= 0.14.9"            #terraform 최소 필요 버전
}
  • aws: 프로바이더의 이름
  • source: 프로바이더의 종류
  • version: 프로바이더의 버전
    • 4.10 : 특정 버전
    • ~> 3.12 : 특정 버전 이상
    • -> 3.12 : 최소 버전

 

Provider Block

  • 필수로 작성해야함
provider "aws" {
  profile = "default"
  region  = "us-west-2"
}

- provider "aws" : terraform block의 provider 이름과 매칭이 되어야함

- profile: aws 자격증명 파일의 프로필

  • ~/.aws/config의 section, ~/.aws/credentials의 section
[vagrant@controller .aws]$ cat config
[default]
region = ap-northeast-2
  • 사용자가 바꿔서 지정해도됨

- region

 

Resource Block

resource "RESOURCE_TYPE" "NAME" {
  ARGUMENT = VALUE
}
  • RESOURCE_TYPE: 리소스 종류
  • NAME: 리소스 이름(terraform에서 구분 하기 위한 이름)
  • ARGUMENT: 인자/속성
  • 참고) 테라폼 리소스 = 앤서블 모듈 테라폼 모듈 = 앤서블 역할
  • 참고) AWS PROVIDER DATA RESOURCES

 

예시

resource "aws_instance" "app_server" {
  ami           = "ami-830c94e3"
  instance_type = "t2.micro"

  tags = {
    Name = "ExampleAppServerInstance"
  }
}
  • 참고) AMI는 같은 이미지더라도 리전이 다르면 아이디가 다름
  • 참고) tag는 AWS를 사용하면 공통속성

 

리소스 생성 순서⭐

  • 의존 관계가 없는 리소스는 병렬로 실행
  • 의존 관계가 있는 경우 의존 관계에 따라서 순서가 정해지게 됨
  • 지울 때(destory)는 역순

명시적 의존성

  • Meta-Arguments
  • 암시적 의존성 : attribute reference를 할당함으로써 암시적 의존성을 가지게 됨
  • depends_on : 의존성을 직접 지정
resource "aws_instance" "app_server" {

  depends_on = [
    aws_s3_bucket.app_bucket
  ]
}

Argument Reference

  • 리소스 블럭의 파라미터

Attribute Reference

  • 속성
  • 암시적 의존성



✔️ Terraform 실행 순서

초기화

디렉토리 위치 확인하기

provider plugin을 다운로드 받을 수 있도록 최초로 1번을 해줘야함

$ terraform init

참고) .terraform은 절대 직접 수정하면 안됨 + 공유하면 안됨 + git에도 올리면 안됨

  • 프로바이더가 tf 코드를 받아서 api로 바꿔서 실행해줌 => 프로바이더는 반드시 있어야함
  • 초기화 작업이 필요한 경우
    • 최초로 프로바이더 설치
    • 프로바이더 버전 업데이트

 

포맷팅

포맷을 일률적으로 맞춰줌

$ terraform fmt
  • 포맷팅이 필요한 경우
    • 새로운 파일 작성
    • 기존 파일 변경

 

유효성 검증

문법상으로 이상이 없는지 검사

$ terraform validate
Success! The configuration is valid.
  • ansible '--systanx-check'와 동일하다고 보면됨

 

계획

실제 aws 서비스 상태와 작성한 프로그램의 상태를 비교해줌

  • 꼭 해야되는 것은 아니나, 하는 것이 좋음
$ terraform plan

 

적용

명령후 yes하면 만들어짐

$ terraform apply
  • --auto-approve 옵션 : 자동 승인, yes 입력안해도됨
$ terraform apply --auto-approve
  • 이미 apply 된 상태에서 이미지를 변경하고 apply 한다면??
    • destroy and then create replacement : 기존의 것 제거하고 교체 => 이미지만 교체하는 것은 불가능
  • 태그만 변경하는 경우에는 삭제되지 않고, 단순히 update

 

제거

yes하면 제거됨

$ terraform destroy

 

상태 확인

terraform.tfstate를 보는 명령 == 상태를 보는 명령어

terraform show
  • [type].[이름]
$ terraform state list
aws_instance.app_server
  • 리소스 상세 정보 확인
    • 리소스가 많을 때는 지정해서 확인 가능
[vagrant@controller 01]$ terraform state show aws_instance.app_server

 

상태 재 동기화

수동으로 수정(ex: AWS Console)을 했다면 해당 명령어를 통해 동기화할 수 있음

$ terraform refresh

 

tfstate 파일

  • terraform.tfstate: 현재상태
  • terraform.tfstate.backup: 직전 상태
[vagrant@controller 01]$ ls
main.tf  terraform.tfstate  terraform.tfstate.backup
  • terraform.tfstate, terraform.tfstate.backup
    • 절대 공유하면 안되고, 직접 수정하면 안되는 파일

 

❕ 만약 terraform.tfstate가 없어진다면?(삭제된다면?)

  • 테라폼은 상태(state)가 없어진 것이기 때문에 아무것도 없다고 가정하고, apply 시 새로 생성됨
  • 기존의 인스턴스는 테라폼에서 더 이상 관리가 안됨 => 수동으로 관리해야함
  • 만약 백업(terraform.tfstate.backup)에 이전상태가 있다면 복구할 수 있음



✔️ Terraform 입력 변수

  • Input Variabe
  • 변수 사용할 때는 따옴표 X
  • number : 숫자는 따옴표 붙이면 안됨
variable "instance_name" {
  type        = string
  description = "Instance Name"
  default     = "App Instance"
}

일반적으로 type, default, description 3가지 정의

  • type
일반타입 string "app_server"
number 1, 1.0
bool true, false
복합타입 list/tuple [a,b,c]
map/object {a=abc, b=xyz}
  • default: 기본 값 -> default는 정의하지 않아도 크게 상관없음 : 우선순위 매우 낮음
  • description: 설명

 

예시

list(값의 타입) : 타입 안넣어주면 디폴트는 string

variable "abc" {
  type = list(string)
  # ["a", "b"]
  type = list(number)
  # [1, 2]
}

변수만 정의하는 별도의 파일

variable "instance_name" {
  type        = string
  description = "Instance Name"
  default     = "App Instance" 
}

 

변수 할당 방법

  • -var옵션

임시로 할당

우선순위가 가장 높음

$ terraform plan -var "instance_name=xyz"
  • terraform.tfvars 파일에 변수 설정

가장 많이 사용하는 방식임

default값이 없어도 해당 값이 할당됨

단, variable.tf에 정의되어있어야함

$ instance_name = "xyz"
  • 환경 변수 설정

잘 안씀



✔️ 실습해보기

💻 탄력적 IP가 할당된 EC2 인스턴스 생성하기

 

📝main.tf

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

  required_version = ">= 0.14.9"
}

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

resource "aws_instance" "app_server" {     #EC2 인스턴스
  ami           = "ami-02de72c5dc79358c9"
  instance_type = "t2.micro"

  tags = {
    Name = "ExampleAppServerInstance"
  }
}

resource "aws_eip" "app_server_eip" {      #EIP 할당
  vpc      = true
  instance = aws_instance.app_server.id    #암시적 종속성
}
  • eip는 인스턴스가 생성된 후 생성됨
    • 암시적인 종족성을 가지기 때문 : ec2-instance의 attribute reference을 할당함으로써
  • 지울 때(destory)는 역순
$ terraform fmt
$ terraform validate
$ terraform plan
$ terraform apply

인스턴스가 생성되고, 탄력적 IP가 할당된 것을 확인할 수 있음



💻 생성된 EC2 인스턴스에 태그 추가하기

 

📝main.tf : tags 수정

 tags = {
    Name        = "ExampleAppServerInstance"
    Environment = "Terraform"                  #태그 추가
  }
$ terraform fmt
$ terraform validate
$ terraform plan
$ terraform apply

태그만 변경하는 경우에는 삭제된 뒤 다시 생성되지 않고, 단순히 update됨

태그 추가 확인



💻 S3 bucket 생성하기

 

📝main.tf

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

  required_version = ">= 0.14.9"
}

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

resource "aws_s3_bucket" "app_bucket" {
  bucket = "encore-20220421"
}
$ terraform fmt
$ terraform validate
$ terraform plan
$ terraform apply

생성 확인



 

💻 EC2 인스턴스의 이름, AMI이미지, 리전, 가용영역 변수처리하기

 

📝main.tf

resource "aws_instance" "app_server" {      
  ami               = var.image_id          #AMI 변수처리
  instance_type     = "t2.micro"
  availability_zone = var.instance_az       #az 변수처리

  tags = {
    Name        = var.instance_name         #인스턴스 이름 변수처리
    Environment = "Terraform"
  }
}

resource "aws_eip" "app_server_eip" {
  vpc      = true
  instance = aws_instance.app_server.id  
}

resource "aws_s3_bucket" "app_bucket" {
  bucket = "encore-20220421"
}

📝provider.tf

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

  required_version = ">= 0.14.9"
}

provider "aws" {
  profile = "default"
  region  = var.instance_region            #region 변수 처리
}

📝variable.tf

variable "instance_name" {

}

variable "image_id" {

}

variable "instance_region"{

}

variable "instance_az" {
  
}

📝terraform.tfvars

instance_name   = "xyz"
image_id        = "ami-0454bb2fefc7de534"
instance_region = "ap-northeast-2"
instance_az     = "ap-northeast-2a"

 

$ terraform fmt
$ terraform validate
$ terraform plan
$ terraform apply

생성확인

  • 인스턴스 이름과 리전 확인

  • AMI 확인

  • 가용영역 확인

 

 

 

728x90
저작자표시 비영리 (새창열림)
    'IaC/Terraform' 카테고리의 다른 글
    • [Terraform] 모듈(Module)
    • [Terraform] Provisioners (feat.Taint)
    • [Terraform] 사용자 데이터(Userdata)와 보안그룹(Security Group)
    • [Terraform] 출력값(Output)과 로컬값(Local)
    nayoungs
    nayoungs
    안되면 될 때까지

    티스토리툴바