Help us understand the problem. What is going on with this article?

AnsibleでAWS環境(RDS)を自動構築する

More than 1 year has passed since last update.

はじめに

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の構成図はこんな感じです。

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で作成しています。

roles/rds/tasks/main.yml
---
- 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」を設定しています。

roles/ec2/tasks/vpc.ymlの一部
- 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
host_vars/localhost.ymlの一部
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からのみ接続できるように設定しています。

roles/ec2/tasks/security_group.ymlの一部
- 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
host_vars/localhost.ymlの一部
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」である全てのサブネットを取得して、
一つのサブネットグループを作成しています。

roles/rds/tasks/rds.ymlの一部
- 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
host_vars/localhost.ymlの一部
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を引っ張ってきて定義しています。

roles/rds/tasks/rds.ymlの一部
- 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
host_vars/localhost.ymlの一部
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に追記する必要があります。

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"
Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away