1
2
3
T101(=Terraform 101 Study)는 Terraform 실무 실습 스터디입니다.
CloudNet@ Gasida(가시다)이 진행하시며, 책 "Terraform Up & Running"을 기반으로 진행하고 있습니다.
22년 9월 기준 학습 내용입니다. 블로그 이주로 다시 포스트합니다. 

테라폼 스터디 4주차가 지났다. 스터디를 진행하면서 테라폼 기능과 툴을 학습하였고, 예제로 AWS 서비스 3티어 아키텍처를 구성할 정도가 되었다. 그렇다면 EKS 처럼 AWS 서비스가 복잡하게 얽혀있는 것도 테라폼으로 구축이 가능할까? 라는 생각으로 글을 작성한다.

구글에 검색해보니 테라폼을 통해 EKS 구축하는 자료들을 쉽게 접할 수 있었다. 자료를 참고하는 것도 많은 도움이 되었지만, 실제 애플리케이션을 운영한다는 것을 가정하고 예제 코드를 수정하고 추가하는 것이 스스로의 실력 향상에 도움이 된다고 생각하여 가상의 주제를 정하였다.

EKS 구축 목적은 가상의 사내 클라우드 저장소 운영으로 정하였다. 여러 글에 나눠 구축 경험을 공유할 예정이다. 여기서의 클라우드 저장소는 사내에서만 접근가능하며, 관리자만이 외부에서 베스천 서버를 통해 클러스터 접근이 가능하도록 한정하였다.

먼저 구성 아키텍처는 다음과 같다.

t101 아키텍처.png

  • 본 포스터 글에서는 테라폼 모듈들로 AWS 서비스를 구축하는 것까지 진행하였다. 실제 애플리케이션이나 운영 add-on서비스들은 추후 블로그 글을 통해 정리할 예정이다.
  • 구성 아키텍처의 테라폼 코드들은 깃허브 링크를 통해서 확인이 가능하다.

레파지토리의 내용을 보면 EKS 구축에 필요한 AWS 서비스들과 사용 변수들을 파일들을 나눠 구성하였다.

아키텍처2.png

  • c1-version.tf : AWS 프로바이더와 지역을 설정하였다.
  • c2-01,c2-02 : AWS 지역과 EKS 구성시 태그 정보나 지역 정보를 지역 변수로 정의한 파일이다.
  • c3 : VPC 서비스를 구축하기 위한 모듈들을 정리했다.
  • c4 : 베스천 서버를 목적으로 EC2를 구성한 파일이다. 또한, EKS 워크 노드 접속 설정과 외부에서 베스천 서버로 접속하기 위해 설정 모듈들이 정의되어 있다.
  • c5 : EKS 구축을 위한 리소스를 정의했다.
  • ~vars 파일들 : 실제 사용 변수들을 정의했다.

EKS 구축에 사용한 모듈은 테라폼 레지스트리에서 인증된 AWS 모듈과 리소스를 사용했다. 테라폼 레지스트리에는 여러 모듈이 있지만, 외부 노출과 사용 안정성 면에서 공인적으로 인증된 모듈 사용을 적극 추천한다.

공식 인증, 검증 마크 표시

공식 인증, 검증 마크 표시

 옆 마크 표시를 확인하자!

옆 마크 표시를 확인하자!

테라폼 레지스트리에서는 여러 예제를 제공한다. 필자는 테라폼 학습시 예제를 통해 학습한 모듈의 내용을 확인하였고 추가 옵션 필요시 레지스트리 내 변수를 확인하여 옵션을 설정하였다.

ec2_instance 모듈 예제

ec2_instance 모듈 예제

모듈 내 key_name 옵션 확인

모듈 내 key_name 옵션 확인

다음의 글은 필자가 커스터마이징을 진행한 부분과 정리가 필요한 내용들을 작성하였다.

EKS 구성

필자는 사내 클라우드 저장소 구성을 목표로 EKS를 구축했다. 이를 위해 EKS 워크 노드 그룹을 프라이빗 서브넷에 배포하여 VPC 외부에서 접근하지 못하게 구성하였습니다. 또한, API 서버 액세스는 프라이빗 액세스로 설정했다.

EKS 보안 그룹은 크게 3가지로 설정이 가능하다. 클러스터 보안 그룹, 추가 보안그룹(컨트롤 노드 보안 그룹), 워크 노드 보안 그룹으로 나눠지며 세부적으로 포트 제어가 가능하다. 클러스터 보안 그룹은 컨트롤 노드 그룹과 워크 노드 그룹 동시에 적용되는 보안 그룹이다. 해당 보안 그룹을 통해 컨트롤 노드와 워크 노드의 통신이 가능하도록 기본적으로 제공되는 보안 그룹이다. 공식 문서를 통해서는 최소 네트워크 허용 포트를 다음의 그림과 같이 권고한다.

<a href="https://github.com/terraform-aws-modules/terraform-aws-eks/blob/master/docs/network_connectivity.md">https://github.com/terraform-aws-modules/terraform-aws-eks/blob/master/docs/network_connectivity.md</a>

https://github.com/terraform-aws-modules/terraform-aws-eks/blob/master/docs/network_connectivity.md

다만, 이번 포스트에서는 EKS 구축과 테스트 용으로 진행하는 것이 목적이라 클러스터 보안 그룹을 0.0.0.0/0 으로 설정하였다.

노드 그룹 설정

운영 단위로 나눠 워크 노드 그룹을 구축하였다. 각 노드 그룹 분리는 실제 인프라간 영향을 최소화를 목적으로 분리하였다. 애플리케이션 운영을 위한 노드 그룹인 ops 와 클러스터 addon 서비스 운영을 위한 addon 로 구성하였고, 추후 모니터링이나 CI/CD 필요시 노드 그룹을 추가 구성할 예정이다.

관리자 서버 접근 설정

EKS 관리를 위해 베스천 서버를 추가로 구성하였다. 베스천 서버는 외부에서 접근이 가능하도록 구성하였고, 베스천 서버에서 EKS API server 와 워크 노드에 접근이 가능하도록 구성했다.

SSH 아키텍처.png

빨간 선은 관리자가 접근하게 되는 통신 경로이다. 이를 구성하기 위해 3가지 작업을 진행하였다.

  1. 베스천 서버 접근 SSH 설정

    먼저 SSH 접속을 위해 AWS에서 pem key를 발급받아 private-key 폴더에 저장하였다. 이후 테라폼에서 베스천 서버 생성시 테라폼 프로비저너(provisioner)을 통해 로컬과 원격에서 SSH 키를 등록하도록 구성하였다. 프로비저너를 통한 스크립트는 다음과 같다.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    
    # Create a Null Resource and Provisioners
    resource "null_resource" "copy_ec2_keys" {
      depends_on = [module.ec2_public]
      # Connection Block for Provisioners to connect to EC2 Instance
      connection {
        type     = "ssh"
        host     = aws_eip.bastion_eip.public_ip    
        user     = "ec2-user"
        password = ""
        private_key = file("private-key/eks-terraform-key.pem")
      }  
    
    ## File Provisioner: Copies the terraform-key.pem file to /tmp/terraform-key.pem
      provisioner "file" {
        source      = "private-key/eks-terraform-key.pem"
        destination = "/tmp/eks-terraform-key.pem"
      }
    ## Remote Exec Provisioner: Using remote-exec provisioner fix the private key permissions on Bastion Host
      provisioner "remote-exec" {
        inline = [
          "sudo chmod 400 /tmp/eks-terraform-key.pem"
        ]
      }
    ## Local Exec Provisioner:  local-exec provisioner (Creation-Time Provisioner - Triggered during Create Resource)
      provisioner "local-exec" {
        command = "echo VPC created on `date` and VPC ID: ${module.vpc.vpc_id} >> creation-time-vpc-id.txt"
        working_dir = "local-exec-output-files/"
        #on_failure = continue
      }
    }
    
    • resource.connection : EC2 SSH 접속 정보 설정
    • resource.file : EC2 서버 내 파일 저장, 접근 키를 서버내로 복사
    • rresource.remote-exec : EC2 서버 내 스크립트 실행, 접근 키에 대한 권한 설정
    • resource.local-exec : 로컬에서 스크립트 실행, 서버 생성 후 VPC 정보를 local-exec-output-files/ 폴더에 저장
  2. 워크 노드 접근 SSH 설정

    베스천서버에서 워크노드로 접근하기 위해 다음과 같이 테라폼 코드 내에서 앞서 생성한 접근 키 설정하였다.

    1
    2
    3
    
    remote_access {
        ec2_ssh_key = "eks-terraform-key"    
    }
    
  3. API server 접근 설정

    API Server를 접근하기 위해서는 네트워크 확인과 config 키 등록이 필요하다. 먼저 네트워크는 베스천 서버와 EKS 클러스터를 동일 VPC에 생성하였고, 보안 그룹을 0.0.0.0/0 으로 설정하여 접근이 가능하도록 구성하였다. config 등록은 클러스터 구축 이후 테스트 단계에서 진행하겠다.

구현

실제 구축은 테라폼 명령어를 통해 쉽게 구축이 가능하다. 다음의 그림은 테라폼 명령어 세부 동작에 대해 자세히 정리되어 있는 그림이 있어 공유한다.

@StackSimplfy

@StackSimplfy

  • terraform init : 코드에서 정의한 프로바이더를 테라폼 레지스트리에서 확인하고 다운받는다.
  • terraform validate : 테라폼 코드에 대해 유효 테스트를 진행해준다.
  • terraform plan : 테라폼 코드가 어떻게 구현되는지 예측 결과를 보여준다. 예측 결과는 desired state로 정의되어 terraform.tfstate 파일로 저장된다.
  • terraform apply : 구현 단계이다. 앞서 단계에서 생성한 파일을 토대로 실제 서비스를 구축한다.
  • terraform destroy : 삭제 명령어다. 실행시 서비스를 삭제한다.

필자 또한 테라폼 명령어를 통해 EKS를 구축하였다. EKS 구축까지 대략 20분이 소비되었다. 구축이 완료되면 AWS 콘솔로 접속하여 구축한 EKS 정보를 확인할 수 있다.

EKS 구축 확인

EKS 구축 확인

테스트

EKS 구축이 완료되었으면 실제 테스트를 진행해보자. 관리자 입장에서 베스천 서버를 접근하고 클러스터 접근이 가능한지 확인하겠다. 먼저, 베스천서버의 EIP를 확인하고 발급받은 키를 통해 베스천서버로 접속하겠다.

EIP 확인

EIP 확인

1
ssh -i private-key/eks-terraform-key.pem ec2-user@3.35.41.234

베스천 서버에서 일부 워크 노드 접근도 바로 가능하다. 확인을 위해 일부 워크 노드 IP(10.0.1.161)로 SSH 접근해보았다.

베스천 서버에서 워크 노드로 접근

베스천 서버에서 워크 노드로 접근

마지막으로 클러스터 관리를 위해 API Server 접근하기 위해서는 쿠버네티스 명령어 도구인 kubectl 설치와 클러스터에 접근하기 위한 키 등록이 필요하다. kubectl 설치는 링크를 참고했고, EKS 클러스터 접근 키는 AWS 명령어를 통해 kubeconfig를 생성했다.

1
aws eks --region ap-northeast-2 update-kubeconfig --name <cluster-name>

EKS 접근 키 발급시 AWS 인증이 필요하다, 액세스 키와 보안키를 등록하고 EKS 클러스터 접근 키를 발급받자.

kube 접근 토큰 발급

kube 접근 토큰 발급

마지막으로 클러스터 접근 키를 통해 클러스터 노드 정보를 확인하고, 노드그룹 확인을 위해 노드 그룹 라벨을 확인하면 테스트가 완료된다.

노드 정보 확인

노드 정보 확인

끝으로

사족이지만, T101 스터디를 통해서 여러 테라폼 툴을 접해보았다. EKS 구축을 진행하면서 사용했던 툴에 대한 경험을 공유하고자 한다.

  • 테라폼 시각화 툴, pluralith(https://www.pluralith.com/)

    테라폼 시각화 툴이지만, 아직 알파 버전으로 업데이트가 필요하였던 툴이다. 특히 EKS 같이 여러 리소스가 혼합되어 복잡해지면 시각화에 한계가 있었다. 또한, pluralith 서버 내 시각화 실행 메모리가 낮게 측정되어 있었다. 처음 시각화 진행시 버그 이슈로 시각화가 안되어 깃허브 이슈를 통해서 원인을 요청하였고 pluralith 측에서 메모리가 낮게 설정되어 있던 것을 확인하였다. 해당 툴 사용시 시각화 단계에서 버그를 뱉는다면 깃허브 이슈로 문의해보자.

    시각화툴.png

  • 테라폼 비용 계산 툴, infracost(https://www.infracost.io/docs/)

    테라폼에서 정의한 서비스들에 대해 비용을 측정해주는 툴이다. 사용하기 편했고 비용 측정에 있어 한눈에 알아볼 수 있어 유용했다. 아래는 이번 포스트에서 구축한 EKS 운영 비용이다. 206달러라니.. 비용이 상당하다.

    infracost.png

이로써 EKS 구축이 끝났다! 다음 블로그 글에서는 EKS addon를 테라폼으로 구축하는 경험을 공유할 예정이다.