#はじめに
AnsibleにはAWSのリソースを操作できるモジュールが豊富に用意されています。
今回はVPCを操作するモジュールを利用して、AnsibleでVPCを作成します。
#やること
- VPC作成
- サブネット作成
- インターネットゲートウェイ作成
- ルートテーブル作成
##ポイント
- 作成したVPCのidを
ec2_vpc_net_facts
モジュールで取得し、後続のタスクで利用する
#前提
AWS関連のモジュール実行にはbotoが必要です。
credential情報は環境変数かaws configure
でセットしてある必要があります。
#sample
以下のようなVPCを作成します。
- CIDR
- 10.0.0.0/16
- サブネット
- パブリック
- 10.0.1.0/24(AZ-a)
- 10.0.2.0/24(AZ-c)
- プライベート
- 10.0.11.0/24(AZ-a)
- 10.0.12.0/24(AZ-c)
- パブリック
##ディレクトリ構成
site.yml
roles/
|--vpc/
| |--tasks/
| | |--main.yml
hosts/aws #inventory
host_vars/
|--localhost.yml
##inventory
AWSリソース関連モジュールはすべてlocalhostで実行するので、下記のようなインベントリファイルを用意します。
[aws]
localhost
##vars
こんな感じに変数を定義します。今回はhost_varsで定義しました。
---
my_vars:
aws:
common:
region: ap-northeast-1
vpc:
name: AnsibleVPC
cidr_block: 10.0.0.0/16
tags:
tag1: tag1
tag2: tag2
subnet:
subnet1:
tags:
Name: public-a
cidr: 10.0.1.0/24
zone: a
subnet2:
tags:
Name: public-c
cidr: 10.0.2.0/24
zone: c
subnet3:
tags:
Name: private-a
cidr: 10.0.11.0/24
zone: a
subnet4:
tags:
Name: private-c
cidr: 10.0.12.0/24
zone: c
route_table:
public:
name: public
subnets:
- 10.0.1.0/24
- 10.0.2.0/24
routes:
- dest: 0.0.0.0/0
gateway_id: igw
##Role
まず、VPCを作成します。
作成後、ec2_vpc_net_facts
でアサインされたVPCのidを保持しておきます。
後続タスクでは、そのidを用いて対象VPCを指定します。
ルートテーブル作成では、対象サブネットをリストで渡す必要があるのですが、with_dictを使ってループさせている関係でそのままではうまく渡せません。
そこで、jinja2のフィルタを使ってリストに整形しています。
要素が1つの場合と複数の場合で処理を分けています。
---
- name: VPC作成
ec2_vpc_net:
name: "{{ my_vars.aws.vpc.name }}"
cidr_block: "{{ my_vars.aws.vpc.cidr_block }}"
region: "{{ my_vars.aws.common.region }}"
tags: "{{ my_vars.aws.vpc.tags }}"
tenancy: default
register: vpc_net
- debug: var=vpc_net
- 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
check_mode: no
- debug: var=vpc_net_fact
- name: Internet Gateway作成
ec2_vpc_igw:
region: "{{ my_vars.aws.common.region }}"
vpc_id: "{{ vpc_net_fact.vpcs[0].id }}"
state: present
register: igw
- debug: var=igw
- name: subnet作成
ec2_vpc_subnet:
region: "{{ my_vars.aws.common.region }}"
state: present
vpc_id: "{{ vpc_net_fact.vpcs[0].id }}"
az: "{{ my_vars.aws.common.region }}{{ item.value.zone }}"
cidr: "{{ item.value.cidr }}"
tags: "{{ item.value.tags }}"
with_dict: "{{ my_vars.aws.vpc.subnet }}"
register: vpc_subnet
- debug: var=vpc_subnet
- name: route table作成
ec2_vpc_route_table:
vpc_id: "{{ vpc_net_fact.vpcs[0].id }}"
region: "{{ my_vars.aws.common.region }}"
tags:
Name: "{{ item.value.name }}"
subnets: "{{ item.value.subnets }}"
routes: >-
{%- if item.value.routes|length == 1 -%}
{{ item.value.routes }}
{%- else -%}
{{ item.value.routes | join(',') }}
{%- endif -%}
with_dict: "{{ my_vars.aws.vpc.route_table }}"
register: route_table
- debug: var=route_table
##site.yml
---
- name: vpc
hosts: localhost
connection: local
roles:
- role: vpc
##実行
$ ansible-playbook -i hosts/aws -l localhost site.yml
#まとめ
VPC関連モジュールではvpc_idが必須なのですが、CIDRブロックと名前でVPCを管理できるので便利かと思います。