はじめに
前回はAnsibleサーバーの構築を実施しました。
今回は構築したAndibleを使ってAWS上にVPCなどのネットワークリソースやキーペアの作成を行います。
- aws上に作成したansibleサーバーでテストサイトを構築する
Playbookの作成
まずはPlaybookを格納するディレクトリを作成します。今後はすべてここを基準に作成、実行していきます。
大まかなレイアウトはここに記載されているものと合わせるようにしています。
> mkdir aws_testsite
> cd aws_testsite
次にansible-playbook
コマンドから呼び出すおおもとのPlaybookファイルsite.yml
を作成します。
AWSのリソースを作成する部分と、作成したEC2インスタンス上の設定(OSやミドルウェア等)を行う部分とに分けて別々に実行できるようにしようと思いますので、このファイルからは子ファイルを呼び出すのみとします。
- import_playbook: aws_infra.yml
呼び出される子のPlaybookは以下のように、aws_network
ロールを呼び出すものとします。ここには今後、EC2インスタンスやRDSインスタンスの作成ロールを追加していきます。
- hosts: localhost
roles:
- { role: aws_network, tags: [aws_network] }
Playbookで指定した通り、aws_network
ロールをroles
フォルダ配下に作ります。
> mkdir -p roles/aws_network/tasks
ネットワークリソースの内容の定義
どのようなネットワーク構成にするかをgroup_vars
フォルダのall.yml
ファイルに定義します。
ここでは、アジアパシフィック(東京)リージョンap-northeast-1
にVPCを作成して、中のAZそれぞれにwebapp用のサブネットを一つづつ作ることにします。
> mkdir -p group_vars
---
vpc:
name: "testsite"
region: "ap-northeast-1"
cidr: "172.22.0.0/16"
subnets:
- name: "webapp1"
cidr: "172.22.1.0/24"
az: "ap-northeast-1a"
- name: "webapp2"
cidr: "172.22.2.0/24"
az: "ap-northeast-1c"
各リソースを作成するタスクの作成
group_vars/all.yml
で定義した内容に従って、各リソースを作成するタスクを作ります。
VPC等のネットワークリソースを作成するタスクは相互のかかわりが大きいのでcreate_vpc.yml
として1つのファイルにまとめます。
---
- import_tasks: create_vpc.yml
VPCの作成
まずVPCを作成します。テストサイトを構成するPlaybookなので、複数のVPCを作成することは考慮しません。
---
- name: create vpc
ec2_vpc_net:
state: present
region: "{{ vpc.region }}"
cidr_block: "{{ vpc.cidr }}"
name: "{{ vpc.name }}"
register: aws_network_vpc
- debug: var=aws_network_vpc
ここまでのPlaybookを実行すると以下のようになります。
$ ansible-playbook site.yml
PLAY [localhost] *************************************************************************************************************************************************************************************
TASK [Gathering Facts] *******************************************************************************************************************************************************************************
ok: [localhost]
TASK [aws_network : create vpc] **********************************************************************************************************************************************************************
changed: [localhost]
TASK [aws_network : debug] ***************************************************************************************************************************************************************************
ok: [localhost] => {
"aws_vpc": {
"changed": false,
"failed": false,
"vpc": {
"cidr_block": "172.22.0.0/16",
"classic_link_enabled": null,
"dhcp_options_id": "dopt-f6c50e92",
"id": "vpc-603e2404",
"instance_tenancy": "default",
"is_default": false,
"state": "available",
"tags": {
"Name": "testsite"
}
}
}
}
サブネットの作成
続いてVPC内にサブネットを作成します。こちらは複数のサブネットを構成するのでwith_items
で複数のサブネットを作成します。
引数として前タスクで作成したVPCのIDが必要となりますので、register
ディレクティブで確保したaws_network_vpc
から取得します。
- name: create vpc subnets
ec2_vpc_subnet:
state: present
vpc_id: "{{ aws_network_vpc.vpc.id }}"
region: "{{ vpc.region }}"
cidr: "{{ item.cidr }}"
az: "{{ item.az }}"
tags:
Name: "{{ item.name }}"
with_items: "{{ vpc.subnets }}"
インターネットゲートウェイの作成
このVPC内とインターネット間での通信ができるようにインターネットゲートウェイを作成します。
インターネットからのWebアクセスやSSH接続、また内部からインターネットの参照に使用します。
ここでもVPC IDが必要となります。
- name: create internet gateway
ec2_vpc_igw:
state: present
region: "{{ vpc.region }}"
vpc_id: "{{ aws_network_vpc.vpc.id }}"
register: aws_igw
ルートテーブルの作成
各サブネットにインターネット参照を可能とするルートテーブルを定義します。
今回の構成では、すべてのサーバーをAnsibleで管理するためにインターネットからのSSH接続が必要となるため、作成したサブネットすべてにインターネット向けのルートを設定します。
ルートテーブルに登録するサブネット名のリストが必要となるため、group_vars/all.yml
の定義から、サブネット名のリストを作成しています。
- name: make subnet list
set_fact:
list_subnets: "{{ vpc.subnets | map(attribute='name') | list }}"
- name: Set up public subnet route table
ec2_vpc_route_table:
state: present
region: "{{ vpc.region }}"
vpc_id: "{{ aws_network_vpc.vpc.id }}"
tags:
Name: "Public subnet"
subnets: "{{ list_subnets }}"
routes:
- dest: 0.0.0.0/0
gateway_id: "{{ aws_igw.gateway_id }}"
セキュリティグループの作成
続いて作成するWEBサーバーへのアクセスを制御するためのセキュリティグループを定義します。
まずはAnsibleサーバーからのSSH接続を可能にするために、「0.0.0.0/0」からのSSH(TCP/22)接続を許可します。
EC2は停止するたびにグローバルIPアドレスが変わるため、全アドレスからのSSHを許可しています。
EC2のSSHは既定で公開鍵認証のみが有効となるので、テストサイトであれば問題ないでしょう…
(SSHに脆弱性が発見される可能性もあるので本番サイトの場合はまた別に考える必要があります)
Webアプリへの接続を許可するルールも定義しておきます。
こちらは接続元のIPを限定して許可する設定としています。これは、AWS上でWebサーバーを公開すると、すぐにWordPressやphpMyAdminへのアタックと思われるアクセスがあるためです。
複数の接続元がある場合には、それぞれルールを定義します。(Ansible 2.4になればcidr_ipや、portをリスト構成にできるようになるようです)
security_groups:
- name: "SG_webapps"
description: "for WebApplication Servers"
rules:
- proto: tcp
from_port: 22
to_port: 22
cidr_ip: 0.0.0.0/0
- proto: tcp
from_port: 80
to_port: 80
cidr_ip: x.x.x.x/32
- proto: tcp
from_port: 80
to_port: 80
cidr_ip: y.y.y.y/32
- name: create security group
ec2_group:
name: "{{ item.name }}"
description: "{{ item.description }}"
vpc_id: "{{ aws_network_vpc.vpc.id }}"
region: "{{ vpc.region }}"
rules: "{{ item.rules }}"
with_items: "{{ security_groups }}"
キーペアの作成
EC2インスタンスにアクセスするキーペアを作成するタスクを作成します。
秘密鍵は、実行ユーザー(ec2-user)の~/.ssh
に保存するようにしています。
---
- import_tasks: create_vpc.yml
- import_tasks: create_keypair.yml
keypair:
name: "testsite_key"
ssh_keyfile_path: '~/.ssh'
ansible_ssh_private_key_file: '{{ ssh_keyfile_path }}/{{ keypair.name }}.pem'
---
- name: create keypair
ec2_key:
name: "{{ keypair.name }}"
region: "{{ vpc.region }}"
register: aws_keypair
- name: create keypair file
file:
path: '{{ ansible_ssh_private_key_file }}'
state: touch
mode: 0600
when: aws_keypair.key.private_key is defined
- name: keypair write
shell: echo "{{ aws_keypair.key.private_key }}" > {{ ansible_ssh_private_key_file }}
delegate_to: 127.0.0.1
when: aws_keypair.key.private_key is defined
次回
次回は EC2インスタンスを作成します。