8주차 - Automation - ACK, Crossplane, Pulumi

0. 도입

  • 로컬에 Terraform을 설정해본다.

  • AWS 설정을 해본다.

  • HCL에 대해 알아본다.

  • Block을 알아본다.

  • Version 알아본다.

  • 프로바이더 버전을 알아본다.

  • 리소스 구성 해본다.

  • 종속성, 리소스 속성 참조해본다.

  • 데이터 소스 구성, 변수 선언, 변수 참조해본다.

  • output을 활용해본다.

  • 모듈화를 해본다.

  • VPC를 배포해보고 보안그룹 및 EC2도 배포해본다.

  • 마지막으로 Terraform으로 EKS를 배포해본다.

  • CloudNet@ 가시다 서님께 감사의 말씀을 드려본다.

1. 선수지식

  • 기본 AWS

  • EKS에 대한 설정들(Terraform 대상 사용)

2. 실습 환경 준비

A. [준비] 로컬 환경

  1. https://developer.hashicorp.com/terraform/install

    1. 해당 링크를 사용해서 테라폼을 설치합니다

wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update && sudo apt install terraform
설치 확인
  1. AWSCLI 설치

    1. 해당 링크를 사용해서 AWS CLI 를 설정한다.

    2. 'aws configure' 으로 AWS 크리덴셜을 설정한다.

curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
  1. EKSCTL 설치

    1. 해당 링크를 사용해서 EKSCTL 을 설정한다.

  2. KUBECTL 설치

    1. 해당 링크를 사용해서 KUBECTL 을 설정한다.

  3. HELM 설치

    1. 해당 링크를 사용해서 HELM을 설정한다.

  • aws configure 잘된것을 확인한다.

B. [준비] AWS 확인하기

목적: EC2 생성해보기

실험 설정:

  1. EC2 이미지중 제일 최근의 것을 가져오기

    1. 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

  2. terraform 코드 생성

실험 결과:

  1. terraform init

  1. terraform plan

  1. terraform apply

EC2 생성
  1. terraform 파일 수정

  1. terraform plan

  2. terraform apply

  • 이름 변경 확인

3. Terraform 기본 사용

A. [이론] HCL

  • IaC는 수동 프로세스가 아니라 코드를 통해서 인프라를 관리하고 프로비저닝 하는 것을 말합니다.

  • 테라폼은 HCL 을 사용해서 선언적으로 생성하고 버저닝을 히스토리로 관리가능합니다.

// 값을 가져와서 넣는다.
    myEKSname = format("%s name", var.somevariable)
// null 일때, 값을 넣는다.
  credentials = var.somevariable== "" ? file(var.somevariable) : var.somevariable

B. [이론] Block

  • 테라폼 구성을 명시하는데 block을 사용합니다.

  • 테라폼 버전과 프로바이더 버전을 명시함으로써 실행 오류를 제거합니다.

    • 3년 후에 실행하던 동일한 결과를 얻을 수 있어야한다!

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

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

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

  backend "local" { # state를 보관하는 위치를 지정
    path = "relative/path/to/terraform.tfstate"
  }
}
  • 테라폼 내에서 시맨틱 버전관리도 밑과 같이 가능하다.

# version = Major.Minor.Patch
version = 1.3.4

C. [이론] Version

목적: 높은 버전을 의도적으로 명시해서 init 확인하기

  • 버전이 안맞아서 안돌아가는 것을 확인 가능하다.

D. [이론] 프로바이더 버전

목적: 높은 프로바이더버전을 의도적으로 명시해서 init 확인하기

실험 설정:

  • 안돌아 가는것을 확인

E. [이론] 리소스 구성

목적: Jenkins 작업 생성해보기

실험 설정:

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

resource "aws_instance" "web" {
  ami = "ami-a1b2c3d4"
  instance_type = "t2.micro"  
}
```
  • 다음과 같이 리소스 블록은 resource로 시작하고 리소스 블락이 생성한 리소스 유형을 정의한다.

  • 다음과 같은 추가적 종속성이나 메타 인수를 정의가 가능하다.

    • depends_on : 종속성을 선언하며, 선언된 구성요소와의 생성 시점에 대해 정의

    • count : 선언된 개수에 따라 여러 리소스를 생성

    • for_each : map 또는 set 타입의 데이터 배열의 값을 기준으로 여러 리소스를 생성

    • provider : 동일한 프로바이더가 다수 정의되어 있는 경우 지정

    • lifecycle : 리소스의 수명주기 관리

    • provisioner : 리소스 생성 후 추가 작업 정의

    • timeouts : 프로바이더에서 정의한 일부 리소스 유형에서는 create, update, delete에 대한 허용 시간 정의 가능

F. [이론] 종속성/ 리소스 속성 참조

목적:

실험 설정:

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

resource "local_file" "def" {
  content  = local_file.abc.content    // 리소스참조로종속성! 표기
  //  depends_on = [
  //  local_file.abc   // 명시적종속성!
  //  ]
  
  filename = "${path.module}/def.txt" 
}
  • 종속성 표기되는 것을 확인

H. [이론] 데이터 소스 구성

목적: 데이터 소스를 정의해서 구성이 가능하다.

실험 설정:

  1. 파일을 참조

data "local_file" "abc" {
  filename = "${path.module}/abc.txt"
}
  1. 파일을 생성

    echo "t101 study - 2week" > abc.txt

I. [이론] 데이터 소스 속성 참조

목적: AWS 가용영역을 인수로 정의하고 가져오기

실험 설정:

  1. 인수값을 확인할 수 있다.

  1. 서브넷 id 만 지정해주면 생성이 될것으로 보인다.

J. [이론] 변수 선언 방식

목적: 테라폼 변수 생성해보기

테라폼 예약 변수 이름으로 사용 불가능 : source, version, providers, count, for_each, lifecycle, depends_on, locals

  • 변수 정의 시 사용 가능한 메타인수

    • default : 변수 값을 전달하는 여러 가지 방법을 지정하지 않으면 기본값이 전달됨, 기본값이 없으면 대화식으로 사용자에게 변수에 대한 정보를 물어봄

    • type : 변수에 허용되는 값 유형 정의, string number bool list map set object tuple 와 유형을 지정하지 않으면 any 유형으로 간주

    • description : 입력 변수의 설명

    • validation : 변수 선언의 제약조건을 추가해 유효성 검사 규칙을 정의 - 링크

    • sensitive : 민감한 변수 값임을 알리고 테라폼의 출력문에서 값 노출을 제한 (암호 등 민감 데이터의 경우) - 링크

    • nullable : 변수에 값이 없어도 됨을 지정

variable "string" {
  type        = string
  description = "var String"
  default     = "myString"
}

variable "number" {
  type    = number
  default = 123
}

variable "boolean" {
  default = true
}

variable "list" {
  default = [
    "google",
    "vmware",
    "amazon",
    "microsoft"
  ]
}

output "list_index_0" {
  value = var.list.0
}

output "list_all" {
  value = [
    for name in var.list : upper(name)
  ]
}

variable "map" { # Sorting
  default = {
    aws   = "amazon",
    azure = "microsoft",
    gcp   = "google"
  }
}

variable "set" { # Sorting
  type = set(string)
  default = [
    "google",
    "vmware",
    "amazon",
    "microsoft"
  ]
}

variable "object" {
  type = object({ name = string, age = number })
  default = {
    name = "abc"
    age  = 12
  }
}

variable "tuple" {
  type    = tuple([string, number, bool])
  default = ["abc", 123, true]
}

variable "ingress_rules" { # optional ( >= terraform 1.3.0)
  type = list(object({
    port        = number,
    description = optional(string),
    protocol    = optional(string, "tcp"),
  }))
  default = [
    { port = 80, description = "web" },
  { port = 53, protocol = "udp" }]
}

  • 유효성 검사

  • 변수 참조

  • 민감한 변수 취급

  • output 선언 및 활용

  • 모듈화도 진행이 가능하다.

다음의 내용들을 종합해서 vpc를 진행해보자

R. [실습] VPC 배포

목적: vpc를 모듈로 받아서 생성할 수있다.

  • Security Group 설정도 가능하다.

실험 설정:

  1. 다음 코드들을 들고 와서 필요한부분들을 고쳐서 vpc를 생성한다.

git clone https://github.com/terraform-aws-modules/terraform-aws-vpc/
tree terraform-aws-vpc/examples -L 1
tree terraform-aws-vpc/examples -L 2
cd terraform-aws-vpc/examples/simple

  • plan 을 확인해보면 ap-northeast에 정상적으로 배포하는 것을 볼 수있다.

S. [실습] 보안그룹/EC2 배포

목적: Terraform으로 원하는 ec2 인스턴스를 생성할 수있다.

실험 설정:

  1. 보안 그룹 생성

  2. 보안 그룹 배포

  3. ec2 생성

  4. 배포 후 ec2 생성 확인

실험 결과:

  1. 그래프 확인

  1. vpc 생성 확인

  1. EC2 생성 확인 및 생성 데이터 확인

5. Terraform 으로 EKS 배포

A. [실습] 첫번째 EKS 클러스터 배포

목적: 첫번쨰 EKS 클러스터 Terraform으로배포해보기

실험 설정:

'git clone https://github.com/gasida/aews-cicd.git' 을 가지고 terraform init 과 plan으로 어떤 리소스가 배포되는지 확인해본다.

  1. 주요 생성 자원들

    1. VPC

    2. Subnet

    3. IGW

    4. NATGW

    5. Routing Table

    6. EKS

    7. EKS SG

실험 결과:

  1. 다음과 같이 EKS 가 정상적으로 Terraform으로 배포된것을 확인할 수있다.

'more terraform.tfstate' 으로 eks cluster 에 대한 값들을 정상 표기하는 것을 확인 할 수 있습니다.

  • 'ubectl get pod -A' 로 배포된 리소스 확인

  1. 클러스터 인증 정보까지 변경하고 확인해본다.

  • AWS 에서 생성하는것보다 20분정도 빠르게 생성된것같다.

B. [실습] 두번째 EKS 클러스터 배포

목적: 첫번째 EKS를 이름만 바꿔서 배포할 수 있다.

실험 설정:

  1. 이름만 바꿔서 배포 해보기

  1. 버전이 1.28인 eks 클러스터가 배포된것을 확인

C. [실습] 삭제

목적: EKS 자원들을 Terraform으로 삭제 할 수 있다.

실험 설정:

  1. 'terraform destroy -auto-approve -var=ClusterBaseName=myeks2 -var=KubernetesVersion="1.28"'

version으로 잡아서 삭제 진행

실험 결과:

  1. 삭제 확인

6. AWS Controller for Kubernetes (ACK)

  • 소개

    • AWS ACK 는 AWS 서비스 리소스를 K8S에서 직접 정의하고 사용할 수 있게 합니다.

  • 다음과 같이 K8S 의 api를 사용해서 ack-s3-controller를 사용해 IRSA가 AWS S3 API를 통해 버킷을 생성합니다.

B. [실습] ACK로 RDS 생성

목적: ACK로 RDS 자원을 생성할 수 있다.

실험 설정:

  1. ACK RDS Controller 설치

  1. irsa 설정

  • eksctl을 사용해야되는데 eksctl이 설정된 bastion이 없어서 진행을 못했다.

  • 깔아서 진행해볼 예정이다.

  1. AWS RDS for MariaDB 생성

Last updated