Terraform에서 관리하는 인프라 배포 자동화

소개



안녕하세요. Wano 주식 회사 엔지니어 nari입니다.
이번에는 GitFlow를 이용하여 CodeBuild에서 실행하는 CI에서 terraform 리소스를 체크/배포하는 구조를 만들었으므로 그 비망록을 남겨두려고 생각합니다.

전체 시스템 이미지





왜 만들려고 생각했는가?


  • 작업 내역을 슬랙에 남겨두고 싶었습니다
  • 프로덕션 환경은 검토 점검 후 그대로 배포되도록하고 싶었습니다.
  • 운영은 다른 팀으로 이어지기 때문에 작업은 가능한 한 간단하게 만들고 싶었습니다

  • 우려점



  • 이전 기사 과 같이, 컴퍼넌트(tfstate)를 분할해 관리하고 있으므로, 전부 일일이 plan이나 apply 하고 있으면 통지도 번잡해져, 실행 시간도 길어질 것 같다
  • CI (테스트)시에 사용하고 있던 build image가 있으므로 심지어 해결할 수 있으면 곧바로 구축할 수 있을 것 같다


  • 어떻게 우려 사항을 개선했는가


  • 아래의 기사를 꽤 참고로 해, 코드의 차이가 있는 디렉토리만으로 plan/apply 를 실행하도록(듯이) 했다
    Terraform 어디서 실행하고 있습니까? - mixi developers - Medium
  • 위의 기사와 다른 것은 build 페이즈로 달리는 run.sh에서의 plan과 apply의 분기를, branch의 이름으로 실현한 곳
  • 브랜치 이름이 plan로 시작하는 경우 plan 그렇지 않으면 apply를 실행합니다.


  • run.sh
    
    #!/bin/sh -xe
    if echo $USER_BRANCH | grep -q 'plan/'; then
      /bin/sh script/tf_ci/plan.sh
    else
      /bin/sh script/tf_ci/apply.sh
    fi
    
  • 명령 조작과 user를 연결하고 싶었기 때문에 message에 user의 항목을 추가 projectURL도 추가
  • 디렉토리가 각 환경을 관리하기 때문에 stage 환경에서는 prod 디렉토리를 무시하고 prod 환경에서는 stage 디렉토리를 무시하는 방식으로 명령을 실행합니다.
  • lambda 리소스는 events 디렉토리 아래에서 apex로 관리되므로 events 디렉토리는 apex 명령을 실행하도록 변경됩니다.

    plan.sh
    
    #!/bin/sh -xe
    if [ $ENV = "stage" ]; then
        export EXCLUDE_ENV="prod"
    elif [ $ENV = "prod" ]; then
        export EXCLUDE_ENV="stage"
    fi
    
    export EXCLUDE_DIRS='^\.|script|server_src|resources|playground|env|dockerfiles|modules|fluentd|nginx|test_ci_conf|tf_ci_conf|events|'$EXCLUDE_ENV
    echo $EXCLUDE_DIRS
    DIRS=$(git --no-pager diff origin/master..HEAD --name-only | xargs -I {} dirname {} | egrep -v "$EXCLUDE_DIRS" | uniq)
    if [ -z "$DIRS" ]; then
      echo "No directories for plan."
      exit 0
    fi
    
    BUILD_URL="https://ap-northeast-1.console.aws.amazon.com/codesuite/codebuild/projects/${USER_CODEBUILD_PROJECT_NAME}/build/${CODEBUILD_BUILD_ID}"
    for dir in $DIRS
    do
      if [[ "`echo $dir | grep events`" ]] ;then
        echo "events"
        (cd $dir && cd ../ && apex deploy)
        (cd $dir && cd ../ && apex infra init -input=false -no-color)
        (cd $dir && cd ../ && apex infra plan -input=false -no-color | tfnotify --config ${REPOSITORY_ROOT}/${ENV}_tfnotify.yaml plan --message "dir : $dir  user : $USER_AUTHOR console : $BUILD_URL")
      else
        (cd $dir && terragrunt init -input=false -no-color)
        (cd $dir && terragrunt plan -input=false -no-color | tfnotify --config ${REPOSITORY_ROOT}/${ENV}_tfnotify.yaml plan --message "dir : $dir  user : $USER_AUTHOR console : $BUILD_URL")
      fi
    done
    
    
    
    

    향후 전망


  • slack에서 CI kick에서 결과 확인까지 완료하고 싶습니다
  • 차이 만 계획이지만, 각 구성 요소에 대한 알림이 끊어지기 때문에이를 통합하고 싶습니다

  • 참고문헌


  • Terraform 어디서 실행하고 있습니까? - mixi developers - Medium
  • 좋은 웹페이지 즐겨찾기