はじめに
AWSの無料枠範囲で遊んでいます。
無料枠を超えないようにするため、作っては削除。作っては削除。をコンソールでやるのがめんどくさくなりました。
そのため、AnsibleでAWSの環境構築を自動構築できるようにしよう!ということで、
Ansible Playbookのサンプルを作成してます。
この記事で作成したplaybookはgithubで公開しています。
https://github.com/rednes/ansible-aws-sample
(AWS02フォルダ)
AWSの何を作るか
以下の内容をAnsibleで自動構築できるようにします。
- VPCの作成
- Internet Gatewayの作成
- サブネットの作成
- ルートテーブルの作成
- セキュリティグループの作成
- EC2インスタンスの作成
- サブネットグループの作成
- RDSの作成
- EC2インスタンスにWordPress環境の構築
前提
- ansible, botoをインストールすること
- AWSのサーバー構築に使用するIAMユーザが作成されていること
- AWSマネジメントコンソールでキーペア登録していること
AWS構成図
今回Ansibleで構築するAWSの構成図はこんな感じです。
ディレクトリ構成
├── ansible.cfg
├── group_vars
│ └── all.yml
├── host_vars
│ └── localhost.yml
├── hosts
│ ├── ec2.ini
│ └── ec2.py
├── roles
│ ├── ec2
│ │ └── tasks
│ │ ├── ec2.yml
│ │ ├── main.yml
│ │ ├── security_group.yml
│ │ └── vpc.yml
│ ├── rds
│ │ └── tasks
│ │ ├── main.yml
│ │ └── rds.yml
│ ├── wordpress
│ │ ├── defaults
│ │ │ └── main.yml
│ │ └── tasks
│ │ └── main.yml
│ └── yum
│ ├── defaults
│ │ └── main.yml
│ └── tasks
│ └── main.yml
└── site.yml
Playbookの解説
AnsibleでAWS環境(RDS以外)を構築する内容については、過去の記事を参考にしてください。
今回はRDSの構築についてだけ説明します。
RDSの環境はrdsのroleで作成しています。
---
- include_tasks: rds.yml
main.ymlでは単純にrds.ymlをインクルードしているだけです。
rds.ymlでRDSインスタンスを作成しています。
サブネットとセキュリティグループはec2のroleであわせて作成しています。
1. 異なるAZでサブネットを二つ作成
ec2_vpc_subnetモジュールでサブネットを構築します。
サブネットではVPC, Availability Zone, CIDRを指定します。
RDSでは単独のAZでしか使用しない場合でも、複数のAZにまたがったサブネットグループを作成する必要があるため、
今回は使用していませんがわざわざ使用しないAZにサブネットを作成しています。
サブネットグループ作成時に使用するサブネットを識別するため、タグに「route: private」を設定しています。
- name: subnet作成
ec2_vpc_subnet:
region: "{{ aws.common.region }}"
state: present
vpc_id: "{{ vpc_net.vpc.id }}"
az: "{{ aws.common.region }}{{ item.value.zone }}"
cidr: "{{ item.value.cidr }}"
map_public: "{{ item.value.map_public|default(True) }}"
tags: "{{ item.value.tags }}"
with_dict: "{{ aws.vpc.subnet }}"
register: vpc_subnet
aws:
common:
region: ap-northeast-1
vpc:
subnet:
subnet1:
tags:
Name: public-a
route: public
cidr: 10.0.1.0/24
zone: a
subnet2:
tags:
Name: private-a
route: private
cidr: 10.0.2.0/24
map_public: False
zone: a
subnet3:
tags:
Name: private-c
route: private
cidr: 10.0.3.0/24
map_public: False
zone: c
2. セキュリティグループを作成
ec2_groupモジュールでセキュリティグループを構築します。
セキュリティグループでは主にVPCとインバウンドルールを指定します。
AnsibleDBという名称のセキュリティグループを作成して、
EC2からのみ接続できるように設定しています。
- name: security group作成
ec2_group:
name: "{{ item.value.name }}"
description: "{{ item.value.description }}"
tags:
Name: "{{ item.value.name }}"
vpc_id: "{{ vpc_net_fact.vpcs[0].id }}"
region: "{{ aws.common.region }}"
purge_rules: "{{ item.value.purge_rules|default(False) }}"
rules: "{{ item.value.rules }}"
with_dict: "{{ aws.vpc.security_group }}"
register: security_group
aws:
common:
region: ap-northeast-1
vpc:
security_group:
security_group1:
name: AnsibleWeb
description: EC2 group
rules:
- proto: tcp
ports:
- 22
cidr_ip: 0.0.0.0/0
- proto: tcp
ports:
- 80
- 443
cidr_ip: 0.0.0.0/0
security_group2:
name: AnsibleDB
description: EC2 group
rules:
- proto: tcp
ports:
- 3306
cidr_ip: 10.0.1.0/24
3. サブネットグループを作成
rds_subnet_groupモジュールでサブネットグループを構築します。
サブネットグループでは主にsubnet idを指定します。
ec2_vpc_subnet_factsモジュールでタグが「route: private」である全てのサブネットを取得して、
一つのサブネットグループを作成しています。
- name: subnet取得
ec2_vpc_subnet_facts:
region: "{{ aws.common.region }}"
filters:
"tag:route": private
register: ec2_subnet_facts
check_mode: no
- name: rds-subnet-group作成
rds_subnet_group:
name: "{{ aws.vpc.rds.subnet_group.name }}"
region: "{{ aws.common.region }}"
state: present
description: "{{ aws.vpc.rds.subnet_group.description }}"
subnets: "{{ ec2_subnet_facts.subnets | map(attribute='id') | list }}"
register: rds_subnet_group
aws:
common:
region: ap-northeast-1
vpc:
rds:
subnet_group:
name: wp-dbsubnet
description: WordPress DB Subnet
4. RDSを作成
rdsモジュールでRDSインスタンスを構築します。
セキュリティグループはec2_group_factsモジュールを利用して、
名称からIDを引っ張ってきて定義しています。
- name: RDS作成
rds:
command: create
instance_name: "{{ aws.vpc.rds.db_name }}"
username: "{{ aws.vpc.rds.db_user }}"
password: "{{ aws.vpc.rds.db_password }}"
db_name: wordpress
region: "{{ aws.common.region }}"
subnet: "{{ aws.vpc.rds.subnet_group.name }}"
vpc_security_groups: "{{ ec2_group_facts.security_groups[0].group_id }}"
db_engine: "{{ aws.vpc.rds.db_engine }}"
engine_version: "{{ aws.vpc.rds.engine_version }}"
license_model: "{{ aws.vpc.rds.license_model }}"
instance_type: "{{ aws.vpc.rds.instance }}"
size: "{{ aws.vpc.rds.size }}"
tags:
Name: "{{ aws.vpc.rds.db_name }}"
register: rds
aws:
common:
region: ap-northeast-1
vpc:
rds:
db_name: wordpressdb
db_user: root
db_password: password
db_engine: MySQL
engine_version: 5.6.37
license_model: general-public-license
instance: db.t2.micro
size: 20
注意点
RDSのエンドポイントがRDSを作成するまでわからないため、まず最初にRDSインスタンスまで作成した後に
RDSのエンドポイントをgroup_vars/all.ymlに追記する必要があります。
---
my_vars:
rds:
endpoint: XXXX # RDSで作成したDBのエンドポイントを入力
RDS作成が完了したら以下の様にawscli等を使用してエンドポイントを取得し、
上述のall.ymlにエンドポイントを記載するとEC2からRDSのmysqlに接続してWordPress環境を構築できます。
$ aws rds describe-db-instances --query="DBInstances[].Endpoint"