aws上に作成したansibleサーバーでテストサイトを構築する(6) RDSの構成-1

# はじめに
[前回](https://qiita.com/yoshino_dd/items/1292d6b3beeae26433f7)までで、WebサーバーへのWordpressソースの展開まで完了しました。
今回は、wordpress用データベースとして使用するRDSインスタンスを作成する準備をします。

- aws上に作成したansibleサーバーでテストサイトを構築する
  1. [Ansibleサーバー構築](https://qiita.com/yoshino_dd/items/1e0969fd6dab1b51e1e0)
  1. [AWSネットワーク構成](https://qiita.com/yoshino_dd/items/d9be528837803ebb4bd3)
  1. [EC2インスタンスの作成](https://qiita.com/yoshino_dd/items/4368e468c6aa5353bf3c)
  1. [サーバー共通の設定](https://qiita.com/yoshino_dd/items/3fa56fc09e9162d6ad4a)
  1. [Webサーバーの構成](https://qiita.com/yoshino_dd/items/1292d6b3beeae26433f7)
  1. [RDSの構成-1](https://qiita.com/yoshino_dd/items/8d559b60d5b9f316d8bb)
  1. [RDSの構成-2](https://qiita.com/yoshino_dd/items/1da42dc2d1446ec20526)
  1. [WordPressの設定](https://qiita.com/yoshino_dd/items/d41694d468c5c64d78a0)
  1. 参考にしたサイトなど

このページと次のページの内容については、全面的にこちらのページを参考にしました。

- [RDSをAnsibleで管理する](http://qiita.com/tomohiko_isobe/items/7ce42217e177f0c6b7ec)

# RDS操作権限追加
まず、最初の回でansibleサーバーに適用したIAMロールにはEC2の操作権限のみしか付与していないので、RDS操作の権限を追加します。

AWSマネジメントコンソールからIAMの管理ページに移動して、「ロール」を表示。
![2017-11-08_16h34_32.png](https://qiita-image-store.s3.amazonaws.com/0/150514/ac565e2f-eec6-faad-58f4-144c309ecffe.png)

ansibleサーバーに付与したロール「ansible_server_role」を選択。
![2017-11-08_16h39_05.png](https://qiita-image-store.s3.amazonaws.com/0/150514/88e5fe02-ebed-4b02-a52c-c7daa88f94f4.png)

「アクセス権限」タブの「ポリシーのアタッチ」ボタンをクリック。
![2017-11-08_16h41_45.png](https://qiita-image-store.s3.amazonaws.com/0/150514/ce73649f-5215-79aa-20c4-c72f7ed476e7.png)

`AmazonRDSFullAccess`を追加。
![2017-11-08_16h42_52.png](https://qiita-image-store.s3.amazonaws.com/0/150514/d61fd86c-eead-91fd-4ec4-03f0cc0c26a8.png)

これでansibleサーバーにRDSの操作権限が付与されました。

# RDS用プレイブック作成
権限を付与したら、RDSを作成するロールを追加します。これは、AWSのリソースなので`aws_infra.yml`に追加することにします。

```diff:aws_infra.yml(変更)
 - hosts: localhost
   roles:
   - { role: aws_network, tags: [aws_network] }
+  - { role: aws_rds, tags: [aws_rds] }

 - hosts: all
   connection: local
   roles:
   - { role: aws_ec2, tags: [aws_ec2] }
```
```shell-session:command
$ mkdir -p roles/aws_rds/tasks
```

# RDS周辺のリソース作成
RDSインスタンスを作成するには、RDS用のサブネットグループと、セキュリティグループを作っておく必要があるのでそれらの準備を行います。

### RDSサブネットグループの準備
RDSサブネットグループは、RDSインスタンスを配置する、2つ以上のサブネットをまとめたものです。
インスタンスの起動先サブネットは1つなのですが、なぜか2つ以上のサブネットでグループを作らないといけないようです。

まず、`group_vars/all.yml`にDB用のサブネット定義を2つ追加します。

```diff:group_vars/all.yml(変更部分)
 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"
+  - name: "database1"
+    cidr: "172.22.128.0/24"
+    az: "ap-northeast-1a"
+  - name: "database2"
+    cidr: "172.22.129.0/24"
+    az: "ap-northeast-1c"
```

さらに、rds関連の設定をまとめた変数をrdsという名前で追加することにします。
とりあえず先程追加したサブネットをグループとして定義します。

```diff:group_vars/all.yml(追加部分)
rds:
  subnet_group:
  - name: database
    description: 'private subnet group for database'
    subnets:
    - database1
    - database2
```

RDSサブネットグループを作成するタスクを追加します。
rds_subnet_groupモジュールを使いますが、サブネットの指定にsubnetIDが必要となるので、ec2_vpc_subnet_factsモジュールを使用して取得します。

まずは、aws_networkロールで作成したサブネットから先程定義したRDSサブネットグループに含まれるサブネットの情報を取得します。

```yaml:roles/aws_rds/tasks/main.yml
---
- name: subnet id 取得
  ec2_vpc_subnet_facts:
    region: '{{ vpc.region }}'
    filters:
      "tag:Name": "{{ item.1 }}"
  with_subelements:
  - "{{ rds.subnet_group }}"
  - subnets
  register: subnet_fact

- debug: var=subnet_fact
```

次に取得した情報からRDSサブネットグループ名とサブネットIDを対応付けたディクショナリを組み立てます。

```yaml:roles/aws_rds/tasks/main.yml(追加)
- name: subnet dict作成
  set_fact:
    subnets_dict: >-
      {%- set dict = {} -%}
      {%- set inc = 0 -%}
      {%- set subnet_group_cnt = rds.subnet_group | length -%}
      {%- for i in range(subnet_group_cnt) -%}
      {%-   set list = [] -%}
      {%-   for j in range(rds.subnet_group[i].subnets | length) -%}
      {%-     set _ = list.append(subnet_fact.results[inc+j].subnets[0].id) -%}
      {%-   endfor -%}
      {%-   set _ = dict.update({rds.subnet_group[i].name: list}) -%}
      {%-   set inc = inc + subnet_group_cnt -%}
      {%- endfor -%}
      {{ dict }}

- debug: var=subnets_dict
```

上で作成したディクショナリを使って、RDSサブネットグループを作成するタスクが以下となります。

```yaml:roles/aws_rds/tasks/main.yml(追加)
- name: rds subnet group 作成
  rds_subnet_group:
    state: present
    name: "{{ item.name }}"
    description: "{{ item.description }}"
    region: "{{ vpc.region }}"
    subnets: >-
      {%- set list = subnets_dict[item.name] -%}
      {{ list }}
  with_items: "{{ rds.subnet_group }}"
  register: rds_subnet_group

- debug: var=rds_subnet_group
```  

### セキュリティグループの準備
セキュリティグループも`group_vars/all.yml`にデータベースアクセス用のものを追加して`aws_network`ロールで作成します。

```yaml:group_vars/all.yml(追加部分)
security_groups:
<< 中略 >>
  - name: "SG_database"
    description: "for RDS"
    rules:
    - proto: tcp
      from_port: 3306
      to_port: 3306
      cidr_ip: 172.22.0.0/16
```

サブネットと同じように、`ec2_group_facts`で取得した情報をもとに、名前とIDを紐づけたハッシュを作成します。

```yaml:roles/aws_rds/tasks/main.yml(追加)
- name: security group id 取得
  ec2_group_facts:
    region: '{{ vpc.region }}'
    filters:
      group_name: "{{ item.1 }}"
  with_subelements:
    - "{{ rds.instance }}"
    - security_group
  register: sg_fact

- name: security group dict作成
  set_fact:
    sg_dict: >-
      {%- set dict = {} -%}
      {%- for i in range(sg_fact.results|length) -%}
      {%-   set _ = dict.update({sg_fact.results[i].security_groups[0].group_name: sg_fact.results[i].security_groups[0].group_id}) -%}
      {%- endfor -%}
      {{ dict }}

- debug: var=sg_dict
```  

# 次回
ここまでで、RDSインスタンスの作成に必須となるリソースの準備ができました。
次回はRDSインスタンス本体の作成を行います。

- [aws上に作成したansibleサーバーでテストサイトを構築する(7) RDSの構成-2](https://qiita.com/yoshino_dd/items/1da42dc2d1446ec20526)

---
---