AWSで3層ネットワーク構成を構築するAnsibleのPlaybookを作ってみた

こんにちは。
SS チームのしめじです。
以前に Ansible で2層のネットワークを構築する記事を書いたんですが、実際の案件では3層のネットワークで環境を構築することも多いですよね。
という訳で、Ansible で AWS の3層ネットワークを構築する Playbook を作ってみました。
※ 実際に構築する環境はこちらになります↓

ディレクトリ構成
Playbook のディレクトリ構成は下記のような形となります。
. ├── README.md ├── ansible.cfg ├── hosts ├── roles │ └── aws_vpc │ ├── tasks │ │ └── main.yml │ └── vars │ └── main.yml └── vpc_create.yml
Playbook
はい、Playbook です。
基本的には2層の Playbook と同じなんですが、新たに NATGATEWAY の作成と、DMZ サブネット用のルートテーブルを作成する機能を追加してます。
---
# tasks file for aws_vpc
- name: create_vpc
ec2_vpc_net:
name: "{{ vpc_name }}"
cidr_block: "{{ vpc_cidr }}"
region: "{{ region }}"
profile: "{{ profile }}"
dns_hostnames: yes
dns_support: yes
register: vpc_info
# PUBLIC_SUBNET 作成
- name: create_public_subnet
ec2_vpc_subnet:
vpc_id: "{{ vpc_info.vpc.id }}"
cidr: "{{ item.pub_subnet_cidr }}"
az: "{{ item.subnet_az }}"
region: "{{ region }}"
resource_tags: { "Name":"{{ item.pub_subnet_name }}" }
profile: "{{ profile }}"
register: pubsub_info
with_items:
- "{{ pub_subnet }}"
# DMZ_SUBNET 作成
- name: create_dmz_subnet
ec2_vpc_subnet:
vpc_id: "{{ vpc_info.vpc.id }}"
cidr: "{{ item.dmz_subnet_cidr }}"
az: "{{ item.subnet_az }}"
region: "{{ region }}"
resource_tags: { "Name":"{{ item.dmz_subnet_name }}" }
profile: "{{ profile }}"
register: pubsub_info
with_items:
- "{{ dmz_subnet }}"
# PRIVATE_SUBNET 作成
- name: create_private_subnet
ec2_vpc_subnet:
vpc_id: "{{ vpc_info.vpc.id }}"
cidr: "{{ item.pri_subnet_cidr }}"
az: "{{ item.subnet_az }}"
region: "{{ region }}"
resource_tags: { "Name":"{{ item.pri_subnet_name }}" }
profile: "{{ profile }}"
register: prisub_info
with_items:
- "{{ pri_subnet }}"
# IGW 作成
- name: create_igw
ec2_vpc_igw:
vpc_id: "{{ vpc_info.vpc.id }}"
region: "{{ region }}"
tags: { "Name":"{{ igw_name }}" }
profile: "{{ profile }}"
register: igw_info
# ROUTETABLE 作成(IGW)
- name: create_route_table
ec2_vpc_route_table:
vpc_id: "{{ vpc_info.vpc.id }}"
subnets: "{{ atache_igw_subnet }}"
routes:
- dest: 0.0.0.0/0
gateway_id: "{{ igw_info.gateway_id }}"
region: "{{ region }}"
profile: "{{ profile }}"
resource_tags: { "Name":"{{ rttable_pub_name }}" }
# NGW を配置する SUBNETID を取得
- name: get_subnet_id
shell: aws ec2 describe-subnets --region {{ region }} --profile {{ profile }} --output text | grep -B 1 {{ ngw_subnet_name }} | awk 'NR==1 {print $12}'
register: ngw_subnet_id
#- name: show
# debug:
# msg: "{{ ngw_subnet_id.stdout }}"
# NGW 作成
- name: create_ngw
ec2_vpc_nat_gateway:
subnet_id: "{{ ngw_subnet_id.stdout }}"
region: "{{ region }}"
profile: "{{ profile }}"
wait: yes
register: ngw_info
#- name: show
# debug:
# msg: "{{ ngw_info.nat_gateway_id }}"
# NGW 作成まで待つ
#- name: wait_for_ngw
# pause:
# minutes: 5
# ROUTETABLE 作成(NGW)
- name: create_route_table2
ec2_vpc_route_table:
vpc_id: "{{ vpc_info.vpc.id }}"
subnets: "{{ atache_ngw_subnet }}"
routes:
- dest: 0.0.0.0/0
gateway_id: "{{ ngw_info.nat_gateway_id }}"
region: "{{ region }}"
profile: "{{ profile }}"
resource_tags: { "Name":"{{ rttable_dmz_name }}" }
awscli コマンドの結果を整形して DMZ サブネットの ID を取得しています。
これを利用して NATGATEWAY を作成する感じですね。
あと NATGATEWAY が作成されるまで少し時間がかかるので、「pause」モジュールで一時的に処理を止めてます。
※ 追記
Twitter にて「ec2_vpc_nat_gateway」に「wait」というオプションがあることご指摘いただきました!
ありがとうございます!
変数の定義
---
# vars file for aws_vpc
# REGION
region: "ap-northeast-1"
# PROFILE
profile: "default"
# VPC
vpc_name: "shimeji-3layer-vpc"
vpc_cidr: "10.10.0.0/16"
# IGW
igw_name: "shimeji-3layer-igw"
# NGW
ngw_name: "shimeji-3layer-ngw"
# NGW を作成するサブネット名
ngw_subnet_name: "shimeji-3layer-public-subnet-a"
# ROUTETABLE(PUBLIC)
rttable_pub_name: "shimeji-3layer-pub-rt"
# ROUTETABLE(DMZ)
rttable_dmz_name: "shimeji-3layer-dmz-rt"
# PUBLIC_SUBNET
pub_subnet:
- { pub_subnet_cidr: "10.10.10.0/24" ,subnet_az: "ap-northeast-1a" ,pub_subnet_name: "shimeji-3layer-public-subnet-a" }
- { pub_subnet_cidr: "10.10.20.0/24" ,subnet_az: "ap-northeast-1c" ,pub_subnet_name: "shimeji-3layer-public-subnet-c" }
# DMZ_SUBNET
dmz_subnet:
- { dmz_subnet_cidr: "10.10.30.0/24" ,subnet_az: "ap-northeast-1a" ,dmz_subnet_name: "shimeji-3layer-dmz-subnet-a" }
- { dmz_subnet_cidr: "10.10.40.0/24" ,subnet_az: "ap-northeast-1c" ,dmz_subnet_name: "shimeji-3layer-dmz-subnet-c" }
# PRIVATE_SUBNET
pri_subnet:
- { pri_subnet_cidr: "10.10.50.0/24" ,subnet_az: "ap-northeast-1a" ,pri_subnet_name: "shimeji-3layer-private-subnet-a" }
- { pri_subnet_cidr: "10.10.60.0/24" ,subnet_az: "ap-northeast-1c" ,pri_subnet_name: "shimeji-3layer-private-subnet-c" }
# IGW に紐付けるサブネット
atache_igw_subnet:
- "10.10.10.0/24"
- "10.10.20.0/24"
# NGW に紐付けるサブネット
atache_ngw_subnet:
- "10.10.30.0/24"
- "10.10.40.0/24"
今回はそれぞれのリソースに「shimeji-3layer」の prefix をつけます。
実行
実際に実行してみましょう。
root@BYD-NPC-023:/opt/playbook/aws-vpc-3layer# ansible-playbook -i hosts vpc_create.yml
PLAY [create vpc subnet igw routetable] *************************************************************************************************************************************************************************
TASK [aws_vpc : create_vpc] *************************************************************************************************************************************************************************************
changed: [127.0.0.1]
TASK [aws_vpc : create_public_subnet] ***************************************************************************************************************************************************************************
changed: [127.0.0.1] => (item={u'pub_subnet_name': u'shimeji-3layer-public-subnet-a', u'subnet_az': u'ap-northeast-1a', u'pub_subnet_cidr': u'10.10.10.0/24'})
changed: [127.0.0.1] => (item={u'pub_subnet_name': u'shimeji-3layer-public-subnet-c', u'subnet_az': u'ap-northeast-1c', u'pub_subnet_cidr': u'10.10.20.0/24'})
TASK [aws_vpc : create_dmz_subnet] ******************************************************************************************************************************************************************************
changed: [127.0.0.1] => (item={u'dmz_subnet_cidr': u'10.10.30.0/24', u'dmz_subnet_name': u'shimeji-3layer-dmz-subnet-a', u'subnet_az': u'ap-northeast-1a'})
changed: [127.0.0.1] => (item={u'dmz_subnet_cidr': u'10.10.40.0/24', u'dmz_subnet_name': u'shimeji-3layer-dmz-subnet-c', u'subnet_az': u'ap-northeast-1c'})
TASK [aws_vpc : create_private_subnet] **************************************************************************************************************************************************************************
changed: [127.0.0.1] => (item={u'pri_subnet_cidr': u'10.10.50.0/24', u'pri_subnet_name': u'shimeji-3layer-private-subnet-a', u'subnet_az': u'ap-northeast-1a'})
changed: [127.0.0.1] => (item={u'pri_subnet_cidr': u'10.10.60.0/24', u'pri_subnet_name': u'shimeji-3layer-private-subnet-c', u'subnet_az': u'ap-northeast-1c'})
TASK [aws_vpc : create_igw] *************************************************************************************************************************************************************************************
changed: [127.0.0.1]
TASK [aws_vpc : create_route_table] *****************************************************************************************************************************************************************************
changed: [127.0.0.1]
TASK [aws_vpc : get_subnet_id] **********************************************************************************************************************************************************************************
changed: [127.0.0.1]
TASK [aws_vpc : create_ngw] *************************************************************************************************************************************************************************************
changed: [127.0.0.1]
TASK [aws_vpc : wait_for_ngw] ***********************************************************************************************************************************************************************************
Pausing for 300 seconds
(ctrl+C then 'C' = continue early, ctrl+C then 'A' = abort)
ok: [127.0.0.1]
TASK [aws_vpc : create_route_table2] ****************************************************************************************************************************************************************************
changed: [127.0.0.1]
PLAY RECAP ******************************************************************************************************************************************************************************************************
127.0.0.1 : ok=10 changed=9 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
うん、成功です!
終わりに
AWS のネットワークを管理画面からポチポチして構築することもできますが、時間もかかるしヒューマンエラーが発生するかもですよね。
その点 Ansible を使えば、時短になるし、ミスも減らせます!
↓因みに2層はこちらです。
この記事がお役に立てば【 いいね 】のご協力をお願いいたします!
0