home..

EKS IaC

Kubernetes EKS AEWS Gasida Cloudnet IaC Terraform

EKS IaC

Infrastructure as Code 의 줄인말로, 구성할 인프라를 코드로 선언하는 방식입니다.

Hashicorp 사에서 공개한 도구인 Terraform 을 이용하여 AWS 자원을 프로비저닝 해볼 생각입니다.

실습은 Mac 에서 진행하기위해 brew로 설치를 진행합니다

# tfenv 설치
brew install tfenv

# 설치 가능 버전 리스트 확인
tfenv list-remote

# 테라폼 1.5.1 버전 설치
tfenv install 1.8.1

# 테라폼 1.5.1 버전 사용 설정 
tfenv use 1.8.1

# tfenv로 설치한 버전 확인
tfenv list

# 테라폼 버전 정보 확인
terraform version

# 자동완성
terraform -install-autocomplete
## 참고 .zshrc 에 아래 추가됨
cat ~/.zshrc
autoload -U +X bashcompinit && bashcompinit
complete -o nospace -C /usr/local/bin/terraform terraform

# AWS CLI 설치
brew install awscli

# EKSCTL 설치
brew install eksctl

# Kubectl 설치
brew install kubernetes-cli

# Helm 설치
brew install helm

# 추가 도구 설치
brew install tree jq watch

VS Code Extension 설치

Extension → HashiCorp HCL 설치

Untitled

기본 환경준비

mkdir learn-terraform
cd learn-terraform
touch main.tf

사용하려는 최신 AL2 ami ID 검색

AL2ID=`aws ec2 describe-images --owners amazon --filters "Name=name,Values=amzn2-ami-hvm-2.0.*-x86_64-gp2" "Name=state,Values=available" --query 'Images|sort_by(@, &CreationDate)[-1].[ImageId]' --output text`
echo $AL2ID

리소스 생성 Test

cat <<EOT > main.tf
provider "aws" {
  region = "ap-northeast-2"
}

resource "aws_instance" "example" {
  ami           = "$AL2ID"
  instance_type = "t2.micro"
}
EOT

배포하기

# plan 실행 시 아래와 같은 정보가 출력
terraform plan

# apply 실행
terraform apply
# Enter a value: yes 입력

삭제

# 리소스 삭제
terraform destroy -auto-approve

HCL

HCL(HashiCorp Configuration Language)은 Hashicorp사에서 IaC와 구성 정보를 명시하기 위해 개발된 오픈 소스 도구입니다.

HCL 특징

  • IaC는 코드를 통해 인프라를 관리하고 프로비저닝
  • HCL이 테라폼에서의 코드영역. 읽기쉽고 빠르게 배울 수 있게 설계
  • 선언적(declarative) 특성을 갖고 Turing-complete 언어적 특성

Untitled

json type으로 생성하는것보다 훨씬 간결하고 읽기 쉽다는 점이 제일 큰 장점입니다.

json type에 비해 약 50~70%정도 짧아진다고 하네요

HCL에서 사용하는 표현식은 다음과 같습니다

// 한줄 주석 방법1
# 한줄 주석 방법2

/*
라인
주석
*/

locals {
  key1     = "value1"     # = 를 기준으로 키와 값이 구분되며
  myStr    = "TF ♡ UTF-8" # UTF-8 문자를 지원한다.
  multiStr = <<EOF
  Multi
  Line
  String
  with anytext
EOF

  boolean1    =true   # boolean true
  boolean2    =false  # boolean false를 지원한다.
  deciaml     = 123    # 기본적으로 숫자는 10진수,
  octal       = 0123   # 0으로 시작하는 숫자는 8진수,
  hexadecimal = "0xD5" # 0x 값을 포함하는 스트링은 16진수,
  scientific  = 1e10   # 과학표기 법도 지원한다.

  # funtion 호출 예
  myprojectname = format("%s is myproject name", var.project)

  # 3항 연산자 조건문을 지원한다.
  credentials = var.credentials == "" ? file(var.credentials_file) : var.credentials
}

테라폼 블록

테라폼 버전이나 프로바이더 버전들은 명시적으로 선언해 실행 오류를 최소화하는것을 목표로 합니다.

멱등성을 보장하기 위해서죠

terraform {
  required_version = "~> 1.3.0" # 테라폼 버전

  required_providers { # 프로바이더 버전을 나열
    random = {
      version = ">= 3.0.0, < 3.1.0"
    }
    aws = {
      version = "4.2.0"
    }
  }

  cloud { # Cloud/Enterprise 같은 원격 실행을 위한 정보 [참고: Docs]
    organization = "<MY_ORG_NAME>"
    workspaces {
      name = "my-first-workspace"
    }
  }

  backend "local" { # state를 보관하는 위치를 지정 [참고: Docs, local, remote, s3]
    path = "relative/path/to/terraform.tfstate"
  }
}

버전 체계는 시맥틴 버전관리를 따라

# version = Major.Minor.Patch
version = 1.3.4

일반적으로 MAJOR.MINOR.PATCH 형태로 표현됩니다.

  • MAJOR: 호환되지 않는 API 변경
  • MINOR: 기존 버전과 호환되는 새로운 기능 추가
  • PATCH: 기존 버전과 호환되는 버그 수정

테라폼에서의 버전 제약 구문은 다른 프로그래밍 언어의 종속성 관리와 매우 유사하게 동작합니다. 여기 몇 가지 주요 연산자와 그들이 어떻게 작동하는지에 대한 간단한 요약입니다:

  • = 또는 없음: 이 연산자는 오직 지정된 버전만을 허용합니다. 다른 조건과는 병합될 수 없습니다.
  • !=: 이 연산자는 지정된 버전을 제외하고 모든 것을 허용합니다.
  • >, >=, <, <=: 이 연산자들은 기본 수학적 비교를 수행하여 버전을 허용하거나 제외합니다.
  • ~>: 이 연산자는 “거의 동일한” 버전을 허용합니다. 지정된 버전의 마지막 숫자만이 증가할 수 있습니다. 예를 들어, ~> 1.2는 1.3, 1.4 등을 허용하지만 2.0은 허용하지 않습니다.

리소스 구성

리소스 블록은 Terraform 코드에서 실제 클라우드 리소스를 선언하고 생성합니다.

  • 기본 구조resource 를 사용하여 리소스 블록을 시작합니다.
  • 리소스 유형resource 프로바이더에 종속적입니다.
  • 이름: 동일한 유형의 리소스를 구분하기 위해 사용합니다.
  • 구성 인수: 중괄호 {} 안에는 해당 리소스의 속성이나 설정을 정의합니다.

코드 예시

resource "local_file" "abc" {
  content  = "123"
  filename = "${path.module}/abc.txt"
}

resource "aws_instance" "web" {
  ami           = "ami-a1b2c3d4"
  instance_type = "t2.micro"
}

주의사항

  • 프로바이더 블록 별도 선언 권장resource 블록에서 사용되는 리소스 유형은 특정 프로바이더에 종속되기 떄문에 별도로 프로바이더를 선언하는 것이 권장됩니다.

종속성

resource, module의 선언으로 프로비저닝 되는 요소의 순서를 정의할수있습니다.

resource "local_file" "abc" {
  content  = "123!"
  filename = "${path.module}/abc.txt"
}

resource "local_file" "def" {
  content  = local_file.abc.content
  filename = "${path.module}/def.txt"
}

이런식으로 def는 abc를 참조해야만 생성이 가능하지만, 명시적인 depend_on 파라미터를 사용하여 종속성을 부여할수있스비낟.

resource "local_file" "abc" {
  content  = "123!"
  filename = "${path.module}/abc.txt"
}

resource "local_file" "def" {
  depends_on = [
    local_file.abc
  ]

  content  = "456!"
  filename = "${path.module}/def.txt"
}

리소스 속성

  • 리소스 구성에서 참조 가능한 값은 인수속성이다
    • 인수 : 리소스 생성 시 사용자가 선언하는 값
    • 속성 : 사용자가 설정하는 것은 불가능하지만 리소스 생성 이후 획득 가능한 리소스 고유 값
# Terraform Code
resource "<리소스 유형>" "<이름>" {
  <인수> = <값>
}

# 리소스 참조
<리소스 유형>.<이름>.<인수>
<리소스 유형>.<이름>.<속성>

resource "kubernetes_namespace" "example" {
  metadata {
    annotations = {
      name = "example-annotation"
    }
    name = "terraform-example-namespace"
  }
}

resource "kubernetes_secret" "example" {
  metadata {
    namespace = kubernetes_namespace.example.metadata.0.name # namespace 리소스 인수 참조
    name      = "terraform-example"
  }
  data = {
    password = "P4ssw0rd"
  }
}

쿠버네티스 프로바이더의 Namespace를 리소스로 생성해,

Secret을 해당 Namespace에 생성하는 종속성을 갖는 예시입니다.

Namespace 가 바뀌어도 참조중인 모든 리소스가 업데이트되죠.

데이터 소스 구성

데이터 소스는 외부 리소스나 저장된 정보를 참조할 때 사용합니다.

데이터 소스를 설정하는 방법은 리소스 블록을 정의하는 것과 비슷합니다.

데이터 소스 유형은 프로바이더 이름과 리소스 유형으로 구성되며, 이후에는 고유한 이름과 구성 인수를 선언합니다.

cat <<'EOT' > main.tf
data "local_file" "abc" {
  filename = "${path.module}/abc.txt"
}
EOT

메타인수로는 depends_oncountfor_eachlifecycle 등이 사용 가능합니다.

  • depends_on : 종속성을 선언하며, 선언된 구성요소와의 생성 시점에 대해 정의
  • count : 선언된 개수에 따라 여러 리소스를 생성
  • for_each : map 또는 set 타입의 데이터 배열의 값을 기준으로 여러 리소스를 생성
  • lifecycle : 리소스의 수명주기 관리
© 2024 mont kim   •  Powered by Soopr   •  Theme  Moonwalk