パフォーマンス検証環境を新たに作りたい場合など柔軟にAWS環境の構成を何度も作り直したい時、構成管理ツールを使って自動化すると非常に便利だと感じています。
- 同じミドルウェアの設定の環境を迅速に作れる。
- サーバの環境、ミドルウェアの設定内容をコードベースで把握できる。状態が共有しやすい。
- 作り直しが必要になった時に、手間がかからない。
- オペミスもないので、環境構築に時間がかからない。
構成管理ツールとしてAnsibleを使ったAWS環境構築の設定に関してまとめてみました。 VPC、セキュリティグループ、EC2、RDSを構築するPlayBookを作ってみたので、部分的にでも使える箇所があれば、参考にしてみてください。
- 構成図
- 環境
- ①AWS CLI、②構成管理ツール Ansibleのインストール
- ③Ansible定義ファイル(playbook)作成
- ④VPC(とサブネット、ルートテーブル)構築
- ⑤セキュリティグループ設定
- ⑥EC2構築
- ⑦RDS構築
- 実行と確認
- 参考資料
構成図
構築するローカル環境とAWS環境は以下の図の通りです。
環境
①AWS CLI、②構成管理ツール Ansibleのインストール
AnsibleからAWS環境を作るには、AWS CLIのインストールが必要です。 AnsibleにはデフォルトでAWS環境を操作するためのモジュールがあり、AWS CLI経由で環境を作ることができます。
各ツールのインストール方法はこちらの記事を参照してください。 simple-minds-think-alike.hatenablog.com
③Ansible定義ファイル(playbook)作成
Ansible定義ファイルにAWS環境の構築内容を記載していきます。
Ansible定義ファイルのディレクトリ / ファイル構成
ローカル環境に作るAnsible定義ファイルの定義ファイルのディレクトリ / ファイル構成の最終系は以下のようになります。
├── build_aws.yml └─ roles ├── common │ └── vars │ └── main.yml # 実行順序: 1 ├── ec2 │ ├── tasks │ │ └── main.yml # 実行順序: 7 │ └── vars │ └── main.yml # 実行順序: 6 ├── rds │ ├── tasks │ │ └── main.yml # 実行順序: 9 │ └── vars │ └── main.yml # 実行順序: 8 ├── securitygroup │ ├── tasks │ │ └── main.yml # 実行順序: 5 │ └── vars │ └── main.yml # 実行順序: 4 └── vpc ├── tasks │ └── main.yml # 実行順序: 3 └── vars └── main.yml # 実行順序: 2
ansibleのplaybook実行時に指定する定義ファイル build_aws.yml
を作成し、以下のように記載しました。
- hosts: localhost connection: local sudo: yes pre_tasks: - name: boto、boto3、botocoreが未インストールならインストール pip: name: "{{ item }}" with_items: - boto - boto3 - botocore roles: - common - vpc - securitygroup - ec2 - rds
AWS各環境を構築するansibleのモジュールをを用いて、ローカル環境にインストールされているAWS CLIを実行するので、connection: local
を指定しています。
各ファイルがないのでまだ動きませんが、以下のように実行するとVPC、セキュリティグループ、EC2、RDSを一度に作成します。
$ sudo ansible-playbook build_aws.yml
このように実行すると、rolesで指定した順番通りに(common, vpc, securitygroup, ec2, rdsディレクトリの順番で)実行し、各ディレクトリ内のvarsで変数の設定を読み込み、tasksで構築の処理を行うようになります。
また、AnsibleでAWS環境を構築するには、boto, boto3, botocoreのようなライブラリが必要になるため、pre_tasksとして追加し、インストールにはsudo権限が必要なのでsudoをyesにします。
続いて、VPC、セキュリティグループ、EC2、RDSそれぞれの定義ファイルの中身を記載して行きます。
④VPC(とサブネット、ルートテーブル)構築
共通設定
roles/common/vars/main.yml
の内容は以下の通りで、VPC、セキュリティグループ、EC2、RDS構築全てに関係する共通の設定を書きました。
# aws-cliで実行する際のprofile profile: performance-test # 構築するAWS環境のリージョン region: ap-northeast-1 # SSH接続を許可する接続元CIDR (オフィスのIPを入れてます) office_ip_cidr: XXX.XXX.XXX.XXX/32
※今回パフォーマンステスト環境を作るための定義ファイルを作ったので、全体的にPerformance testのような文言が入っていますが、目的の用途に応じた名前を付けると良いと思います。
VPC設定
roles/vpc/vars/main.yml
に、VPC構築に関する設定のみ記載します。
vpc: name: VPC cidr_blodk: 10.0.0.0/16 subnet: - name: Performance test public subnet1 az: ap-northeast-1a cidr: 10.0.1.0/24 route: Public - name: Performance test private subnet1 az: ap-northeast-1a cidr: 10.0.11.0/24 route: Private - name: Performance test private subnet2 az: ap-northeast-1c cidr: 10.0.12.0/24 route: Private
パブリックなサブネットを1つ、プライベートなサブネットを2つ作成する設定です。 後で構築するMulti AZ構成のRDSセキュリティグループには、2つのサブネットを指定する必要があり、RDSは今回構築するVPC環境外からアクセスされたくないので、プライベートなサブネットを2つ作っています。
roles/vpc/tasks/main.yml
には、VPC構築するためのタスクを記載します。
- name: VPC構築 ec2_vpc_net: name: Performance-test VPC cidr_block: "10.0.0.0/16" profile: "{{ profile }}" region: "{{ region }}" register: _vpc - name: Internet gateway設定 ec2_vpc_igw: vpc_id: "{{ _vpc.vpc.id }}" profile: "{{ profile }}" region: "{{ region }}" register: _igw - name: Public, Private subnet構築 ec2_vpc_subnet: vpc_id: "{{ _vpc.vpc.id }}" az: "{{ item.az }}" cidr: "{{ item.cidr }}" resource_tags: Name: "{{ item.name }}" profile: "{{ profile }}" region: "{{ region }}" with_items: "{{ subnet }}" register: _subnet - name: Public subnetのRoute設定 ec2_vpc_route_table: vpc_id: "{{ _vpc.vpc.id }}" tags: Name: Performance test public route subnets: "{{ _subnet.results | selectattr('item.route', 'equalto', 'Public') | map(attribute='subnet.id') | list }}" # Public subnetの場合のみ、VPC外からアクセス可能にしています routes: - dest: 0.0.0.0/0 gateway_id: "{{ _igw.gateway_id }}" profile: "{{ profile }}" region: "{{ region }}" - name: Private SubnetのRoute設定 ec2_vpc_route_table: vpc_id: "{{ _vpc.vpc.id }}" tags: Name: Performance test private route subnets: "{{ _subnet.results | selectattr('item.route', 'equalto', 'Private') | map(attribute='subnet.id') | list }}" profile: "{{ profile }}" region: "{{ region }}"
⑤セキュリティグループ設定
roles/securitygroup/vars/main.yml
に、セキュリティグループ設定に関する設定のみ記載します。
security_group: common: group_name: performance test common description: common rules rules: - proto: tcp from_port: 22 to_port: 22 cidr_ip: "{{ office_ip_cidr }}" - proto: icmp from_port: -1 to_port: -1 cidr_ip: "{{ office_ip_cidr }}" web_server: group_name: performance test web server description: web server rules rules: - proto: tcp from_port: 80 to_port: 80 cidr_ip: 0.0.0.0/0 - proto: tcp from_port: 443 to_port: 443 cidr_ip: 0.0.0.0/0 db_server: group_name: performance test db server description: db server rules rules: - proto: tcp from_port: 5432 to_port: 5432 cidr_ip: 10.0.1.0/24
共通(common)のセキュリティグループには、オフィスIPからのみ
してみました。
Webサーバ(web_server)のセキュリティグループには、どこからでも
- HTTP(port: 80)
- HTTPS(port: 443)
にアクセスできるようにしてみました。
DBサーバ(db_server)のセキュリティグループには、パブリックなサブネットからのアクセスのみを許可するようにcidr_ipを指定します。
roles/securitygroup/tasks/main.yml
には、セキュリティグループ設定するためのタスクを記載します。
- name: Security Group 作成 ec2_group: name: "{{ item.value.group_name }}" description: "{{ item.value.description }}" vpc_id: "{{ _vpc.vpc.id }}" rules: >- {%- if item.value.rules|length == 1 -%} {{ item.value.rules }} {%- else -%} {{ item.value.rules | join(",") }} {%- endif -%} profile: "{{ profile }}" region: "{{ region }}" with_dict: "{{ security_group }}"
⑥EC2構築
roles/ec2/vars/main.yml
に、EC2構築に関する設定のみ記載します。
owner: ubuntu group: ubuntu
EC2構築時に、キーペアを作っているのでpemファイルを保存する際のowner, groupを設定しています。
roles/ec2/tasks/main.yml
には、EC2構築するためのタスクを記載します。
- name: EC2キーペア作成 ec2_key: name: performance test key pair region: "{{ region }}" profile: "{{ profile }}" register: ec2_key - name: プライベートキーを保存 copy: content: "{{ ec2_key.key.private_key }}" dest: "/home/ubuntu/.ssh/performance_test.pem" mode: 0600 owner: "{{ owner }}" group: "{{ group }}" when: ec2_key.changed - name: EC2インスタンス構築 ec2: # EC2インスタンスの起動を待たないと、Elastic IPを割り当てでエラーになる wait: yes key_name: "{{ ec2_key.key.name }}" profile: "{{ profile }}" region: "{{ region }}" instance_type: t2.nano # Ubuntu Server 18.04 LTS (HVM), SSD Volume Typeのイメージ image: ami-09b68f5653871885f vpc_subnet_id: "{{ _subnet.results | selectattr('item.route', 'equalto', 'Public') | map(attribute='subnet.id') | first }}" group: - "{{ security_group.common.group_name }}" - "{{ security_group.web_server.group_name }}" instance_tags: Name: Performance test ec2 # count_tag, exact_countで、同じEC2インスタンスが複数できないように count_tag: Name: Performance test ec2 exact_count: 1 volumes: - device_name: /dev/sda1 volume_type: gp2 volume_size: 8 delete_on_termination: true register: ec2 - name: EC2インスタンスに新しいElastic IPを割り当てる ec2_eip: region: "{{ region }}" state: present device_id: "{{ ec2.instances[0].id }}" profile: "{{ profile }}" when: ec2.instances is defined and (ec2.instances|length>0) register: eip
⑦RDS構築
roles/rds/vars/main.yml
に、DBの接続情報などRDS構築に関する設定のみ記載します。
rds: db_name: performance_testing_production db_user: XXXXX db_password: XXXXXXXXXXXXXX
roles/rds/tasks/main.yml
には、RDS構築するためのタスクを記載します。
- name: rds-subnet-group作成 rds_subnet_group: name: Performance test rds subnet group description: Performance test rds subnet group description state: present subnets: "{{ _subnet.results | selectattr('item.route', 'equalto', 'Private') | map(attribute='subnet.id') | list }}" profile: "{{ profile }}" region: "{{ region }}" register: rds_subnet_group - name: セキュリティグループIDを取得 ec2_group_facts: filters: group-name: performance test db server profile: "{{ profile }}" region: "{{ region }}" register: group_fact - name: RDSインスタンス構築 rds: command: create force_failover: no instance_name: performance-test-rds username: "{{ rds.db_user }}" password: "{{ rds.db_password }}" db_name: "{{ rds.db_name }}" subnet: Performance test rds subnet group vpc_security_groups: "{{ group_fact.security_groups[0].group_id }}" db_engine: postgres engine_version: 10.6 license_model: postgresql-license instance_type: "db.t2.micro" size: "20" tags: Name: "{{ rds.db_name }}" profile: "{{ profile }}" region: "{{ region }}" register: rds
実行と確認
以下のコマンドを実行します。
$ sudo ansible-playbook build_aws.yml
事前にansibleインストール方法の記事で書いたようにローカル環境でプロファイル登録してあるので、AWSへの接続情報などを指定しなくてもaws-cliを実行できます。
構築できたかEC2にSSH接続して確認します
$ ssh -i ~/.ssh/performance_test.pem ubuntu@ec2-【Elastic IPで割り当てたIP】.ap-northeast-1.compute.amazonaws.com
参考資料
AnsibleでAWSモジュールを使う | mediba Creator × Engineer Blog AnsibleによるVPCの構成管理 | DevelopersIO