Let's Encrypt と Ansible でらくらく SSL 設定をする

## まえがき

[**Let's Encrypt**](https://letsencrypt.jp/) がサービス開始してから、手軽かつ無料で Web サイトを SSL 化することができるようになりました。**SEO 効果**や **セキュリティ向上**のため、常時 SSL 化などの需要もあると思います。

ちょうど最近 Let's Encrypt を利用してSSLの設定をする機会があったのと、将来も SSL の設定をする機会はありそうなので自動化したいと思っていたところ、 Gihhub で [**thefinn93/ansible-letsencrypt**](https://github.com/thefinn93/ansible-letsencrypt) という **Ansible** スクリプトを見つけたので使ってみることに。

~~**git clone** でコードを取得..~~ どうやら **ansible-garaxy** に対応しているということで、**ansible-garaxy** を利用して取得、実行してみようと思います。

目標は **面倒な SSL 取得周りのコマンドを全て自動で行う** こと

以下いろいろ書いてありますがザックリとまとめると、
> 
**Ansible の設定ファイル　(hosts, playbook.yml) を作成して、実行すると /etc/letsencrypt に証明書が取得できるから後は好きに使ってください** 

というだけの内容です。つまり、そういうことです。

## 内容

- **前提条件**
- **自動化の内容**
- **Ansible で Let's Encrypt の SSL 証明書の取得**
- **Nginx の設定**
- **まとめ**


## 前提条件

- Ansible バージョン2.0以上 がインストールされている
  - `ansible --version` コマンドで確認できます
- すでにドメインの取得が終わっていて、サーバに割り当てられている

>
```bash
nslookup example.com # example.com は 自分が取得したドメイン
```
とやって
>
```bash
Name:	example.com
Address: 123.456.789.012 # こんな IP 存在しない。
```
>
と表示されていれば平気だと思います。

(自分が試した OS は Ubuntu 14.04 のみですが、他の OS でも動作するみたいです)

## 自動化の内容

- SSL 証明書などを Let's Encrypt を利用して取得し、`/etc/letsencrypt` 以下に設置する
- 証明書自動更新用の cron タスクの追加

## Ansible で Let's Encrypt の SSL 証明書の取得

### コードの取得

```bash
ansible-galaxy install thefinn93.letsencrypt -p ~/ansible
```

`~/ansible` は自分が ansible スクリプトをダウンロードしたいディレクトリを適当に決めてください。

### `hosts` にターゲットとなるサーバの IP を記述

```text:~/ansible/hosts
[web]
123.456.789.0
```

### `playbook.yml` の編集

```yaml:~/ansible/playbook.yml
- hosts: web
  remote_user: ubuntu # サーバアクセス時の SSH ユーザ名
  roles:
    - thefinn93.letsencrypt
  vars:
    letsencrypt_webroot_path: /var/www/html
    letsencrypt_email: your-username@something.com # メールアドレス。通知がくることがある(?)
    letsencrypt_cert_domains: # 証明書を取得したいドメインのリスト
      - example.com
      - www.example.com
    letsencrypt_renewal_command_args: '--renew-hook "systemctl restart nginx"'
```

### Ansible の実行

```
cd ~/ansible
ansible-playbook playbook.yml -i hosts
```

*Nginx などのサーバが動作している場合は、一度プロセスを停止させておかないとエラーが出るかもしれません。*

### 正しく実行できたか確認

```
/etc/letsencrypt
```
上記のディレクトリが生成さてていて、`/etc/letsencrypt/live` ディレクトリに該当する証明書などが作成されていれば成功。

さらに、証明書を自動更新するための cron タスクも追加されていることも確認しておく。

```
sudo crontab -l
```

```bash:結果
#Ansible: Let's Encrypt Renewal
0 0 * * * /usr/local/share/letsencrypt/env/bin/letsencrypt renew --renew-hook "systemctl restart nginx" > /dev/null
```


## Nginx の設定

動作確認さえしていない例ですが。

```nginx:nginx設定ファイル(例)
server {
    # http リクエストを https にリダイレクト (1/3)
    listen 80 default_server;
    server_name sample.com www.sample.com;
    return 301 https://$host$request_uri;
}

server {
  # SSL を取得したドメイン名を記述 (2/3)
  server_name sample.com www.sample.com;
  root /var/www/sample.com/;

  # これはログなので SSL と関係ないです
  access_log /var/log/nginx/sample.com.access;
  error_log /var/log/nginx/sample.com.error;

  # Lets Encrypt で取得した証明書などを指定 (3/3)
  listen 443 ssl;
  ssl_certificate /etc/letsencrypt/live/sample.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/sample.com/privkey.pem;
}

```

## まとめ

**Ansible** を用いて **Let's Encrypt** の証明書取得を自動で行いました。

今まで認証サービスのWebフォームから証明書取得の手続きをしたり、SSL関連のコマンドを使ったり(僕はよく忘れていて毎回ggるのですが...)していた作業が Lets' Encrypt のおかげで単純化され、Ansible などで自動化できるのはかなり楽に感じました。

僕自身はスクリプトのコマンドの内容などを気にせずに Ansible で一気にやってしまったのですが、より深い理解をする場合は [**Let's Encrypt 総合ポータル**](https://letsencrypt.jp/) などが参考になると思います。