Ansibleを使ってWebサーバを構築します。
要件は下記のとおりです。
- ローカルホストをターゲットノードとする
- MWはNginxを用いる
- 自己証明書を用いてhttps化する
この要件を満たすようにplaybookを作成します。
具体的な処理は以下一覧
- Nginxをインストールする
- pipをインストールする
- pyOpenSSLをインストールする
- 自己証明書配置先ディレクトリを作成
- 秘密鍵を作成
- 変数読み込み
- CSR(証明書要求)を作成
- 証明書を作成
- Nginxの設定ファイルを配置
- Nginxを再起動
※ aptは既にインストールされているという前提です。
使用環境
・ ゲストOS: Windows10 Home
・ ホストOS: Ubuntu20.04(Ansibleを実行するホストです)
・ Ansible: 2.9.6
ディレクトリ構成
/etc/ansible/
│ ## playbook本体
├ test1.yml
├ files
│ ## CSR発行時に使用する変数
├ certificate_vars.ini
│ ## nginxの設定ファイル
└ nginx_ssl.conf
playbookのtaskがroleに分割されていない、ファイルが用途に関わらず同じディレクトリに配置されているなど典型的なアンチパターンになっていますが、お試しということでひとまずこれでいきます。
実装例
---
- hosts: localhost
become: yes
# 1. Nginxをインストールする
tasks:
- name: Install Nginx
apt:
name: nginx
state: latest
# 2. pipをインストールする
- name: Install pip
apt:
name: pip
state: latest
# 3. pyOpenSSLをインストールする(鍵発行用)
- name: Install pyOpenSSL
pip:
name:
- pyOpenSSL
# 4. 自己証明書配置先ディレクトリを作成
- name: nginx ssl directory
file: path=/etc/nginx/ssl state=directory owner=root group=root mode=00755
# 5. 秘密鍵を作成
- name: Create Private Key
openssl_privatekey:
path: /etc/nginx/ssl/server.key
state: present
# 6. 変数読み込み
- name: Include Vars File
include_vars: "/etc/ansible/files/certificate_vars.ini"
# 7. CSR(証明書要求)を作成
- name: create CSR
openssl_csr:
commonName: "{{ca_cn}}"
countryName: "{{ca_c}}"
emailAddress: "{{ca_email}}"
localityName: "{{ca_l}}"
organizationName: "{{ca_o}}"
organizationalUnitName: "{{ca_ou}}"
stateOrProvinceName: "{{ca_st}}"
path: /etc/nginx/ssl/server.csr
privatekey_path: /etc/nginx/ssl/server.key
state: present
# 8. 証明書を作成
- name: ensure self signed certificate
openssl_certificate:
csr_path: /etc/nginx/ssl/server.csr
path: /etc/nginx/ssl/server.crt
privatekey_path: /etc/nginx/ssl/server.key
provider: selfsigned
state: present
# 9. Nginxの設定ファイルを配置
- name: deploy nginx_ssl.conf
copy:
src: /etc/ansible/files/nginx_ssl.conf
dest: /etc/nginx/conf.d
# 10. Nginxを再起動
- name: Start Nginx
service:
name: nginx
state: started
---
#commonName
ca_cn: oreoreCA.fugafuga
#countryName
ca_c: JP
#emailAddress
ca_email: fugafuga@example.com
#localityName
ca_l: Shibuya
#orgName
ca_o: hoge company
#orgUnitName
ca_ou: hoge division
#PrefName
ca_st: Tokyo
server {
# 443番ポートを許可し、SSL機能をON
# listen 80;
listen 443 ssl;
# 証明書を設定
ssl_certificate /etc/nginx/ssl/server.crt;
ssl_certificate_key /etc/nginx/ssl/server.key;
}
playbookと各種ファイルを作成し、以下のコマンドを実行します。
cd /etc/ansible
ansible-playbook /etc/ansible/test1.yml
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit
localhost does not match 'all'
PLAY [localhost] ******************************************************************************
TASK [Gathering Facts] ************************************************************************
ok: [localhost]
TASK [Install Nginx] **************************************************************************
ok: [localhost]
TASK [Install pip] ****************************************************************************
ok: [localhost]
TASK [Install pyOpenSSL] **********************************************************************
ok: [localhost]
TASK [nginx ssl directory] ********************************************************************
ok: [localhost]
TASK [Create Private Key] *********************************************************************
ok: [localhost]
TASK [Include Vars File] **********************************************************************
ok: [localhost]
TASK [create CSR] *****************************************************************************
ok: [localhost]
TASK [ensure self signed certificate] *********************************************************
ok: [localhost]
TASK [deploy nginx_ssl.conf] ******************************************************************
ok: [localhost]
TASK [Start Nginx] ****************************************************************************
changed: [localhost]
PLAY RECAP ************************************************************************************
localhost : ok=11 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
failed=0になればokです。
使用モジュール
① aptモジュール
用途
aptパッケージを管理します。
主なパラメータ
パラメータ | 主な値 | 説明 |
---|---|---|
name | 対象パッケージ | インストールする パッケージを指定 |
state | present,absent,latest | パッケージの状態を指定 |
② fileモジュール
ファイルやディレクトリを操作します。
よく使いそう
主なパラメータ
パラメータ | 主な値 | 説明 |
---|---|---|
path | 任意のディレクトリ | ファイルを作成・配置するパス |
state | file,directory,link | 作成するリソースの種類 |
mode | 0755, u+rwx | ファイルの権限を指定 |
③ openssl_privatekeyモジュール
秘密鍵を管理します。(使用にあたってpyOpenSSLパッケージが必要です)
主なパラメータ
パラメータ | 主な値 | 説明 |
---|---|---|
path | 任意のディレクトリ | 鍵の名前・配置先 |
backup | no,yes | 上書きする際にバックアップを作成するかどうか |
mode | 0755, u+rwx | ファイルの権限を指定 |
size | 2024,4096 | 鍵の大きさを指定 |
type | RSA, DSA | 鍵生成時のアルゴリズム。 デフォルトではRSA |
④ openssl_csrモジュール
CSR(証明書要求)を作成します。
※ pyOpenSSLが必要です
主なパラメータ
パラメータ | 主な値 | 説明 |
---|---|---|
path | 任意のディレクトリ | CSRの配置先 |
privatekey_path | 秘密鍵のパス | 証明書要求を送る際に使う 秘密鍵のパス |
⑤ openssl_certificateモジュール
サーバ証明書を作成します。
※pyOpenSSLが必要です
主なパラメータ
パラメータ | 主な値 | 説明 |
---|---|---|
csr_path | CSRのパス | 証明書要求のパス |
privatekey_path | 秘密鍵のパス | 秘密鍵のパス |
provider | selfsigned, ownca | 証明書の発行元 |
⑥ copyモジュール
ファイルをターゲットノードにコピーします。
これもよく使いそう
主なパラメータ
パラメータ | 主な値 | 説明 |
---|---|---|
src | 任意のファイル | コピーするファイル |
dest | 任意のディレクトリ | コピー先ディレクトリ |
remote_src | yes,no | yesの場合、ターゲットノード間でファイルをコピーする |
まとめ
Ansibleを使うとサーバの状態がコードで管理されるので便利です。
設定ファイルの書き換えや作成については、srcモジュールでコントロールノードから配置するのか
文字列置換をするのがよいか分かりません。(そのあたりのベストプラクティスをまた調べる必要がありそうです。)