リモート開発メインのソフトウェア開発企業のエンジニアブログです

AnsibleのEC2インベントリ機能を使って自動でIPアドレスを割り当てる

Ansibleのec2.pyを使ったインベントリが出来なくなったということで、その改修作業について書こうと思ったのですが、これについては良くまとまっている記事が既にありますので、こちらを参照で済ませたいと思います。

https://zenn.dev/ohsawa0515/articles/enable-ec2-dynamic-inventory-by-ansible

今回は上記の記事では紹介されていない動的な手法について紹介したいと思います。具体的にはDEV, STG, PROD環境でデプロイ先のEC2が違う場合のymlファイルの書き方についてです。

ディレクトリ構成

ファイルの説明を簡単にすると、ansible.cfgがansibleの設定ファイルで、batch.ymlがansible-playbook実行時のエントリポイントで、aws_ec2.ymlがインベントリの要となるファイルです。

aws_ec2.yml は inventory 配下に置いてますが、場所はお好きな場所で!

my-project
    ├ ansible
        ├ ansible.cfg
        ├ batch.yml
        └ inventory
            └ aws_ec2.yml

ansible.cfg

インベントリファイルのパスを書きます。2通りの書き方が出来るようです。お好きな方で!

[defaults]
inventory = ./inventory/aws_ec2.yml

または

[defaults]
inventory = ./inventory

batch.yml

ansibleコマンドを実行するときに指定するymlファイルです。環境によってAWSアカウント自体を分けているため、環境変数で切り替えています。

以下コマンド例です。

$ AWS_PROFILE=my-project-dev ansible-playbook batch.yml

$ AWS_PROFILE=my-project-stg ansible-playbook batch.yml

$ AWS_PROFILE=my-project-prod ansible-playbook batch.yml

batch.yml の中身ですが、もう少しまとまりの良い書き方があるかもしれませんが、環境ごとに定義を分けています。

- hosts: dev_batch
  vars:
    ansible_user: ec2-user
    stage: dev
  become: yes
  roles:
    - common
    - batch
  vars_files:
    - stage_vars/dev.yml

- hosts: stg_batch
  vars:
    ansible_user: ec2-user
    stage: stg
  become: yes
  roles:
    - common
    - batch
  vars_files:
    - stage_vars/stg.yml

- hosts: prod_batch
  vars:
    ansible_user: ec2-user
    stage: prod
  become: yes
  roles:
    - common
    - batch
  vars_files:
    - stage_vars/prod.yml

この batch.yml が読み込まれただけで、インベントリが機能していない場合、上記の「hosts:」に指定している dev_batch, stg_batch, prod_batch にはまだIPアドレスが入っていない状態です。

IPアドレスを取得するには、以下のように aws_ec2.yml を記述します。

aws_ec2.yml

DEV, STG, PROD環境ごとに別AWSアカウントに配置されている EC2 のバッチサーバーですが、それぞれは環境に応じてタグ名を変えているので、それを条件「==」で検索することが出来ます。

そして、検索で見つかったEC2の public-ip を返すことで、自動でdev_batch, stg_batch, prod_batch に対してIPアドレスを割り振ることが出来ます。

plugin: aws_ec2
regions:
  - ap-northeast-1  # prod は東京にあり、
  - us-east-1       # stg, dev はバージニアにある

groups:
  dev_batch: "tags.Name == 'dev_MyProject_Batch'"
  stg_batch: "tags.Name == 'stg_MyProject_Batch'"
  prod_batch: "tags.Name == 'prod_MyProject_Batch'"

hostnames:
  - network-interface.association.public-ip

IPアドレスが固定されている場合は「hosts:」に直値で書いてしまうのもありですが、そうでない場合も多いと思いますので、その時はこの方法を参考にしてもらえればと思います。

まとめ

aws_ec2で取得出来る情報はIPアドレス以外にも多岐に渡るので、有効活用すれば思いもしない自動化が出来るかもしれません。色々と試してみたいですね。

← 前の投稿

Spark 2.x で null を含む JSON を書き出す方法

次の投稿 →

[GitHub Actions] Secrets や書き込み権限が必要な Workflow を Dependabot からも使えるようにする

コメントを残す