
Moto は LocalStack の内部でも使われている AWS モックツールで,Moto (Server Mode) を使えば http://localhost:5000 で AWS API を呼び出せるようになる👌
Moto を使って AWS アカウントなしで Terraform のチュートリアルを実行できたら勉強するときに便利かも〜?と思って試してみた.今回は Terraform の moved ブロックを学べる「Use configuration to move resources」をテーマに試してみて,最終的に AWS アカウントなしで実行できた❗️
セットアップ
今回試すチュートリアル「Use configuration to move resources」は ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-* というフィルタ条件で AMI を参照する実装になっていて,Moto にプリセットされている AMI にはなかった.しかし Moto には独自の AMI を登録する仕組みがあって amis.json を準備しておく.
[ { "ami_id": "ami-99999999999999999", "state": "available", "public": true, "owner_id": "099720109477", "image_location": "None", "sriov": "simple", "root_device_type": "ebs", "root_device_name": "/dev/sda1", "description": "ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-example", "image_type": "machine", "platform": "windows", "architecture": "x86_64", "name": "ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-example", "virtualization_type": "hvm", "hypervisor": "xen" } ]
詳しくは別の記事にまとめてある📝
そして,以下のように環境変数 MOTO_AMIS_PATH に ~/amis.json を指定して Moto (Server Mode) を起動すれば OK👌
$ docker run --rm -p 5000:5000 \ --name moto \ -v ~/amis.json:/moto/amis.json \ -e MOTO_AMIS_PATH=/moto/amis.json \ motoserver/moto
👾 main.tf
次に GitHub リポジトリ hashicorp-education/learn-terraform-move を clone する.
そして main.tf の provider 部分を以下のように書き換えると Amazon EC2 API に対する操作は Moto を参照するようになる.
provider "aws" { region = var.region default_tags { tags = { hashicorp-learn = "move-config" } } skip_credentials_validation = true skip_requesting_account_id = true endpoints { ec2 = "http://localhost:5000" } }
チュートリアルを実施する
あとは Moto を意識することなくチュートリアル「Use configuration to move resources」を実施できる👌
apply を実行できた❗️(なお Amazon EC2 インスタンスは実際には起動してなく,IP アドレスはダミー値)
$ terraform apply (中略) Apply complete! Resources: 24 added, 0 changed, 0 destroyed. Outputs: public_ip = "54.214.42.251"
moved ブロックで既存リソースを別のモジュールに移動できた❗️
moved { from = module.security_group.aws_security_group.sg_8080 to = module.web_security_group.aws_security_group.this[0] } moved { from = module.security_group.aws_security_group_rule.ingress_rule to = module.web_security_group.aws_security_group_rule.ingress_with_cidr_blocks[0] } moved { from = module.security_group.aws_security_group_rule.egress_rule to = module.web_security_group.aws_security_group_rule.egress_with_cidr_blocks[0] } moved { from = aws_instance.example to = module.ec2_instance.aws_instance.example }
moved ブロックでモジュール名を変更できた❗️
moved { from = module.vpc to = module.learn_vpc }
destroy を実行できた❗️(もはや destroy を実行せず Moto (Server Mode) を停止してしまっても OK💡)
$ terraform destroy (中略) Plan: 0 to add, 0 to change, 24 to destroy. Changes to Outputs: - public_ip = "54.214.42.251" -> null Do you really want to destroy all resources? Terraform will destroy all your managed infrastructure, as shown above. There is no undo. Only 'yes' will be accepted to confirm. Enter a value: yes (中略) Destroy complete! Resources: 24 destroyed.
まとめ
Moto を使って AWS アカウントなしで Terraform のチュートリアルを実行できた👏
Terraform を勉強したいけど,慣れるまでは AWS アカウントを使うことに不安がある...という相談を受けることもあって,Moto を使うという選択肢も紹介できそうだった.LocalStack だと Free プランで使える AWS サービスに制約があるため,Terraform を実行するための AWS API カバレッジという意味では Moto にメリットがあると思う.ちなみに Moto の AWS API カバレッジは以下の implementation_coverage.md にある📝