Closed8

Docker + terraform でローカル実行環境。

簡単ですが、一応メモ程度に残しておきます。
実行環境をDocker化するのは、後々のリモートのterraform実行環境と合わせる。
意味や、バージョンの管理 tfenv を使わないでいいのでやる。個人的に楽だからやってみます。

FROM hashicorp/terraform:1.0.9

して、リソースファイルと credentials を共有するだけです。

zsh
# configure
aws configure --profile terraform

# build
docker build --file Dockerfile.dev -t terraform .

# run
docker run --rm -w /terraform -v ${PWD}:/terraform -v ~/.aws:/.aws -it $(docker images terraform -q) \
 -chdir=$DIRECTORY $SUBCOMAND

backend, provider に shared_credentials_file = "/.aws/credentials"を指定してあげます。

terraform {
  backend "s3" {
    shared_credentials_file = "/.aws/credentials"
  }
}

provider "aws" {
  shared_credentials_file = "/.aws/credentials"
}

プロフィールを外部から与えたい場合、外部ファイルのbackend の設定を指定できます。

init の時

zsh
### init
docker run --rm -w /terraform -v ${PWD}:/terraform -v ~/.aws:/.aws -it $(docker images terraform -q) \
 -chdir=$Directory init -backend-config=./.tfenv
.tfenv
profile="terraform"
shared_credentials_file="/.aws/credentials"

AWS CLI を使いたい場合。

FROM hashicorp/terraform:1.0.9

# install coreutils
RUN apk add coreutils

# install glibc
ENV GLIBC_VER=2.34-r0
RUN apk --no-cache add binutils curl && \
curl -sL https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub -o /etc/apk/keys/sgerrand.rsa.pub && \
curl -sLO https://github.com/sgerrand/alpine-pkg-glibc/releases/download/${GLIBC_VER}/glibc-${GLIBC_VER}.apk && \
curl -sLO https://github.com/sgerrand/alpine-pkg-glibc/releases/download/${GLIBC_VER}/glibc-bin-${GLIBC_VER}.apk && \
apk add --no-cache glibc-${GLIBC_VER}.apk glibc-bin-${GLIBC_VER}.apk

# install awscliv2
RUN curl -sL https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip -o awscliv2.zip && \
unzip -q awscliv2.zip && \
aws/install

https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2-linux.html

Makefile

SERVICE := tfcicd
TFVERSION := 1.0.9
.DEFAULT_GOAL := help
PWD = $(shell realpath $(dir $(lastword $(MAKEFILE_LIST))))
DIRS := $(filter-out $(EXCLUDES), $(wildcard ??*))
TFVARS = $(shell realpath --relative-to $(dir) $(PWD)/.tfvars)
TFENV = $(shell realpath --relative-to $(dir) $(PWD)/.tfenv)
IMAGE_NAME := $(SERVICE)-$(TFVERSION)
IMAGE := $(shell docker images $(IMAGE_NAME) -q)

env:
	@echo terraform version $(TFVERSION)
	@echo service version $(SERVICE)
	@echo pwd $(PWD)
	@echo dirs $(DIRS)
	@echo image terraform $(IMAGE)
	@echo image name $(IMAGE_NAME)

dirs: ### list of directory
	@$(foreach val, $(DIRS), /bin/ls -dF $(val);)

help: ### display help
	@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) \
		| sort \
		| awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'

build: ## build terraform image
	@docker build -t $(IMAGE_NAME) . --file Dockerfile.dev

init: ## terraform init
	docker run --rm -w /terraform -v $(PWD):/terraform -v ~/.aws:/.aws -it $(IMAGE) \
	-chdir=$(dir) init -backend-config=$(TFENV)

plan: ## terraform plan
	docker run --rm -w /terraform -v $(PWD):/terraform -v ~/.aws:/.aws -it $(IMAGE) \
	 -chdir=$(dir) plan -var-file=$(TFVARS)

apply: ## terraform apply
	docker run --rm -w /terraform -v $(PWD):/terraform -v ~/.aws:/.aws -it $(IMAGE) \
	 -chdir=$(dir) apply -var-file=$(TFVARS)

destroy: ## terraform destroy
	docker run --rm -w /terraform -v $(PWD):/terraform -v ~/.aws:/.aws -it $(IMAGE) \
	 -chdir=$(dir) destroy -var-file=$(TFVARS)

fmt: ## terraform fmt
	docker run --rm -w /terraform -v $(PWD):/terraform -v ~/.aws:/.aws -it $(IMAGE) \
	 -chdir=$(dir) fmt

Makefile について

変数の初期化方法

:= 右辺を直ぐに展開
= 変数が使われる時に展開

アットマーク(@): アットマークがついたコマンドは、make 実行時にコマンド名を表示しない
@ をつけないタスクは実行時にコマンドを表示してくれるのでオプションをつけたいときは、コマンドをコピペしてからオプションつけています。

Provider の初期化用変数に外部的に値を渡す。
--var-file オプションを使います。.tfvars を参照します。

aws_profile="tfcicd"
aws_region="ap-northeast-1"
shared_credentials_file="/.aws/credentials"
# variables
variable "aws_profile" {
  type = string
}

variable "aws_region" {
  type = string
}

variable "shared_credentials_file" {
  type = string
}

Backend は別で指定(-backend-config) でしないといけないので、
.tfenv を読み込むように別にファイルを用意してます。

profile="tfcicd"
region="ap-northeast-1"
shared_credentials_file="/.aws/credentials"

また、-backend-config や -var-file オプションの後には相対パスでファイルを指定しなければいけなかったのでrealpath を使ってます。

このスクラップは1ヶ月前にクローズされました
ログインするとコメントできます