【備忘録】Ansible応用編① EC2インスタンス作成から鍵認証ログインの自動化

## 環境

・[【備忘録】Ansible② Playbookとインベトリの書き方](https://qiita.com/Kento75/items/a5e89c5034200310f98f) で使用したEC2
・T2.micro（webサーバー）
 ・Python2.7.14（boto、awscliインストール済み）
・aws-cli設定済み

## インベントリ設定
Ansible.cfgに以下の設定を追加する。

StrictHostKeyChecking=no を指定することで初めて接続するホストに対しての接続許可（Yes/No）の確認を無効にできる。

private_key_file に設定した認証鍵を使用して、リモートホストに接続する。（今回作成するEC2の認証鍵）

```
[ssh_connection]
ssh_args = -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no
private_key_file = /home/ec2-user/.ssh/dev-key.pem
```

## Playbook作成
以下のPlaybookは /etc/ansible/hosts にホストを書き込むため、実行ユーザーに書き込み権限が必要。

```YAML
# ~/create-ec2.yml
- name: EC2インスタンス作成
  hosts: localhost
  connection: local
  gather_facts: False
  vars:
    keypair_name: dev-key   # 作成する認証鍵の名前
    ec2_name: test-ec2      # 作成するEC2の名前
    profile: default
    region: ap-northeast-1
  tasks:

  - name: AWSに認証鍵を登録
    ec2_key:
      name: "{{ keypair_name }}"
      region: "{{ region }}"       # リージョンの指定
      profile: "{{ profile  }}"    # プロフィールの指定
    register: keypair_regst

  - name: 認証鍵ファイル生成（権限：0600）
    file:
      path=~/.ssh/{{ keypair_regst.key.name }}.pem
      state=touch
      mode=0600

  - name: 認証鍵ファイルにデータを追加
    shell: echo "{{ keypair_regst.key.private_key }}" > ~/.ssh/{{ keypair_name }}.pem
    when: keypair_regst.key.private_key is defined

  - name: EC2インスタンスの生成
    ec2:
      instance_tags:
        Name: "{{ ec2_name }}"        # インスタンスの名前を指定
      key_name: "{{ keypair_name }}"  # インスタンスにログインするための認証鍵を指定
      instance_type: t2.micro         # インスタンスタイプを指定
      image: ami-0a2de1c3b415889d2    # Amazon Linux2 を指定 
      region: ap-northeast-1          # 東京リージョンを指定
      vpc_subnet_id: subnet-xxxxxxx   # サブネットを指定（ここは適宜変える）
      group: your-group-name          # セキュリティグループ名を指定（ここは適宜変える）
      wait: yes
      count: 1                        # インスタンスは1つ
      assign_public_ip: no
    register: ec2_regst

  - name: インベントリにホストを追加
    add_host:
      groups=my_host
      name="{{ ec2_regst.instances[0].private_ip }}"
      
  - name: 作成したEC2が接続可能状態になるまで待つ
    local_action: wait_for port=22 host="{{ ec2_regst.instances[0].private_ip }}" search_regex=OpenSSH delay=5

- name: EC2インスタンスにsshログイン
  hosts: my_host  # 作成時にインベトリに追加したグループを指定
  serial: 1
  user: ec2-user  # EC2 デフォルトユーザーを指定
  tasks:
    - debug:
      msg: "Hello world!"
```

## 実行結果

実行すると認証鍵の登録と、EC2の作成、ログイン、デバックログの表示まで実行される。

```
$ ansible-playbook create-ec2.yml
PLAY [EC2インスタンス作成] ***************************************************************************************************************************************************************************************************************************

TASK [AWSに認証鍵を登録] ****************************************************************************************************************************************************************************************************************************
changed: [127.0.0.1]

TASK [認証鍵ファイル生成（権限：0600）] ********************************************************************************************************************************************************************************************************************
changed: [127.0.0.1]

TASK [認証鍵ファイルにデータを追加] ************************************************************************************************************************************************************************************************************************
changed: [127.0.0.1]

TASK [EC2インスタンスの生成] **************************************************************************************************************************************************************************************************************************
changed: [127.0.0.1]

TASK [インベントリにホストを追加] *************************************************************************************************************************************************************************************************************************
changed: [127.0.0.1]

TASK [作成したEC2が接続可能状態になるまで待つ] *****************************************************************************************************************************************************************************************************************
ok: [127.0.0.1 -> localhost]

PLAY [EC2インスタンスにsshログイン] *********************************************************************************************************************************************************************************************************************

TASK [Gathering Facts] ***********************************************************************************************************************************************************************************************************************
ok: [xxx.xx.xx.xxx]

TASK [debug] *********************************************************************************************************************************************************************************************************************************
ok: [xxx.xx.xx.xxx] => {
    "msg": "Hello world!"
}

PLAY RECAP ***********************************************************************************************************************************************************************************************************************************
127.0.0.1                  : ok=6    changed=5    unreachable=0    failed=0   
xxx.xx.xx.xxx              : ok=2    changed=0    unreachable=0    failed=0  

```

## Permission denied 等のエラーが発生した場合

以下のディレクトリ、ファイルの権限を確認する。

| ディレクトリ or ファイル名              | 権限 |
| --------------------------------------- | ---- |
| /home/<ユーザー名>                      | 755  |
| /home/<ユーザー名>/.ssh                 | 700  |
| /home/<ユーザー名>/.ssh/authorized_keys | 644  |
| /home/<ユーザー名>/.ssh/known_hosts     | 644  |


[](https://qiita.com/Kento75/items/f714eb3ea9ccb65b01e1)
[](https://qiita.com/Kento75/items/a5e89c5034200310f98f)
[](https://qiita.com/Kento75/items/e1478fead92f70fb757e)