ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 06. 테라폼을 팀에서 사용하기
    레거시/Terraform Up and Running 2021. 6. 16. 22:41
    반응형

    이 문서는 책 "테라폼 설치에서 운영까지"을 읽고 작성되었습니다. 최대한 요약해서 책 내용을 최소로 하는데 목표를 두고 있어서, 더 친절하고 정확한 내용을 원하신다면 책을 구매하시는 것을 추천드립니다. => 책 링크

    이번 장에서는 Terraform을 팀에서 사용할 때 좋은 팁들을 알려준다.

    버전 관리

    Github같은 버전 관리 도구를 잘 이용해야 한다. 책 내용을 따르면 레포지토리를 다음과 같이 구성할 수 있겠다.

    • 테라폼 모듈 (gurumee-tf-module)
    • stage 환경 (gurumee-tf-stage)
    • prod 환경 (gurumee-tf-prod)

    음 개인적으로는 이건 큰 서비스에 적합할 것 같고 작은 규모라면 다음과 같이 구성하면 좋을 듯 하다.

    • 테라폼 모듈 (gurumee-tf-module)
    • 인프라 환경 (gurumee-tf-infra)
      • prod
      • stage

    책에서는 다음과 같이 Terraform으로 인프라스트럭처를 관리할 것을 권고한다.

    1. 테라폼 외 방법으로 인프라스트럭처를 변경하지 않는다.
    2. 1:1로 표현한다. 배포한 모든 리소스는 각 환경에 그에 상응하는 코드가 있어야 한다. 모듈을 적극 활용할 것.
    3. master 브랜치는 실제 상용 환경에 배포된 내용을 표현하게끔 만든다.

    검증 자동화

    이는 자동화된 테스트를 구성하는 것을 의미한다. 다음의 단계가 있다.

    1. 코드 준비하기
    2. 테스트 코드 작성하기
    3. 여러 유형의 자동화된 테스트 사용

    먼저 Terraform에서의 자동화된 테스트는 단순히 terraform apply 실행한 다음 배포된 리소스가 예상대로 작동하는지 확인하는 정도이다. 프로그래밍 언어 레벨의 단위 테스트보다 느리고 취약하지만, 운영 중에 문제를 확인하고 변경하는 것보다 훨씬 좋다. 이를 위해서는 많은 부분을 플러그인 형태로 구성하는 것이 중요하다. 이전 장에서, 입력 부부은 variable, 출력 부분을 output을 빗대어 설명한 적이 있다. variable, output은 구성될 인프라스트럭처의 입력/출력을 담당하기 때문에, 단위 테스트 코드를 보다 수월하게 작성하게 해줄 것이다.

     

    위와 같이 코드를 준비했다면, 이제 자신이 자신 있는 언어로 테스트 코드를 작성하면 된다. 책에서는 Ruby로 예제를 다뤘지만 Python, Golang이면 더욱 좋지 않을까? 인프라스트럭처에 필요한 입력을 넣고 원하는 출력이 나오는지 확인하면 된다. 예를 들면 region, s3_bucket_name 등이 있겠다. ec2 인스턴스의 ami_id 같은 것은 가변적이기 때문에 테스트를 안하는 것이 나을 수도 있을 것 같다.

     

    여러 유형의 자동화된 테스트는 보통 단위 테스트, 통합 테스트를 의미한다. 테라폼에서 단위 테스트는 모듈 하나를 테스트하는 것과 같다. 해당 모듈을 성공적으로 배포할 수 있는지, 인스턴스 접속, 데이터 저장이 정상적으로 이루어지는지 확인할 수 있다. 통합 테스트는 여러 모듈이 함께 동작하는지 확인하는 것이다. 모듈 A가 모듈 B에 의존한다면, 모듈 A, 모듈 B 뿐 아니라, 모듈 간 서로 통신이 잘 되는지도 확인해야 한다.

    코드 작성 지침

    일반적으로 코드 작성 지침이라고 하면 다음과 같은 사항이 있다.

    • 문서
    • 파일 레이아웃
    • 스타일 가이드

    책에서는 먼저 문서에 대해서는 Terraform 코드 작성 이전에 README를 만들 것을 권고한다. (모듈 단위마다 필요한듯 하다.) 코드로써 모듈이 어떻게 동작하는지 보일 수 있어야 하며, 예시 정도는 주석으로 처리해서 보여주는 것이 좋다.

     

    파일 레이아웃은 각 환경을 기초로 vpc, mgmt 등 격리 수준에 따라서 분리하는 것이 좋다. 이는 다음 절에서 더 알아보자.

     

    스타일 가이드는 간단하다. terraform fmt로 코드 스타일 가이드를 맞출 수 있다.

    워크플로

    책에서 권고하고 있는 워크플로는 다음과 같다.

    1. terraform plan을 항상 먼저 실행할 것
    2. stage 환경에서 먼저 인프라스트럭처를 적용 후, 검증한다.
    3. 코드 리뷰를 통해 팀원들이 모두 검토한다.
      1. 변경 사항 출력
      2. 계획 출력
      3. 자동화된 테스트 출력
    4. prod 환경에서 인프라스트럭처를 적용한다.

    그럼에도 실제적으로 사용할 때, 문제가 생길 수 있다. 책에서는 충돌을 감안하고 스테이징 환경을 공유 테스트 환경으로 사용해보라 말한다. terraform plan만 잘 실행한다면 문제가 발생하기 전에 충돌을 발견할 수 있다. 거대한 환경에서는 여러 스테이징 환경을 만들어볼 것을 추천한다. 이런 느낌으로

    |- us-east-1
        |- prod
            |- vpc
                |- vars.tf
                |- outputs.tf
                |- main.tf
            |- services
                |- frontend-app
                    |- vars.tf
                    |- outputs.tf
                    |- main.tf
                |- backend-app
                    |- vars.tf
                    |- outputs.tf
                    |- main.tf
            |- data-storage
                |- mysql
                    |- vars.tf
                    |- outputs.tf
                    |- main.tf
                |- redis
                    |- vars.tf
                    |- outputs.tf
                    |- main.tf
        |- ann (사람 이름이 개발자마다의 스테이징 환경을 뜻한다.)
        |- bill
        |- cindy
        |- ...
    |- ap-northeast-2
        |- ...    
    |- ...

    근데 이 경우엔 매우 많은 코드가 중복이 될 것이다. 이 때 해결할 수 있는 한 가지 방법은 모듈도 상용 환경에 맞춰서 구성을 하는 방법이 있다.

    |- modules
        |- vpc
            |- vars.tf
            |- outputs.tf
            |- main.tf
        |- services
            |- frontend-app
                |- vars.tf
                |- outputs.tf
                |- main.tf
            |- backend-app
                |- vars.tf
                |- outputs.tf
                |- main.tf
         |- data-storage
            |- mysql
                |- vars.tf
                |- outputs.tf
                |- main.tf
            |- redis
                |- vars.tf
                |- outputs.tf
                |- main.tf   

    이렇게 맞춰 놓은 경우 .tfvars 파일을 이용해서 라이브 환경을 다음과 같이 구성할 수 있다.

    |- us-east-1
        |- prod
            |- vpc.tfvars
            |- services
                |- frontend-app.tfvars
                |- backend-app.tfvars
            |- data-storage
                |- mysql.tfvars
                |- redis.tfvars
        |- ann (사람 이름이 개발자마다의 스테이징 환경을 뜻한다.)
        |- bill
        |- cindy
        |- ...
    |- ap-northeast-2
        |- ...    
    |- ...

    그리고 .tfvars에 다음과 같이 작성해두면 된다. 아래는 prod/services/frontend-app.tfvars의 코드이다.

    source = "git:git@github.com:foo/modules.git//frontend-app?ref=v0.0.3"
    aws_region = "us-east-1"
    environment_name = "prod"
    frontend_app_instance_type = "m4.large"
    frontend_app_instance_count = 10

    개발자 "ann" 씨의 스테이징 환경에서 코드는 다음과 같아질 것이다.(ann/services/frontend-app.tfvars)

    source = "git:git@github.com:foo/modules.git//frontend-app?ref=v0.0.7"
    aws_region = "us-east-1"
    environment_name = "stage-ann"
    frontend_app_instance_type = "t2.micro"
    frontend_app_instance_count = 2

    음 나름 심오한데 한 번 실무에서 적용해봐야겠다.

Designed by Tistory.