LocalStackに対しTerraformを実行する、最もお手軽な例
目的
本物のAWSに触ることなく、Terraformのお勉強がしたい
そこで、LocalStackによりローカル環境でAWSのモックを立てて、そこをTerraformでいじることにします。AWSアカウントを持っていない、料金が怖い、本物のAWS環境を壊したくない、等々の事情があっても、Terraformを使った気になることができます。
本記事は極力コマンドやYAMLを書いたりせず、GUIポチポチの割合を増やしお手軽さを重視しました。
目標・方法の概要
目標はシンプルに、Amazon S3のバケット my-tf-test-bucket
を作成します。
LocalStackは、ローカル環境でAWSをエミュレートしてくれるものです[1] 。全てのAWSサービス・機能がサポートされているわけではないので注意ですが、基本的な用途では差し支えありません。
TerraformのAWSプロバイダは、もちろん普通は本物のAWSに対して処理するものですが、向き先をLocalStackへと変えることができます。
環境
前提条件 (筆者の環境)
- Windows 11 WSL2 (Ubuntu 20.04)
- Docker Desktop 4.11.0
本記事で導入するもの
- Terraform 1.2.6
- LocalStack 1.0.4.dev
前準備
LocalStack
LocalStackを導入します。大抵の例ではdocker-compose.ymlを書くことになりますが、本記事では超お手軽にLocalStack CockpitによりGUIだけで済ませてしまいます。
ダウンロードはここから。インストール時に警告が出ますが押し通します。
あとは以下の手引きに従います。といっても STARTボタンを押すだけです。[2]
初回は時間がかかります。STARTされたら、Docker Desktopからコンテナ一覧を見に行くと、localstack_main
というのが立ちあがっているのが確認できるはずです。
とりあえずLocalStack単体で触ってみたければ、このコンテナの中に入れば自由に触れます。中では awslocal
を使います。
root@642f2b84e287:/opt/code/localstack# awslocal s3api create-bucket --bucket hoge
{
"Location": "/hoge"
}
root@642f2b84e287:/opt/code/localstack# awslocal s3 ls
2022-08-07 14:55:59 hoge
Terraform
続いてTerraformを導入します。以下はWSL2のUbuntuを開いて、コマンドを入れていきます。
Terraformはバージョンを切り替えることが多いのでtfenvで導入します。
$ git clone --depth=1 https://github.com/tfutils/tfenv.git ~/.tfenv
$ echo 'export PATH=$PATH:$HOME/.tfenv/bin' >> ~/.bashrc
$ source ~/.bashrc
tfenvを使ってTerraformの最新版(本記事では1.2.6)を導入します。裏でunzipが必要らしいので、もしまだなければ事前にインストールします。
$ sudo apt update
$ sudo apt install unzip
$ tfenv install
$ tfenv list
* 1.2.6 (set by /home/hoge/.tfenv/version)
$ tfenv use
Switching default version to v1.2.6
Default version (when not overridden by .terraform-version or TFENV_TERRAFORM_VERSION) is now: 1.2.6
$ terraform -version
Terraform v1.2.6
on linux_amd64
下準備は以上です。
Terraformのコード
以下の記事を参考にしました。[3]
適当な空のディレクトリに main.tf
という1ファイルを作り、書いていきます。ファイル名は何でも可です。
terraform {
backend "local" {}
}
provider "aws" {
region = "ap-northeast-1"
access_key = "hoge"
secret_key = "piyo"
s3_use_path_style = true
skip_credentials_validation = true
skip_metadata_api_check = true
skip_requesting_account_id = true
endpoints {
s3 = "http://localhost:4566"
}
}
resource "aws_s3_bucket" "my-bucket" {
bucket = "my-tf-test-bucket"
}
backend "local"
でローカルに向けています。https://www.terraform.io/language/settings/backends/local
その下がAWSのリージョンや、認証に要するキー設定です。region
はAWSで予約済みの値(us-east-1など)であれば任意に設定できるようです。access_key
やsecret_key
は全くのでたらめな値で良いものの、何でもいいので書く必要はあるようです。
その下の4行がモックとしての動作に必要なフラグの設定です。そしてendpoints
のところでLocalStackに向けています。URLはこの値固定で良いようです。
最後の3行で、作成するS3バケットを定義しています。my-tf-test-bucket
という名前のバケットがこれで作られます。
applyして確認
あとはお決まりのinit - plan - applyの流れです。以下もWSL2です。main.tfがある場所で実行します。
$ terraform init
Initializing the backend...
Successfully configured the backend "local"! Terraform will automatically
use this backend unless the backend configuration changes.
Initializing provider plugins...
- Finding latest version of hashicorp/aws...
- Installing hashicorp/aws v4.25.0...
- Installed hashicorp/aws v4.25.0 (signed by HashiCorp)
(以下略)
$ terraform plan
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the
following symbols:
+ create
Terraform will perform the following actions:
# aws_s3_bucket.my-bucket will be created
+ resource "aws_s3_bucket" "my-bucket" {
+ acceleration_status = (known after apply)
+ acl = (known after apply)
...
(以下略)
$ terraform apply
(中略)
Plan: 1 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
aws_s3_bucket.my-bucket: Creating...
aws_s3_bucket.my-bucket: Creation complete after 1s [id=my-tf-test-bucket]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
本当にバケットが作られたか、LocalStackのコンテナを見に行って確認します。
$ sudo docker exec -it <コンテナID> awslocal s3 ls
2022-08-07 15:04:04 my-tf-test-bucket
-
最近バージョン1.0になったと話題になりました https://www.publickey1.jp/blog/22/awslocalstack10.html ↩︎
-
手引きにある Run configurations の箇所は設定しなくても構いません ↩︎
-
私の記事の上位互換な気がするので、私の記事は意味がない気がしますね。 ↩︎
Discussion