50/120

김건호·2022년 4월 21일
0
post-custom-banner

terraform 환경 구성

설치

$ 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
Terraform v1.1.9
on linux_amd64

테라폼 패키지에 파일 딱 하나

관리도구는 파일하나로 만드는게 요새 트렌드

AWS IAM 사용자 생성

  1. IAM 서비스에서 사용자 생성
  2. 프로그래밍 방식으로 생성
  3. administratoraccess 권한이 있는 그룹에 사용자 추가
  4. 키파일.csv 다운로드

AWS CLI 설치

$ curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
$ sudo yum -y install unzip
$ unzip awscliv2.zip
$ sudo ./aws/install

$ aws --version
aws-cli/2.5.7 Python/3.9.11 Linux/3.10.0-1127.el7.x86_64 exe/x86_64.centos.7 prompt/off

asw configure로 사용자 설정

$ aws configure

# 사용자 확인
$ aws sts get-caller-identity

terraform 개념

HCL: Hashicorp Configuration Lanaguage
terraform에서 사용하는 전용 언어
DSL : Domain Specific Language

기능

https://www.terraform.io/intro

workflow

  • 코드를 작성 HCL 언어로
  • Plan 생략이 가능
  • Apply 성공할때만 비용 발생

provider

https://registry.terraform.io/browse/providers

lock-in

구성파일

Terraform Configure File
.tf HCL
.tf.json json 형식
파일로 작성

현재 디렉토리의 위치가 매우 중요

<BLOCK TYPE> <BLOCK LABEL> ... {
	ARGUMENT
	KEY = VALUE
}

블록(중괄호)로 구성

테라폼 블록

terraform {
  required_providers {
    aws = { # aws 아니여도 됨 그냥 이름 지정 실제 클라우드는 source 가 프로바이더의 종류
      source  = "hashicorp/aws" # 공급자를 나타냄 (정해져있음)
      version = "~> 3.27"  # 버전 지정 안하면 최신버전 설치
      # provider version 확인 (aws 새로운 기능 추가/삭제-> API가 변경되는 경우가 있음)
    }
  }
  required_version = ">= 0.14.9" # 테라폼 버전
}

굳이 안해도됨

프로바이더 블록(필수)

provider "aws" { # 위에 aws랑 반드시 매칭되어야 함
  profile = "default"
  region  = "us-west-2"
}
  • provider " aws" : terraform 블록 이름 매칭
    profile : aws w자격증명파일의 프로필
    .aws/config 의 섹션
    region 리전

리소스 블록

resource "RESOURCE_TYPE" "NAME" {
  ARGUMENT = VALUE
}
  • RESOURCE_TYPE: 리소스 종료
  • NAME: 리소스 이름(테라폼에서 구분 하기 위한 이름)
  • ARGUMENT: 인자/속성
resource "aws_instance" "app_server" { # 별명 마음대로 붙일 수 있음
  ami           = "사용하는 이미지의 아이디 - 이미지 이름이 같아도 리전이 다르면 아이디가 다르니 주의"
  instance_type = "인스턴스 유형"

  tags = {
    Name = "ExampleAppServerInstance"
  }
}

리소스는 앤서블의 모듈과 비슷
테라폼의 모듈은 = 앤서블의 역할

실행 순서

초기화 작업

$ terrafrom init # 현재 디렉토리 위치 중요

Installing hashicorp/aws
프로바이더를 받음
Terraform has been successfully initialized!
[vagrant@controller 01]$ ls -a
.  ..  main.tf  .terraform  .terraform.lock.hcl

.terrform 건드리면 안됨
.terrform의 tree구조에서 가장 마지막에 있는 실행파일은 프로바이더 -> init으로 받아온 파일 -> tf 파일을 얘가 받아서 실행을 해줌
API로 바꿔주는 파일

프로바이더 플러그인 설치를 위한 과정
또 하면 이미 초기화 되었다고 나옴

hcl 파일은 사고방지를 위한 파일로 삭제후 init 하면 init 새로 진행
버전이 바뀌면 init을 새로 진행

.trerrform은 절대 공유되어서는 안됨

포맷팅

$ terraform fmt

다른말로는 linting 한다고 함
포맷을 맞춰줌

파이썬 pep8 스타일 가이드과 비슷

언제?
새로운 파일 작성
기존 파일 변경

유효성 검증

$ terraform validate

코드가 문법상 이상이 없는지 확인

plan

$ terraform plan

(known after apply) 항목은 apply 이후에 알 수 있다는 내용

현재 aws와 내 코드와 비교하는 기능

apply

apply 시 자동으로 plan 진행
하지만, 항상 plan을 먼저하여 어떻게 변하는지 다 봐야함

플랜 한번 더 해보면 바뀐게 없다 -> 선언한 파일대로 만들어져있어서 변경할게 없다

삭제

terraform destroy

상태 확인

아래 두 파일은 절대 공유 금지

  • terraform.tfstate: 현재상태
  • terraform.tfstate.backup: 직전 상태
    tfstate 파일을 삭제하거나 잃어버림 -> 현재상태를 잃어버림
    plan 하면 새로만든다고함-->실행중이던 애는 지울수가 없음 리소스 많은경우 수동으로 지우지도 못함
    --> 관리를 잘해야함

상태 확인 명령어

terraform show # terraform.tfstate -> 현재 상태 확인
terraform state list 어떤 리소스가 있는지 목록 리소스의타입.이름 형식으로 나옴
terraform state show aws_instance.app_server # 리소스에 대한 정보만 확인 가능

예시

이미지를 바꾸려고함

기존에 있는건 배포되어있는 상태 -> 이미지 교체 시도
인스턴스가 삭제되었다가 다시만들어짐 -> 인스턴스에서 이미지만 바뀔 수 없기 때문에 -> 기존꺼 삭제하고 새로 만들어야함

tags에서 태그를 추가하는 경우는 현재있는 상태에서 바로 업데이트
update in-place(속성 업데이트할 수 있는 상태) 태그만 따로 추가하는 것 이기 때문에

상태 재동기화

부득이하게 관리 콘솔에서 작업을 햇을때 동기화 시킬 수 있음
ex) 디스크 용량을 바꿀 경우 8->10 바로 테라폼에 반영되지 않으므로 재동기화

terraform refresh

리소스 생성 순서

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

Elastic IP Resource 추가

aws_eip

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

인스턴스에 추가

S3 Bucket 만들기

resource "aws_s3_bucket" "b" {
  bucket = "my-tf-test-bucket"

  tags = {
    Name        = "My bucket"
    Environment = "Dev"
  }
}

resource "aws_s3_bucket_acl" "example" {
  bucket = aws_s3_bucket.b.id
  acl    = "private"
}

암시적 의존성과 명시적 의존성

암시적 의존성

elastic ip는 ec2가 있어야 연결될 수 있기때문에 자동으로 ec2가 먼저 생성되고 생성됨

aws_instance.app_server: Creating...
aws_s3_bucket.b: Creating...
aws_s3_bucket.b: Creation complete after 3s 
aws_s3_bucket_acl.example: Creating...
aws_s3_bucket_acl.example: Creation complete after 1s
aws_instance.app_server: Still creating... [10s elapsed]
aws_instance.app_server: Still creating... [20s elapsed]
aws_instance.app_server: Still creating... [30s elapsed]
aws_instance.app_server: Creation complete after 33s
aws_eip.lb: Creating...
aws_eip.lb: Creation complete after 1s 

Apply complete! Resources: 4 added, 0 changed, 0 destroyed.

삭제할때는 역순으로

명시적 의존성

ec2가 S3의 오브젝트를 접근하는 것과 같은 상황에선 depends_on(의존관계를 직접적으로 설정할 수 있음)으로 명시적 의존성을 걸어 S3가 먼저 생성될 수 있도록 하여야 함

resource "aws_instance" "app_server" {

  depends_on = [
    aws_s3_bucket.app_bucket
  ]
}

depends_on 은 meta argument로
테라폼 자체에서 제공하는 argument로 공통적으로 사용 됨

입력 변수(Input Variable)

변수를 설정하기 위한 variable 블록
블록은 variable.tf 별도의 파일로 관리 가능

variable "image_id" {
  type = string
}

variable "availability_zone_names" {
  type    = list(string)
  default = ["us-west-1a"]
}
  • type:
    일반 타입
    string : "app_server"
    number : 1, 1.0
    bool : true, false
    복합 타입
    - list / tuple
    - [a, b, c]
    - map / object
    - `{a = abc, b = xyz}
  • default: 기본 값
  • description: 설명
variables abc {
  type = list(string)
  # ["a", "b"]
  type = list(number)
  # [1, 2]
}

변수 값 할당

-var 옵션

ansible -e 옵션과 같음 우선순위가 제일 높음

terraform plan -var "instance_name=xyz"

terraform.tfvars 파일

가장 많이 쓰는 방식
terraform.tfvars

instance_name = "xyz"
profile
Ken, 🔽🔽 거노밥 유튜브(house icon) 🔽🔽
post-custom-banner

2개의 댓글

comment-user-thumbnail
2022년 4월 21일

왜이리 빨리 끝낸거야 ㅋㅋㅋㅋㅋ

1개의 답글