はじめに
AnsibleにはAWSのリソースを操作できるモジュールが豊富に用意されています。
今回は、ec2_eipモジュールを利用して取得済みのEIPをEC2インスタンスにAnsibleでアサインしてみます。
やること
- EC2インスタンスに取得済みEIPをアサイン
ポイント
ec2_eipモジュールでは、対象のEC2インスタンスIDが必要となりますが、IDをAnsibleのYAMLに書きたくないので、EC2インスタンス名からIDを取得する実装とします。
前提
- AWS関連のモジュール実行にはbotoが必要です。
- credential情報は環境変数か
aws configure
でセットしてある必要があります。 - EIPは取得済みであること。
下記リソースを前提に進めます。
- VPC
- AnsibleVPC
- 取得済みEIP
- 54.xx.xx.xx
- 52.xx.xx.xx
- EC2インスタンス
- test01
- 54.xx.xx.xxをアサイン
- test02
- 52.xx.xx.xxをアサイン
- test01
sample
ディレクトリ構成
ディレクトリ構成
site.yml
roles/
|--eip/
| |--tasks/
| | |--main.yml
hosts/aws #inventory
host_vars/
|--localhost.yml
inventory
AWSリソース関連モジュールはすべてlocalhostで実行するので、下記のようなインベントリファイルを用意します。
hosts/aws
[aws]
localhost
vars
こんな感じに変数を定義します。今回はhost_varsで定義しました。
host_vars/localhost.yml
---
my_vars:
aws:
common:
region: ap-northeast-1
vpc:
name: AnsibleVPC # ターゲットのVPC名
eip:
- ip: 54.xx.xx.xx
device: test01 #ec2 instance name
- ip: 52.xx.xx.xx
device: test02 #ec2 instance name
Role
まずVPCを特定するためにidが必要ですが、こちらと同様、VPC名でidを取得します。
ec2_remote_factsモジュールでEC2インスタンス名からIDを取得し、set_factモジュールで{EC2インスタンス名:ID}
のディクショナリを生成します。
後続タスクではこのディクショナリから対象のEC2インスタンスIDを取得します。
roles/eip/tasks/main.yml
---
- name: vpc_id取得
ec2_vpc_net_facts:
region: "{{ my_vars.aws.common.region }}"
filters:
"tag:Name": "{{ my_vars.aws.vpc.name }}"
register: vpc_net_fact
when: my_vars.aws.vpc is defined
check_mode: no
- debug: var=vpc_net_fact
- name: ec2 facts取得
ec2_remote_facts:
region: "{{ my_vars.aws.common.region }}"
filters:
vpc_id: "{{ vpc_net_fact.vpcs[0].id }}"
"tag:Name": "{{ item.value.tags.Name }}"
with_dict: "{{ my_vars.aws.ec2 }}"
register: ec2_fact
when: my_vars.aws.eip is defined
- name: ec2 dict作成
set_fact:
ec2_dict: >-
{%- set dict = {} -%}
{%- for i in range(ec2_fact.results|length) -%}
{%- set _ = dict.update({ec2_fact.results[i].instances[0].tags.Name: ec2_fact.results[i].instances[0].id}) -%}
{%- endfor -%}
{{ dict }}
when: my_vars.aws.eip is defined
- name: associate an elastic IP with an instance
ec2_eip:
region: "{{ my_vars.aws.common.region }}"
device_id: >-
{%- set id = ec2_dict[item.device] -%}
{{ id }}
ip: "{{ item.ip }}"
with_items: "{{ my_vars.aws.eip }}"
register: eip
when: my_vars.aws.eip is defined
- debug: var=eip
site.yml
site.yml
---
- name: eip
hosts: localhost
connection: local
roles:
- role: eip
実行
Command
$ ansible-playbook -i hosts/aws -l localhost site.yml
まとめ
マネジメントコンソール上では管理しづらいEIPですが、Ansibleで管理すればどのEIPがどのインスタンスにアサインされているのか分かりやすくなると思います。