Terraformはリソースのプロビジョニングツール。Ansibleはサービスの構成管理を行うツール。同じIaCを実現するためのツールでもそれぞれ得意領域と言うのがあって使い分けるのがベストプラクティスな模様なので連携させてみた。
(Ansibleで無理やりリソースのプロビジョニングは可能だしTerraformでもEC2程度ならAMI使ったりユーザデータなんかでサーバ管理もできなくは無さそうって言う思いは少しあるけどこれはバッドプラクティスなのだろうか)
早速サンプル
main.tfを以下のように記載する。
resource "aws_instance" "default" { ami = data.aws_ami.latest-ubuntu.id key_name = var.key_name private_ip = var.private_ip count = 1 security_groups = var.security_groups subnet_id = var.subnet_id instance_type = "t3.medium" tags = { Name = "terraform-ansible" } provisioner "remote-exec" { connection { type = "ssh" user = "ubuntu" host = var.private_ip private_key = file("~/.ssh/${var.key_name}.pem") } inline = [ "sudo apt install -y python" ] } provisioner "local-exec" { command = "ansible-playbook -i hosts ${var.service_name}.yml" } }
resourceの前半あたりは単純にEC2インスタンスを作成してるだけなので省略する。
肝はlocal-exec プロビジョナでローカル環境で実行するコマンドを指定する。Terraformの実行端末上で行うコマンドでTerraformを実行するのがCD用のサーバなどの場合はそこにインストールする必要があるので注意。
開発者がtfをpush -> デプロイサーバがterraformを実行 -> リソース作成後にAnsibleを実行という流れ。
サービスディスカバリどうするの問題
ec2インスタンスを作成からAnsibleを実行するにあたりec2インスタンスのIPを知る必要があるが以下の記事だとlocal_file.tfを動的に生成してhostsを作っている。このやり方だとデプロイサーバとプライベートIPでの到達生が必要になってしまう。そこで使えそうなのがaws cliを使ったSD
動的にinventoryを生成する方法がAnsible公式より提供されている。どうやってサービスを検出するかがリージョンだったりtagで探せたり他にも大量にやり方がある模様。便利だ。。↓サンプル
ec2_architecture ec2_description ec2_dns_name ec2_id ec2_image_id ec2_instance_type ec2_ip_address ec2_kernel ec2_key_name ec2_launch_time ec2_monitored ec2_ownerId ec2_placement ec2_platform ec2_previous_state ec2_private_dns_name ec2_private_ip_address ec2_public_dns_name ec2_ramdisk ec2_region ec2_root_device_name ec2_root_device_type ec2_security_group_ids ec2_security_group_names ec2_spot_instance_request_id ec2_state ec2_state_code ec2_state_reason ec2_status ec2_subnet_id ec2_tag_Name ec2_tenancy ec2_virtualization_type ec2_vpc_id
まとめと感想
Terraformに入門してみて思ったのがAnsibleだけでも実は無理やりplaybookを書けば不要なものであるなと感じだ。ただAnsibleでやるなら数十行の記述が必要なロジックでもTerraformなら数行で済むみたいなのが多くIaCを長く運用するケースであれば使い分けるのが正義になりそう。
Terraformでリソース作ってAnsibleでサーバ設定してCI/CDパイプラインも一緒に自動で作成されるみたいなのが可能な世界。このフロー自体はすごく便利だけど一個一個が難しいので勉強勉強。
(aws cli使ったシェルスクリプトとCloudFormationでのAWS固有の自動化をすっ飛ばしてTerraformに入門したけど順番的にあってるのか不安)
IaCの得意分野別表
Infrastructure as Code の静的テスト戦略 #CODT2020 / Cloud Operator Days Tokyo 2020 - Speaker Deck
オライリーのIaC本にもあるような内容だが上記のスライドがとてもわかりやすかったので図を貼っておきます。TeffaformはGlobal + mutableの分野