Github Action 과 Terraform 사전 커밋 후크의 지속적인 통합

https://www.youtube.com/watch?v=dOCmqgTTBSY&list=PL81sUbsFNc5aQFJNIh74lRJtav5TfjANB&index=18

pre-commit-terraform

terraform_fmt, terraform_validate, terraform_docs, terraform_tflint 등 이용.

https://github.com/antonbabenko/pre-commit-terraform

terraform_fmt : terraform fmt 명령어 (terraform 프로그램 사용)

terraform_validate : terraform validate 명령어 (terraform 프로그램 사용)

terraform_docs : 모듈 문서화 프로그램

terraform_tflint : A Pluggable Terraform Linter

 

사전에 terraform 은 설치가 되어 있어야 하고 간단한 tf 코드 하나 작성해 놓음. (Build infrastructure | Terraform | HashiCorp Developer )

pre-commit-terraform 요약

terraform 및 pre-commit 설치 . git pre-commit 참고. 설치 후 작동 확인을 해봄.

$ pip install pre-commit $ pre-commit sample-config > .pre-commit-config.yaml $ pre-commit install $ pre-commit run -a

작동 확인 후 .pre-commit-config.yaml 에 필요한 설정을 추가하여 사용을 함.

terraform_docs 설치. terraform_docs 에 대한 설정은 .pre-commit-config.yaml 파일에 가능함. (또는 .terraform-docs.yml)

terraform_tflint 설치. terraform_tflint 에 대한 설정은 .tflint.hcl 이용 가능.

pre-commit 설정파일 작성 (.pre-commit-config.yaml)

$ cat .pre-commit-config.yaml repos: - repo: https://github.com/antonbabenko/pre-commit-terraform rev: v1.64.0 # Get the latest from: https://github.com/antonbabenko/pre-commit-terraform/releases hooks: - id: terraform_fmt - id: terraform_validate - id: terraform_docs args: - --hook-config=--path-to-file=README.md # Valid UNIX path. I.e. ../TFDOC.md or docs/README.md etc. - --hook-config=--add-to-existing-file=true # Boolean. true or false - --hook-config=--create-file-if-not-exist=true # Boolean. true or false - id: terraform_tflint

terraform_tflint 에 대한 설정은 .tflint.hcl 에 하고 tflint --init 명령어 실행 필요

$ cat .tflint.hcl #config { # module = false # disabled_by_default = true #} plugin "aws" { enabled = true version = "0.12.0" source = "github.com/terraform-linters/tflint-ruleset-aws" } rule "terraform_comment_syntax" { enabled = true } rule "terraform_deprecated_index" { enabled = true } rule "terraform_deprecated_interpolation" { enabled = true } rule "terraform_documented_outputs" { enabled = true } rule "terraform_documented_variables" { enabled = true } rule "terraform_module_pinned_source" { enabled = true } rule "terraform_module_version" { enabled = true } rule "terraform_naming_convention" { enabled = true } rule "terraform_required_providers" { enabled = true } rule "terraform_required_version" { enabled = true } rule "terraform_standard_module_structure" { enabled = true } rule "terraform_typed_variables" { enabled = true } rule "terraform_unused_declarations" { enabled = true } rule "terraform_unused_required_providers" { enabled = true } rule "terraform_workspace_remote" { enabled = true } $ tflint --init

terraform_fmt, terraform_validate

terraform 바이너리만 있으면 됨.

pre-commit 실행

mac 에서 실행시

mac에서는 terraform_validate hook을 위해서 coreutils 를 설치해야 함. 안그러면 realpath 가 없다고 나옴.

coreutils is required for terraform_validate hook on MacOS (due to use of realpath).

그런데 mac에서는 아래와 같은 에러가 나오면서 실행이 안된다.

_common.sh 30행을 수동으로 실행시키면 문제는 없는데 hook에서 실행시는 에러가 난다.

30 declare -g -a ARGS=() HOOK_CONFIG=() FILES=()

이 부분은 bash 의 버전과 연관이 있는 듯 하다. 기본 들어있는 bash를 사용할 때 위 에러가 발생을 했다.

아래 issue를 보면 mac에 기본 들어있는 bash 버전과의 문제로 보인다. 임시 해결책으로 brew 로 bash를 설치해주면 5.1.16의 bash에서는 해당 에러가 나지 않았다. (path)

https://github.com/antonbabenko/pre-commit-terraform/issues/337

 

Ubuntu 에서는 실행에 문제가 없었음.

terraform_docs

모듈 문서화 프로그램. terraform-docs 설치 필요함. https://github.com/terraform-docs/terraform-docs

Introduction

linux 설치

mac 설치

여러가지 포맷이 있지만 markdown table 을 가장 많이 사용함.

terraform-docs 에 대한 github actions : https://github.com/terraform-docs/gh-actions

 

pre-commit hook에서 몇가지 설정을 할 수 있고 .terraform-docs.yml 파일에 설정을 할 수도 있음

tflint

https://github.com/terraform-linters/tflint

TFLint는 프레임워크이며 각 기능은 플러그인으로 제공되며 주요 기능은 다음과 같습니다.

  • 주요 클라우드 공급자(AWS/Azure/GCP)에 대해 가능한 오류(예: 잘못된 인스턴스 유형)를 찾습니다.

  • 더 이상 사용되지 않는 구문, 사용되지 않는 선언에 대해 경고합니다.

  • 모범 사례, 명명 규칙을 시행합니다.

linux install : /usr/local/bin/tflint

mac install

AWS/Azure/GCP provider를 사용하는 경우 플러그인을 설치하고 사용을 해야 함.

https://github.com/terraform-linters/tflint-ruleset-aws

.tflint.hcl 파일에 다음 내용을 추가하고 tflint --init 명령을 실행함.

TFLint는 기본적으로 현재 디렉터리 아래에 있는 파일을 검사합니다.

잘못된 instance type을 넣는 경우 tflint 실행시 에러가 남.

Terraform Language 에 대한 룰 : 대부분 활성화를 해서 사용하는 것이 좋은 내용임. https://github.com/terraform-linters/tflint/tree/master/docs/rules

Rule

Description

Enabled

Rule

Description

Enabled

terraform_comment_syntax

# 대신 // 형태의 주석을 허용하지 않음

 

terraform_deprecated_index

Disallow legacy dot index syntax

레거시 dot(.) 인덱스 구문 허용 안 함

 

terraform_deprecated_interpolation

더 이상 사용되지 않는(0.11 스타일) interpolation 허용 안 함

terraform_documented_outputs

Disallow output declarations without description

output설명이 없는 선언을 허용 하지 않음

 

terraform_documented_variables

Disallow variable declarations without description

variable설명이 없는 선언을 허용 하지 않음

 

terraform_module_pinned_source

Disallow specifying a git or mercurial repository as a module source without pinning to a version

버전에 고정하지 않고 git 또는 mercurial 저장소를 모듈 소스로 지정하는 것을 허용하지 않습니다.

terraform_module_version

Checks that Terraform modules sourced from a registry specify a version

레지스트리에서 가져온 Terraform 모듈이 버전을 지정하는지 확인합니다.

terraform_naming_convention

Enforces naming conventions for resources, data sources, etc

리소스, 데이터 소스 등에 대한 명명 규칙을 적용합니다.

 

terraform_required_providers

Require that all providers have version constraints through required_providers

모든 공급자에게 required_providers를 통한 버전 제약 조건이 있어야 합니다.

 

terraform_required_version

Disallow terraform declarations without require_version

terraformrequire_version이 없는 선언 허용 안 함

 

terraform_standard_module_structure

Ensure that a module complies with the Terraform Standard Module Structure

모듈이 Terraform 표준 모듈 구조를 준수하는지 확인

 

terraform_typed_variables

Disallow variable declarations without type

variable유형이 없는 선언 허용 안 함

 

terraform_unused_declarations

Disallow variables, data sources, and locals that are declared but never used

선언되었지만 사용되지 않은 변수, 데이터 소스 및 지역을 허용하지 않습니다.

 

terraform_unused_required_providers

Check that all required_providers are used in the module

required_providers모듈에서 모두 사용되었는지 확인

 

terraform_workspace_remote

terraform.workspace should not be used with a "remote" backend with remote execution

terraform.workspace원격 실행이 있는 "원격" 백엔드와 함께 사용하면 안 됩니다. → 내용이 잘 이해가지는 않음.

aws rule : 기본으로 활성화되어 있는 룰은 그대로 사용을 하는 것이 좋을 듯 함. Deep으로 표시된 부분은 설정에서 “Deep Checking”을 활성화한 경우에만 사용됨.

https://github.com/terraform-linters/tflint-ruleset-aws/blob/master/docs/rules/README.md

예를 들어 아래와 같이 ec2 instance 에 유효하지 않은 instance type을 지정한 경우 tflint에서는 이런 에러를 미리 발견을 함. terraform validate나 terraform plan 에서는 이런 경우의 에러는 찾지 못하고 terraform apply를 할 때 에러가 생길 것임.

 

Terraform linter github actions 도 있음.

https://github.com/terraform-linters/setup-tflint

Automation Tool

  • 정적코드분석 : 보안체크 terraform 보안코드 분석

    • TFsec : vscode extention , cli

    • Terrascan

    • 위와 같은 프로그램을 사용하면 terraform 코드를 짜면서 보안체크를 할 수 있지만 체크하는 룰이 제한되어 있다. 그래서 AWS 리소스를 만든 후에 AWS 컴플라이언스, 보안체크하는 프로그램을 이용하여 체크를 해볼 것을 추천한다. AWS Compliance Scanning Tool

  • 문서자동화

    • DocToc : 마크다운 파일에 대한 목차를 생성. terraform과는 상관없음.

    • Editorconfig : vscode extention. 코드베이스에서 코드스타일을 일관되게 유지. terraform과는 상관없음. terraform 쓸 때는 terraform fmt 를 이용하면 될듯.

Github Actions