Overview
OpenTofu을 이해하고, Terraform Runner인 Atlantis와 연동하여 구성 동작을 확인하겠습니다.
OpenTofu ?
OpenTofu의 배경은 Terraform의 라이센스 변경과 관련이 있습니다. Terraform은 오랫동안 오픈 소스로 제공되었으나, 2023년 8월에 HashiCorp가 Terraform을 포함한 여러 제품의 라이센스를 변경하면서 더 제한적인 Business Source License(BSL)를 도입했습니다. BSL 도입에 따라 Terraform을 서비스 형태로 제공하거나, 상업적 목적으로 대규모로 사용하는 경우 라이센스 비용을 지불해야 합니다.
(출처: GeekNews)
이에 따라 오픈소스 진영에서는 Terraform을 포크하여 만든 도구로 OpenTofu를 출시했습니다.
사용 방법이나 특징들은 Terraform과 거의 비슷합니다. Graph를 통해 구성도를 확인하면 Terraform과 명령어만 다를 뿐 사용 동작은 똑같습니다.
OpenTofu 설치
Environment managers Tools 인 tenv를 통해 쉽게 설치가 가능합니다. (tfenv 아닙니다)
# Mac 기준 tfevn가 있으면 설치 에러로 삭제
brew remove tfenv
# tenv 설치
brew install tenv
tenv -h
# 자동 완성 설정
tenv completion zsh > ~/.tenv.completion.zsh
echo "source '~/.tenv.completion.zsh'" >> ~/.zshrc
# OpenTofu 설치
tenv tofu list-remote
tenv tofu install 1.7.3
tenv tofu use 1.7.3
# tofu 사용
tofu -h
- Terraform과 사용 커맨드가 거의 비슷합니다.
Terraform to OpenTofu
이전 테라폼으로 구성한 EKS 환경을 OpenTofu를 통해 구성하겠습니다.
EKS 환경은 밑 프로젝트을 참고하여 구성하였습니다.
# terraform version install
tenv tf list-remote
tenv tf install 1.8.5
tenv tf use 1.8.5
terraform -h
# 매개 변수 수정
git clone https://github.com/Dhruvin4530/EKS-managed-node-group-Terraform.git
cd EKS-managed-node-group-Terraform
vi terraform.tfvars
----
cluster_name = "prod-cluster"
instance_count = 2
instance_size = "t3.micro"
region = "ap-northeast-2"
cluster_version = "1.28"
ami_id = "ami-085b4285663443932" # 1.27 x86
vpc-cni-version = "v1.14.0-eksbuild.3" # 1.27
kube-proxy-version = "v1.27.4-eksbuild.2" # 1.27
terraform init
terraform apply -auto-approve
- tfenv를 제거하였기에 tenv를 통해 테라폼을 설치후 EKS 환경을 구성하겠습니다.
Terraform 으로 구성한 인프라를 OpenTofu로 마이그레이션하겠습니다.
마이그레이션 과정은 OpenTofu 공식문서를 참고하였습니다.
- Terraform 버전 변환 : 1.8.2 이상의 테라폼 버전에서만 호환이 가능합니다. 그 아래의 경우 버전을 업그레이드해야 합니다.
- Terraform 상태 최신화 : Plan을 통해 변경사항이 있는 지 확인해주세요.
- OpenTofu 버전 확인 : Opentofu 버전이 1.7.1 이상인지 버전 확인이 필요합니다.
- Statefile 백업 : tofu로 변환 전 테라폼 Statefile 백업이 필요합니다.
- 코드 변경 : OpenTofu으로 변환은 아래의 코드 변경이 필요합니다.
EKS 환경에서는 위 내용에 대한 내용이 없으므로 생략합니다.
- OpenTofu 초기화
tofu init
- Opentofu에 대한 프로바이더 확인하면 terraform과 동일한 provider를 사용함을 알 수 있습니다. terraform_aws_provider 는 MIT 라이센스로 opentofu에서도 그대로 사용이 가능합니다.
6. OpenTofu Plan을 통한 변경 사항 확인
tofu plan
...
7. Opentofu apply
tofu apply
Apply를 진행하면 결과가 refresh가 되면서 statefile이 생성됩니다.
statefile은 테라폼과 같이 terraform.state 로 생성됩니다.
마이그레이션 과정 중 statefile이 덮어쓰기가 되며, 문제가 있을 시 롤백이 필요하기에 반드시 사전 백업이 필요합니다.
Atlantis 를 통한 CI 구성
OpenSource CI 툴인 Altantis에서 OpenTofu를 사용할 수 있도록 구성하겠습니다. Atlantis는 위 Opentofu로 구성한 EKS 환경에서 배포하겠습니다. 배포 구성은 아래 문서를 참고하였습니다.
Atlantis Helm 배포 전 EKS 에 다음의 addon 구성이 필요합니다.
- aws load balancer controller
- external dns
- ebs-csi driver
helm repo add runatlantis https://runatlantis.github.io/helm-charts
이전 필자의 블로그 글 스크립트에서 Opentofu를 사용하기 위한 플러그인을 추가해주세요.
vi values-atlantis.yaml
---------------
# add atlantis public domain for :
atlantisUrl: http://horang.link
# Add your terraform repository:
##in my case I'm using the same repository
orgWhitelist: github.com/HanHoRang31/t101-cicd
# If using GitHub, specify like the following:
github:
user: t****66@gmail.com
token: *******************
secret: *******************
# -- Optionally specify an username and a password for basic authentication.
basicAuth:
username: "admin"
password: "1234"
ingress:
annotations:
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}, {"HTTP":80}]'
alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:ap-northeast-2:*******
alb.ingress.kubernetes.io/success-codes: 200-399
alb.ingress.kubernetes.io/group.name: "atlantis"
hosts:
- host: atlantis.horang.link
service: atlantis
paths: ["/*"]
#Specify AWS credentials to be mapped to ~/.aws inside the atlantis container
# to allow atlantis container access AWS:
aws:
credentials: |
[default]
aws_access_key_id = A***************K
aws_secret_access_key = 0********************
region = ap-northeast-2
config: |
[profile a_role_to_assume]
role_arn = arn:aws:iam::**************:role/AmazonEKS_EBS_CSI_DriverRole
source_profile = default
#defaultTFVersion set the default terraform version to be used in atlantis server
## it should be the same as your terraform version to overcome any terraform lock status
defaultTFVersion: 1.8.5
initConfig:
enabled: true
image: alpine:latest
imagePullPolicy: IfNotPresent
# sharedDir is set as env var INIT_SHARED_DIR
sharedDir: /plugins
workDir: /tmp
sizeLimit: 250Mi
# example of how the script can be configured to install tools/providers required by the atlantis pod
script: |
#!/bin/sh
set -eoux pipefail
# terragrunt
TG_VERSION="0.55.10"
TG_SHA256_SUM="1ad609399352348a41bb5ea96fdff5c7a18ac223742f60603a557a54fc8c6cff"
TG_FILE="${INIT_SHARED_DIR}/terragrunt"
wget https://github.com/gruntwork-io/terragrunt/releases/download/v${TG_VERSION}/terragrunt_linux_amd64 -O "${TG_FILE}"
echo "${TG_SHA256_SUM} ${TG_FILE}" | sha256sum -c
chmod 755 "${TG_FILE}"
terragrunt -v
# OpenTofu
TF_VERSION="1.6.2"
TF_FILE="${INIT_SHARED_DIR}/tofu"
wget https://github.com/opentofu/opentofu/releases/download/v${TF_VERSION}/tofu_${TF_VERSION}_linux_amd64.zip
unzip tofu_${TF_VERSION}_linux_amd64.zip
mv tofu ${INIT_SHARED_DIR}
chmod 755 "${TF_FILE}"
tofu -v
environment:
ATLANTIS_TF_DOWNLOAD: false
TERRAGRUNT_TFPATH: /plugins/tofu
repoConfig: |
---
repos:
- id: /.*/
apply_requirements: [approved, mergeable]
allow_custom_workflows: true
allowed_overrides: [workflow, apply_requirements, delete_source_branch_on_merge]
- 아틀란티스를 사용하기 전 Github Repo 구성과 Webhook 설정이 필요합니다. 참고
위 스크립트를 기반으로 atlantis를 배포합니다.
kubectl create ns atlantis
helm install atlantis runatlantis/atlantis -f values-atlantis.yaml -n atlantis
깃허브 웹 훅 연동도 확인해야합니다.
Alantis & OpenTofu 동작 확인
예제 파일을 배포하여 IaC CI 동작을 확인하겠습니다.
코드 관리 루트 디렉토리에 opentofu를 사용하기 위한 atlantis 정의 파일을 추가합니다.
vi atlantis.yaml
---
version: 3
automerge: true
parallel_plan: true
parallel_apply: false
projects:
- name: terragrunt
dir: .
workspace: terragrunt
delete_source_branch_on_merge: true
autoplan:
enabled: true
when_modified: ["*.hcl", "*.tf"]
apply_requirements: [mergeable, approved]
workflow: terragrunt
workflows:
terragrunt:
plan:
steps:
- env:
name: TF_IN_AUTOMATION
value: 'true'
- run: find . -name '.terragrunt-cache' | xargs rm -rf
- run: terragrunt init -reconfigure
- run:
command: terragrunt plan -input=false -out=$PLANFILE
output: strip_refreshing
apply:
steps:
- run: terragrunt apply $PLANFILE
위 스크립트에서 opentofu가 아닌 terragrunt를 통해 명령어가 수행됩니다.
이는 atlantis에서 opentofu를 아직 지원하지 않기 때문입니다.
terragrunt는 terraform과 opentofu를 둘 다 지원합니다.
Terragrunt만 있고 opentofu에 대한 명령어가 없다구요?
위 Atlantis helm 차트 배포 시 Terragrunt 내부 동작을 opentofu로 설정하였습니다.
environment:
ATLANTIS_TF_DOWNLOAD: false
TERRAGRUNT_TFPATH: /plugins/tofu
Atlantis 설정이 끝났으면, 테스트를 위한 예제 파일을 생성하고 terragrunt 정의 파일을 다음과 같이 생성합니다.
echo 'resource "null_resource" "example" {}' > main.tf
vi terragrunt.hcl
--
terraform {
source = "./"
}
~
tree .
.
├── README.md
├── atlantis.yaml
├── main.tf
└── terragrunt.hcl
git checkout -b opentofu
git add . && git commit -m "test opentofu" && git push origin opentofu
이제 깃허브에서 main으로 PR을 요청하면 정상적으로 opentofu로 프로비저닝되는 것을 확인할 수 있습니다.
'Cloud Tech' 카테고리의 다른 글
쿠버네티스 네트워크이해하기(Kind, Pause, Ephemeral Container, FlannelCNI) (0) | 2024.09.06 |
---|---|
컨테이너 구성 이해와 도커 취약점 점검하기 (0) | 2024.08.30 |
Kafka on EKS (0) | 2024.07.27 |
EKS에서 Atlantis 구성하기 (0) | 2024.07.14 |
EKS Karpenter로 부드럽게 Migration 하기 (2) | 2024.07.06 |