地方エンジニアの学習日記

興味ある技術の雑なメモだったりを書いてくブログ。たまに日記とガジェット紹介。

【Terraform】TerraformからAnsible

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

docs.ansible.com

動的に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の分野

f:id:ryuichi1208:20201107232209p:plain