AnsibleでAWS操作　EC2インスタンス編

# AnsibleでAWS操作シリーズ

1. [aws-cliインストール編](http://qiita.com/bakira/items/d94fc79a032b117bf87f)
1. EC2インスタンス編
1. [S3バケット編](http://qiita.com/bakira/items/a1dfe79cfd0e3acaa1a6)
1. [CloudFrontディストリビューション編](http://qiita.com/bakira/items/611e3a51677b751f8366)
1. [Simple Email Service編](http://qiita.com/bakira/items/8147fcc7cb684beedc63)
1. [Certificate Manager編](http://qiita.com/bakira/items/50bdd853ce71953e1600)
1. [Lambda編](https://qiita.com/bakira/items/d55c91328cd1f0ee9581)

# 関連記事

[aws-cli　コマンド一覧(随時追記)](http://qiita.com/bakira/items/8a9481c99ed56a367415)


# やりたかったこと

- EC2インスタンスに紐付けるSecurityGroupの作成/設定
- EC2インスタンスに紐付けるElastic IPの作成/設定/削除
- EC2インスタンスの作成/削除
- Elastic IPの関連付け
- ~~GUIを使わずに黒い画面でコマンドを「**ッターーン!**」してかっこつけたい~~

# やったこと

## 前提

- CIサーバー(`ansible`実行サーバー)構築済み
- CLIサーバー(`aws-cli`実行サーバー)構築済み
- `Ansible`インストール済み
- `aws-cli`インストール済み
- `jq`インストール済み
- 各サーバーへのSSH接続設定済み

※ `${~}`は各環境に合わせて値を設定してください。

## 作業フロー

1. SSH用のセキュリティグループを新規作成

```bash:command
ansible-playbook -i inventory/production create-aws-ec2-ssh-security-group.yml
```
- 戻り値の`GroupId`の値をvars/all.ymlの`SECURITY_GROUP_ID`に指定

2. EC2インスタンスを新規作成

```bash:command
ansible-playbook -i inventory/production create-aws-ec2-instance.yml
```
  - 戻り値の`InstanceId`と`AllocationId`をそれぞれ`INSTANCE_ID`と`ELASTIC_IP_ID`に指定

3. EC2インスタンスの初期設定

```bash:command
ansible-playbook -i inventory/production setup-aws-ec2-instance.yml
```

※`jq`で取得した各種IDを使って一つの`task`でやろうと思いましたが、`Instance`作成直後は`ElasticIP`の紐付けが出来ないっぽいので、`playbook`を分けています。


## ディレクトリ構成
```text

├── ansible.cfg
├── create-aws-ec2-instance.yml
├── create-aws-ec2-ssh-security-group.yml
├── inventory
│   └── production
│       └── inventory
├── roles
│   ├── create-aws-ec2-elastic-ip
│   │   └── tasks
│   │       └── main.yml
│   ├── create-aws-ec2-instance
│   │   └── tasks
│   │       └── main.yml
│   ├── create-aws-ec2-ssh-security-group
│   │   └── tasks
│   │       └── main.yml
│   ├── setup-aws-ec2-elastic-ip
│   │   └── tasks
│   │       └── main.yml
│   └── setup-aws-ec2-instance
│       └── tasks
│           └── main.yml
├── setup-aws-ec2-instance.yml
├── vars
│   └── all.yml
└── view-aws-ec2-instance.yml
```

## Ansible構成ファイル

### inventory

```ini:inventory/production/inventory
[ciservers]
${CIサーバーホスト}

[cliservers]
${CLIサーバーホスト}

[all:vars]
ENV=production

```

### vars

```yaml:vars/all.yml
AWS_EC2:
  SECURITY_GROUP_ID: ${セキュリティグループID}
  SECURITY_GROUP_NAME: ${セキュリティグループ名}
  SECURITY_GROUP_DESCRIPTION: ${セキュリティグループ概要}
  IP_ADDRESS: ${IPアドレス}
  KEY_PAIR_NAME: ${キーペア名}
  AMI_ID: ${AMI ID}
  INSTANCE_TYPE: ${インスタンスタイプ}
  INSTANCE_ID: ${インスタンスID}
  INSTANCE_NAME: ${インスタンス名}
  ALLOCATION_ID: ${Elastic IP ID}
```


### playbook

```yaml:create-aws-ec2-ssh-security-group.yml
- hosts: cliservers
  roles:
    - create-aws-ec2-ssh-security-group
  vars_files:
    - vars/all.yml
```

```yaml:create-aws-ec2-instance.yml
- hosts: cliservers
  roles:
    - create-aws-ec2-instance
    - create-aws-ec2-elastic-ip
  vars_files:
    - vars/all.yml
```

```yaml:setup-aws-ec2-instance.yml
- hosts: cliservers
  roles:
    - setup-aws-ec2-instance
    - setup-aws-ec2-elastic-ip
  vars_files:
    - vars/all.yml
```

### tasks

```yaml:role/create-aws-ec2-ssh-security-group/tasks/main.yml
- name: "Create SSH Security Group"
  shell: |
    aws ec2 create-security-group \
    --group-name {{ AWS_EC2.SECURITY_GROUP_NAME }} \
    --description '{{ AWS_EC2.SECURITY_GROUP_DESCRIPTION }}'
  register: result
  changed_when: False

- debug: var=result.stdout_lines
  when: result | success
  tags:
    - always

- name: "Setup SSH Security Group"
  shell: |
    aws ec2 authorize-security-group-ingress \
    --group-name {{ AWS_EC2.SECURITY_GROUP_NAME }} \
    --protocol tcp \
    --port 22 \
    --cidr "{{ AWS_EC2.IP_ADDRESS }}/0" \
    | jq '.'
  tags:
    - always
```

```yaml:role/create-aws-ec2-instance/tasks/main.yml
- name: "Create Instanse"
  shell: |
    aws ec2 run-instances \
    --image-id {{ AWS_EC2.AMI_ID }} \
    --count 1 \
    --instance-type {{ AWS_EC2.INSTANCE_TYPE }}  \
    --key-name {{ AWS_EC2.KEY_PAIR_NAME }} \
    --security-groups {{ AWS_EC2.SECURITY_GROUP_NAME }} \
    | jq -r '.Instances[] | { InstanceId }'
  register: create_instance_result
  changed_when: False

- debug: var=create_instance_result.stdout_lines
  when: create_instance_result | success
  tags:
    - always
```

```yaml:role/create-aws-ec2-elastic-ip/tasks/main.yml
- name: "Create Elastic IP"
  shell: |
    aws ec2 allocate-address \
    --domain vpc \
    | jq -r '{ AWS_EC2.ALLOCATION_ID }'
  register: result
  changed_when: False

- debug: var=result.stdout_lines
  when: result | success
  tags:
    - always
```

```yaml:role/setup-aws-ec2-instance/tasks/main.yml
- name: "Create Tags"
  shell: |
    aws ec2 create-tags \
    --resources {{ AWS_EC2.INSTANCE_ID }} \
    --tags Key=Name,Value={{ AWS_EC2.INSTANCE_NAME }}
  register: result
  changed_when: False

- debug: var=result.stdout_lines # stdout => stdout_lines
  when: result | success
  tags:
    - always

```

```yaml:role/setup-aws-ec2-elastic-ip/tasks/main.yml
- name: "Setup Elastic IP"
  shell: |
    aws ec2 associate-address \
    --allocation-id {{ AWS_EC2.ALLOCATION_ID }} \
    --instance {{ AWS_EC2.INSTANCE_ID }}
  register: result
  changed_when: False

- debug: var=result.stdout_lines # stdout => stdout_lines
  when: result | success
  tags:
    - always
```

正常に処理が終了したらインストール編で実行したplaybookを実行してみてください。
[インスタンス一覧取得playbook](http://qiita.com/bakira/items/d94fc79a032b117bf87f#playbook-1)

新しいインスタンスの情報が取得出来るはずです。

## おまけ　インスタンス及びElasticIPの削除

```yaml:delete-aws-ec2-instance.yml
- hosts: cliservers
  roles:
    - delete-aws-ec2-instance
    - delete-aws-ec2-elastic-ip
  vars_files:
    - vars/all.yml
```

### tasks

```yaml:role/delete-aws-ec2-instance/tasks/main.yml
- name: "Delete EC2 Instanse"
  shell: |
    aws ec2 terminate-instances \
    --instance-ids {{ AWS_EC2.INSTANCE_ID }}
  register: result
  changed_when: False

- debug: var=result.stdout_lines # stdout => stdout_lines
  when: result | success
  tags:
    - always
```

```yaml:role/delete-aws-ec2-instance/tasks/main.yml
- name: "Delete Elastic IP"
  shell: |
    aws ec2 release-address \
    --allocation-id {{ AWS_EC2.ALLOCATION_ID }}
  register: result
  changed_when: False

- debug: var=result.stdout_lines # stdout => stdout_lines
  when: result | success
  tags:
    - always
```

```bash:command
ansible-playbook -i inventory/production delete-aws-ec2-instance.yml
```

## 終わりに

インスタンスの作成や関連する設定もCLIから実行することが出来ます。
さらに各種設定値等もファイル内に残るので管理がしやすいです！

じゃあの。