infracost 란?
Infracost는 Terraform 코드 변경 사항을 스캔하여 리소스가 생성되기 전에 간단하게 예정치를 확인할 수 있는 솔루션입니다.
infracost는 community버전을 무료로 제공해주고 있으며 Cloud 버전은 유료 버전으로 비용 대시보드, 알람, 레포트 등등 추가 서비스를 제공해주고 있습니다. 비용은 별도 연락을 요청하는것 보니 list price는 아닌것 같습니다.
infracost 구성해보기
infracost는 atlantis와 찰떡궁합인 서비스 입니다. atlantis 를 사용하여 terraform plan을 할때 3가지 방법을 제공합니다.
- append-to-atlantis-comments
- combined-infracost-comment
- multiple-infracost-comments
이 세가지 방법중에 저는 첫번째 방법으로 아래와 같이 구축해보았습니다.
append-to-atlantis-comments
해당 방법은 Infracost를 Atlantis와 함께 사용할 수 있는 방법을 보여줍니다. 아래 예시처럼 Infracost 예상 비용은 Atlantis 출력 하단에 추가됩니다.
- infracost 다운로드 및 설치
# Downloads the CLI based on your OS/arch and puts it in /usr/local/bin
curl -fsSL https://raw.githubusercontent.com/infracost/infracost/master/scripts/install.sh | sh
infracost --version # Should show 0.10.13
- infracost API key 획득 하기
infracost 설치 이후 API key를 획득해야 합니다. 키 획득을 위해 아래와 같이 명령어를 입력하면 로그인을 할 수 있는 url이 주어집니다.
infracost auth login
아래와 같이 출력되며 https://dashboard.infracost.io....
와 같이 생성된 url에 접근하여 google 또는 github 계정으로 로그인합니다.
We're redirecting you to our log in page, please complete that,
and return here to continue using Infracost.
If the redirect doesn't work, use this URL:
https://dashboard.infracost.io/login?cli_port=xxxx&cli_state=xxxxxxx&cli_version=v0.10.12&os=linux&utm_source=cli
Waiting...
xdg-open: no method available for opening 'https://dashboard.infracost.io/login?cli_port=38846&cli_state=xxxxx&cli_version=v0.10.12&os=linux&utm_source=cli'
로그인 이후에 1번째 2번째 단계만 진행하면 api key가 자동으로 로컬 pc 클립보드에 저장이 됩니다. 혹시 모르니 메모장같은 곳에 저장해두고 infracost가 설치되어있는 곳에 환경변수로 아래와 같이 등록합니다.
export INFRACOST_API_KEY=<your-infracost-api-token>
- atlantis 의 repos.yaml 수정
repos:
- id: /.*/
workflow: terraform-infracost
workflows:
terraform-infracost:
plan:
steps:
- init
- plan
- show # this writes the plan JSON to $SHOWFILE
- env:
name: INFRACOST_OUTPUT
command: 'echo "/tmp/$BASE_REPO_OWNER-$BASE_REPO_NAME-$PULL_NUM-$WORKSPACE-${REPO_REL_DIR//\//-}-infracost.json"'
# Run Infracost breakdown and save to a tempfile, namespaced by this project, PR, workspace and dir
- run: |
infracost breakdown --path=$SHOWFILE \
--format=json \
--log-level=info \
--out-file=$INFRACOST_OUTPUT \
--project-name=$REPO_REL_DIR
- run: |
# Read the breakdown JSON and get costs using jq.
# Note jq comes as standard as part of infracost-atlantis Docker images. If you are using the base atlantis
# image you'll need to manually install jq. e.g:
# curl https://stedolan.github.io/jq/download/linux64/jq > /usr/local/bin/jq; chmod +x /usr/local/bin/jq
past_total_monthly_cost=$(cat $INFRACOST_OUTPUT | jq -r "(.pastTotalMonthlyCost // 0) | tonumber")
total_monthly_cost=$(cat $INFRACOST_OUTPUT | jq -r "(.totalMonthlyCost // 0) | tonumber")
diff_total_monthly_cost=$(cat $INFRACOST_OUTPUT | jq -r "(.diffTotalMonthlyCost // 0) | tonumber")
currency=$(cat $INFRACOST_OUTPUT | jq -r '.currency | select (.!=null)')
if [ "$currency" = "" ] || [ "$currency" = "USD" ]; then
currency="$"
elif [ "$currency" = "EUR" ]; then
currency="€"
elif [ "$currency" = "GBP" ]; then
currency="£"
else
currency="$currency " # Space is needed so output is "INR 123"
fi
# Run infracost output to get the diff output
diff_output=$(infracost output --no-color --format diff --show-skipped --path=$INFRACOST_OUTPUT)
change_symbol () {
local old=$1
local new=$2
local change_symbol="+"
if [ "$(echo "$new < $old" | bc -l)" = 1 ]; then
change_symbol=""
fi
printf "%s" "$change_symbol"
}
percent_display () {
local old=$1
local new=$2
local percent
local sym
percent=$(calculate_percentage "$old" "$new")
sym=$(change_symbol "$old" "$new")
local s=""
if [ -n "$percent" ]; then
s="$(printf "%.0f" "$percent")"
s=" ($sym$s%%)"
fi
printf "%s" "$s"
}
calculate_percentage () {
local old=$1
local new=$2
local percent=""
# If both old and new costs are greater than 0
if [ "$(echo "$old > 0" | bc -l)" = 1 ] && [ "$(echo "$new > 0" | bc -l)" = 1 ]; then
percent="$(echo "scale=6; $new / $old * 100 - 100" | bc)"
fi
# If both old and new costs are less than or equal to 0
if [ "$(echo "$old <= 0" | bc -l)" = 1 ] && [ "$(echo "$new <= 0" | bc -l)" = 1 ]; then
percent="0"
fi
printf "%s" "$percent"
}
format_cost () {
cost=$1
if [ -z "$cost" ] || [ "$cost" = "null" ]; then
echo "-"
elif [ "$(echo "$cost < 100" | bc -l)" = 1 ]; then
printf "$currency%0.2f" "$cost"
else
printf "$currency%0.0f" "$cost"
fi
}
percent=$(percent_display "$past_total_monthly_cost" "$total_monthly_cost" | sed "s/%/%%/g")
change_word="increase"
if [ "$(echo "$past_total_monthly_cost > $total_monthly_cost" | bc -l)" = 1 ]; then
change_word="decrease"
fi
msg="##### Infracost estimate #####"
msg="${msg}\n\n"
msg="${msg}Monthly cost will $change_word by $(format_cost $diff_total_monthly_cost)$percent\n"
msg="${msg}\n"
msg="${msg}Previous monthly cost: $(format_cost $past_total_monthly_cost)\n"
msg="${msg}New monthly cost: $(format_cost $total_monthly_cost)\n"
msg="${msg}\n"
msg="${msg}Infracost output:\n"
msg="${msg}\n"
msg="${msg}$(echo "$diff_output" | sed 's/^/ /' | sed "s/%/%%/g")\n"
printf "$msg"
만약 terragrunt를 같이 사용하고 계시면 아래 부분을 수정해야합니다. 아래 init, plan, show는 atlantis 내부에 built in 되어있는 명령어로 일부 옵션이 생략되어있기 때문입니다.
steps:
- init
- plan
- show # this writes the plan JSON to $SHOWFILE
아래와 같이 수정해주시면 됩니다.
steps:
- run: terragrunt init -no-color
- run: terragrunt plan -input=false -out=$PLANFILE -no-color
- run: terragrunt show -json $PLANFILE > $SHOWFILE -no-color
자 그럼 git pr을 올려서 atlantis plan을 해볼까요? 짜잔~ 아래와 같이 예상금액이 추가 ouput으로 표시됩니다.
참고
- infracost공홈 : https://www.infracost.io/docs/#quick-start
- infracost github : https://github.com/infracost/infracost-atlantis
'IT > DevOps' 카테고리의 다른 글
Gradle빌드 설정파일 설명 (build.gradle / settings.gradle / gradle.properties) (0) | 2024.01.03 |
---|---|
[Opensearch] time graph가 나오지 않을때 (API로 인덱스 패턴 time filed 지정하여 생성하기) (0) | 2024.01.02 |
[DevOps] kpexec 사용 법 (pod를 admin권한으로 접속하기) (0) | 2023.08.20 |
[DevOps] k8s sniff 를 사용한 pod의 tcp 패킷 캡처 (0) | 2023.08.20 |
[DevOps] k9s -c pod 컬럼 설명 (0) | 2023.02.24 |