1. はじめに
下記2つの条件で、TerraformをLocalStackへデプロイする記事が見当たらなかったため、今回の記事を作成しました。
- Docker (+ Docker Compose) だけを使用していること。
- 「Integrations / Terraform / Endpoint Configuration」の
apigateway = "http://localhost:4566"
ようにサービスごとにエンドポイントを指定するのを避けるため、tflocalを使用していること。
1.1. 動作環境
Bashなどのコマンドが利用でき、DockerとDocker Composeがインストール済みの環境で実行できます。
1.2. 各種のバージョン
2022年5月3日時点で動作確認済のバージョンは以下の通りです。
- docker
- Docker version 20.10.0, build 7287ab3
- docker-compose
- docker-compose version 1.26.0, build unknown
- localstack
- 0.14.2
- terraform
- Terraform v1.1.9
- tflocal
- 0.2
- aws-cli
- aws-cli/2.6.1 Python/3.9.11 Linux/4.4.0-210-generic docker/x86_64.amzn.2 prompt/off
2. やってみた
2.1. 最終的なファイル構成
$ tree
.
├── localstack
│ └── docker-compose.yml
├── terraform-example
│ ├── main.tf
│ └── terraform.tfstate
└── tflocal
└── Dockerfile
2.2. LocalStackの起動
2.2.1. LocalStackのdocker-compose.ymlを作成する
$ mkdir localstack
$ vi localstack/docker-compose.yml
version: "3.8"
services:
localstack:
container_name: "${LOCALSTACK_DOCKER_NAME-localstack_main}"
image: localstack/localstack:0.14.2
ports:
- "127.0.0.1:53:53" # only required for Pro (DNS)
- "127.0.0.1:53:53/udp" # only required for Pro (DNS)
- "127.0.0.1:443:443" # only required for Pro (LocalStack HTTPS Edge Proxy)
- "127.0.0.1:4510-4559:4510-4559" # external service port range
- "127.0.0.1:4566:4566" # LocalStack Edge Proxy
environment:
- DEBUG=${DEBUG-}
- DATA_DIR=${DATA_DIR-}
- LAMBDA_EXECUTOR=${LAMBDA_EXECUTOR-}
- LOCALSTACK_API_KEY=${LOCALSTACK_API_KEY-} # only required for Pro
- HOST_TMP_FOLDER=${TMPDIR:-/tmp/}localstack
- DOCKER_HOST=unix:///var/run/docker.sock
volumes:
- "${TMPDIR:-/tmp}/localstack:/tmp/localstack"
- "/var/run/docker.sock:/var/run/docker.sock"
localstackのdocker-compose.ymlを参考にしておりますが、
下記2点を変更しています。
- イメージタグの指定 (
image: localstack/localstack
->image: localstack/localstack:0.14.2
) 。 -
network_mode: bridge
を削除。
2.2.2. LocalStackを起動する
$ docker-compose -f localstack/docker-compose.yml up -d
Creating network "localstack_default" with the default driver
・・・(中略)
Creating localstack_main ... done
2.3. tflocalのセットアップ
2.3.1. tflocalのDockerfileを作成する
$ mkdir tflocal
$ vi tflocal/Dockerfile
FROM python:3.8.13-slim
RUN apt-get update -y && \
apt-get install -y gnupg software-properties-common curl && \
curl -fsSL https://apt.releases.hashicorp.com/gpg | apt-key add - && \
apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main" && \
apt-get update -y && \
apt-get install -y terraform=1.1.9 && \
pip install terraform-local==0.2
WORKDIR /app
ENV LOCALSTACK_HOSTNAME=localstack \
S3_HOSTNAME=localstack \
TF_VAR_s3_use_path_style=true \
AWS_DEFAULT_REGION=ap-northeast-1
ENTRYPOINT ["tflocal"]
ENV
で指定している環境変数はこちらを参考にしています。
2.3.2. tflocalのDockerイメージを作成する
$ docker build -t tflocal:0.2 ./tflocal
Sending build context to Docker daemon 2.56kB
・・・(中略)
Successfully tagged tflocal:0.2
2.3.3. tflocalのaliasを設定する
$ alias tflocal='docker run --rm -it -v "$(pwd):/app" --net=localstack_default tflocal:0.2'
毎回Dockerコマンドを入力するのを省略するために、aliasを設定しています。
-v "$(pwd):/app"
と指定しているため、tflocal
コマンドはTerraform定義のファイルがあるディレクトリで実行することを想定しています。
また、--net=localstack_default
と指定しているため、LocalStackコンテナがlocalstack
で名前解決できるようにしています。
2.4. Terraformサンプルの作成とLocalStackへのデプロイ
2.4.1. Terraform定義ファイルを作成する
$ mkdir terraform-sample
$ cd terraform-sample
$ vi main.tf
variable "s3_use_path_style" {
default = "false"
}
provider "aws" {
s3_use_path_style = var.s3_use_path_style
}
resource "aws_s3_bucket" "sample" {
bucket = "sample-bucket"
}
resource "aws_sns_topic" "sample" {
name = "sample-topic"
}
作成するリソースはS3バケットとSNSトピックの2つです。
variable
のs3_use_path_style
はデフォルトではfalse
になりますが、tflocal
コマンドを実行すると、tflocal/Dockerfile
で設定したTF_VAR_s3_use_path_style=true
でtrue
に上書きされるようにしています。
2.4.2. terraform initする
$ tflocal init
Initializing the backend...
・・・(中略)
commands will detect it and remind you to do so if necessary.
2.4.3. LocalStackにデプロイする
$ tflocal apply -auto-approve
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated
with the following symbols:
・・・(中略)
Plan: 2 to add, 0 to change, 0 to destroy.
aws_sns_topic.sample: Creating...
aws_s3_bucket.sample: Creating...
aws_sns_topic.sample: Creation complete after 1s [id=arn:aws:sns:ap-northeast-1:000000000000:sample-topic]
aws_s3_bucket.sample: Creation complete after 1s [id=sample-bucket]
2.5. LocalStackへデプロイされたリソースの確認
2.5.1. LocalStack用のAWS CLIをaliasで設定する
$ alias awslocal='docker run --rm -it -v $(pwd):/aws --net=localstack_default --env AWS_ACCESS_KEY_ID=dummy --env AWS_SECRET_ACCESS_KEY=dummy --env AWS_DEFAULT_REGION=ap-northeast-1 amazon/aws-cli:2.6.1 --endpoint-url http://localstack:4566'
$ awslocal --version
Unable to find image 'amazon/aws-cli:2.6.1' locally
・・・(中略)
aws-cli/2.6.1 Python/3.9.11 Linux/4.4.0-210-generic docker/x86_64.amzn.2 prompt/off
aliasのawslocal
にAWS CLIのDocker版を諸々のパラメータとともに設定しています。
このaliasも--net=localstack_default
と指定しているため、LocalStackコンテナがlocalstack
で名前解決できるようにしています。
2.5.2. S3バケット一覧を取得する
$ awslocal s3 ls
2022-05-02 13:32:25 sample-bucket
2.5.3. SNSトピック一覧を取得する
$ awslocal sns list-topics
{
"Topics": [
{
"TopicArn": "arn:aws:sns:ap-northeast-1:000000000000:sample-topic"
}
]
}
無事に作成できていそうですね!