깃 허브에 커밋하기 전 terraform fmt와 tflint 자동화 하기

테라폼의 pre-commit 스크립트를 모은 pre-commit-terraform 에 대해 적은 글입니다
2022.09.23

안녕하세요 클래스메소드의 수재입니다.
테라폼 코드를 작성하다 보면 tflint, tfsec 같은 툴이나 fmt, validate 같은 명령을 사용하곤 합니다.
CI/CD 과정 중 한 부분에서 위의 작업이 자동으로 진행될 수도 있지만 공동 작업을 위해 코드를 깃허브에 커밋하기 전 위와 같은 툴을 적용하여 커밋하고 싶은 경우도 있습니다.
하지만 매번 수동으로 명령어를 입력하기에는 조금 번거롭습니다.
이번글에서는 이러한 작업을 자동으로 실행해주는 pre-commit-terraform을 소개합니다.

pre-commit-terraform 란?

pre-commit 프레임워크와 함께 사용할 수 있는 테라폼 용 git hook 모음입니다.
현재 지원하고 있는 훅 목록은 다음과 같습니다.

pre-commit 프레임워크?

깃 허브에서도 어떠한 이벤트가 발생하였을 때 특정 스크립트를 실행시키는 훅(hook)이 있습니다.
클라이언트 훅, 서버 훅 등이 있지만 상세한 이야기는 넘어가도록 하겠습니다. git hook에 관한 상세한 내용은 이 페이지를 참고해주세요.
다양한 훅 중에서 pre-commit이란 훅이 있으며 pre-commit 프레임워크는 해당 훅에서 사용할 수 있는 스크립트들을 모은 패키지입니다.
이 프레임워크를 활용하면 환경이나 프로젝트마다 동일한 후킹 환경을 유지할 수 있도록 관리가 편해집니다.
이 글에서 소개하는 pre-commit-terraform 은 pre-commit 프레임워크에서 사용할 수 있는 hook 스크립트 모음집입니다.

설치

사전 준비

fmt와 tflint를 실행하기 위한 패키지를 설치합니다.
이 외에 실행할 훅이 있다면 페이지를 확인하여 필요 패키지를 설치합니다.

$ brew install tflint
$ brew install tfsec
$ brew insatall pre-commit

.pre-commit-config.yaml 준비

프로젝트의 루트 디렉터리에 pre-commit의 설정을 기재한 .pre-commit-config.yaml을 저장합니다.1

# .pre-commit-config.yaml
default_stages: [commit]
repos:
    - repo: https://github.com/antonbabenko/pre-commit-terraform
      rev: v1.74.1
      hooks:
          - id: terraform_fmt
          - id: terraform_validate
          - id: terraform_tflint
          - id: terraform_tfsec

파일을 작성했다면 pre-commit-hook 스크립트를 실행합니다.

$ pre-commit install
pre-commit installed at .git/hooks/pre-commit

실행

수동으로 체크

다음 커맨드로 현재 설정을 통과하는지 체크할 수 있습니다.
훅에 fmt를 설정했기 때문에 자동으로 실행됩니다.

$ pre-commit run -a

모든 규칙을 통과한다면 다음과 같은 결과가 표시됩니다.

$ pre-commit run -a
Terraform fmt............................................................Passed
Terraform validate.......................................................Passed
Terraform validate with tflint...........................................Passed
Terraform validate with tfsec............................................Passed

규칙에 위배되는 내용이 있다면 다음과 해당 내용과 같이 결과가 표시됩니다.

...
Result #5 HIGH Load balancer is exposed publicly. 
────────────────────────────────────────────────────────────────────────────────
  01/alb.tf:3
────────────────────────────────────────────────────────────────────────────────
    1    resource "aws_alb" "test" {
    2      name                             = "test-alb"
    3  [   internal                         = false (false)
    4      load_balancer_type               = "application"
    5      security_groups                  = [aws_security_group.publicSG01.id]
    6      subnets                          = [aws_subnet.publicSubnet1.id, aws_subnet.publicSubnet2.id]
    7      enable_cross_zone_load_balancing = true
    8    }
────────────────────────────────────────────────────────────────────────────────
          ID aws-elb-alb-not-public
      Impact The load balancer is exposed on the internet
  Resolution Switch to an internal load balancer or add a tfsec ignore

  More Information
  - https://aquasecurity.github.io/tfsec/v1.28.0/checks/aws/elb/alb-not-public/
  - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb
────────────────────────────────────────────────────────────────────────────────
...
...
results
  ──────────────────────────────────────────
  passed               18
  ignored              0
  critical             3
  high                 13
  medium               2
  low                  4

  18 passed, 22 potential problem(s) detected.

커밋해보기

만약 규칙을 통과하지 못하는 파일이 있다면 커밋이 실행되지 않습니다.

git add ./ec2.tf
$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   ./ec2.tf
$ git commit -m "test"
# 위와 같은 결과 페이지가 출력됩니다(결과는 생략)
$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   ./ec2.tf

파일을 수정한 후 다시 커밋한다면 문제없이 커밋이 됩니다.

정리

이번에는 간단히 fmttflint만을 체크하는 훅을 설정했지만 terraform_docs처럼 편의성을 위한 다른 훅을 같이 설정하는 것도 좋다고 생각되었습니다.
앞으로 pre-commit은 자주 써야겠다고 생각되네요.

긴 글 읽어주셔서 감사합니다.
오탈자 및 내용 피드백은 언제나 환영합니다. must01940 지메일로 연락 주시면 감사합니다!


본 블로그 게시글을 보시고 문의 사항이 있으신 분들은
클래스메소드코리아 (info@classmethod.kr)로 연락 주시면 빠른 시일 내 담당자가 회신 드릴 수 있도록 하겠습니다 !