こんにちは、CI部の柿﨑です。
10/16(水)より、beatmania IIDX 27 HEROIC VERSE が稼働し始めました。
最近は1日1クレを日課にしておりまして、5年のブランクを経て皆伝取得を目指しております。(以前は中伝でした。)
どの分野にも限らず、資格の取得には日々の積み重ねが大事だと思っている今日この頃です。 今回は、前回のAnsible入門の続きを題材にしていこうと思います。
Playbook内で変数を使うことで可読性や保守性を高めていきましょうというのが、主題となります。
本記事の対象者
- 前回のAWS環境を準備できる方
- AWS環境にてサクッとAnsibleに触りたい方
本記事のコンセプト
- なるべくシンプルに
- 最低限使えるディレクトリ構成でAnsibleの動作を理解する
前提条件
- 前回の前提条件を満たしつつ、前回同様の環境を準備する
※AnsibleサーバーでAnsibleを使えればおk!
目次
- 変数を使ってみよう
- Playbookのタスクを効率的に書いてみよう
- Playbookを暗号化してみよう
- さいごに
1.変数を使ってみよう
前回のPlaybookでは、tasks/main.yml
ファイルを以下のように(一部抜粋)記載していました。
- name: create user user: name: hands-on-user01 createhome: yes state: present password: "{{ 'hands-on' | password_hash('sha512') }}"
簡単に書くと各パラメーターをそのまま記載していますね。
Playbookの構文がこれだけならまだ良いですが、実案件で使っていくとコードが膨らんでいくものです。
こんなときにパラメーターを変数化しておくことで、コードを管理しやすくしてくれます。
※お急ぎの方用ですが、最終系は以下のコードになります。そうでない方はパスしてください。
git clone https://github.com/ikayarou/hands-on-02.git
では早速、変数を使えるようにPlaybookを修正していきましょう。
※今回、tasks/main.yml
ファイル内のsshd_configは触りません。
- Ansibleサーバーに
ec2-user
でSSH接続 - 前回のPlaybookがある場合は
cd ~/hands-on-01
を実行
Playbookがない場合は、以下の手順を実行
cd git clone https://github.com/ikayarou/hands-on-01.git cd hands-on-01
- 変数格納用の
defaults/main.yml
ファイルを作成
mkdir roles/hands-on/defaults vi roles/hands-on/defaults/main.yml
以下の内容で保存
--- # hands-on user name: hands-on-user01 home: yes state: present remove: no password: hands-on
tasks/main.yml
を変数が使えるように修正
vi roles/hands-on/tasks/main.yml
以下の内容で保存
- name: create users user: name: "{{ name }}" createhome: "{{ home }}" state: "{{ state }}" remove: "{{ remove }}" password: "{{ password | password_hash('sha512') }}" - name: change hostname hostname: name: "{{ inventory_hostname }}" - name: modify sshd_config lineinfile: dest: /etc/ssh/sshd_config state: present backrefs: yes regexp: '^PasswordAuthentication no' line: 'PasswordAuthentication yes' notify: - restart sshd
- Playbookを実行し、SSH接続
sudo ansible-playbook -i inventory/hosts site.yml ssh hands-on-user01@192.168.20.4 ※パスワード、hands-on を入力しEnter
上記手順を実行した先で、以下の状態を確認できればおkです。
※ホスト名がClient01でなく、Clinet01だったらごめんなさい。このブログ更新前のhands-on-01が間違ってました。(Gitコード修正済み)
[hands-on-user01@Client01 ~]$ hostname Client01 [hands-on-user01@Client01 ~]$
ひとつずつ説明いたします。
まず、tasks/main.yml
ファイルですが、パラメーターを変数化するときは以下の形になります。
※passwordのところだけやや違いますが、そこは公式ドキュメントに記載があります。
"{{ 変数名 }}"
変数名をなるべく分かりやすい名称にして、各パラメーターを置き換えていけばおkです!
また、以下の項目を追加しました。
remove: "{{ remove }}" ※のちの手順で使うため追加
- name: change hostname hostname: name: "{{ inventory_hostname }}" ※対象サーバーのホスト名を変更するタスク
前者はのちの手順で説明します。
後者の変数に関しては次のdefaults/main.yml
ファイルと一緒に説明します。 次にdefaults/main.yml
ファイルですが、tasks/main.yml
ファイルで指定されている変数と変数の値が記載されております。
# hands-on user name: hands-on-user01 home: yes state: present remove: no password: hands-on
このdefaults
ディレクトリをhands-on
ロール配下に作成することで、当該ロールで使用される変数のデフォルト値を定義することができます。
これと似た機能を持つvars
ディレクトリというものがあり、どちらも変数を定義することができます。
今回はガッツリAnsibleを触る段階ではありませんので、変数の上書きが容易にできて扱いやすいdefaults
ディレクトリを使う方がベターだと考えておkです。 ここでお気づきの方もいるかもしれないですが、defaults/main.yml
ファイルに"{{ inventory_hostname }}"
のパラメーターが記載されていません。
しかし、Client01サーバーのホスト名がClient01
に設定されていました。
これは何かといいますと、マジック変数と呼ばれる機能になります。
こちらに分かりやすく記載されています。
以下画像の赤丸部分の値を引っ張ってきたわけですね!ありがとうAnsible。わざわざ変数のパラメーターを書く必要がありませんので、とても楽ですね♪
2.Playbookのタスクを効率的に書いてみよう
ここまでで変数を使えるようになりました。
ただし、このままの状態でOSのユーザーをいくつも作ってくれえ!
と、頼まれたらどうするのでしょうか。
タスクをコピペして以下のようにしてみたりするかもしれません。
- name: create users_1 user: name: "{{ name_1 }}" createhome: "{{ home_1 }}" state: "{{ state_1 }}" remove: "{{ remove_1 }}" password: "{{ password_1 | password_hash('sha512') }}" - name: create users_2 user: name: "{{ name_2 }}" createhome: "{{ home_2 }}" state: "{{ state_2 }}" remove: "{{ remove_2 }}" password: "{{ password_2 | password_hash('sha512') }}"
こうするとdefaults/main.yml
ファイルも変数のパラメーターを記述していかないといけません。
想像するだけでもしんどいですよね。
そこでwith_items
と呼ばれるものを使ってみます。 with_items
をざっくり説明すると、リスト型や辞書型などのパラメーターの数だけタスク処理をループしてくれるものです。
つまり1つのタスクだけ準備して、パラメーターを複数設定すればおkです。
早速、作成するユーザーを3つに増やして書いてみましょう!
tasks/main.yml
ファイルにwith_itemsを追記
cd ~/hands-on-01 vi roles/hands-on/tasks/main.yml
以下の内容で保存
--- - name: create users user: name: "{{ item.name }}" createhome: "{{ item.home }}" state: "{{ item.state }}" remove: "{{ item.remove }}" password: "{{ item.password | password_hash('sha512') }}" with_items: "{{ users }}" - name: change hostname hostname: name: "{{ inventory_hostname }}" - name: modify sshd_config lineinfile: dest: /etc/ssh/sshd_config state: present backrefs: yes regexp: '^PasswordAuthentication no' line: 'PasswordAuthentication yes' notify: - restart sshd
defaults/main.yml
ファイルの変数の書き方を修正
vi roles/hands-on/defaults/main.yml
以下の内容で保存
--- users: # hands-on - name: hands-on-user01 home: yes state: present remove: no password: hands-on # ika - name: user-ika home: yes state: present remove: no password: ika # tako - name: user-tako home: yes state: present remove: no password: tako
- Playbookを実行し、SSH接続、ユーザー確認
sudo ansible-playbook -i inventory/hosts site.yml ssh user-ika@192.168.20.4 ※パスワード、ika を入力しEnter cat /etc/passwd ※末尾に3つのユーザーが追加されていれば成功
こちらもひとつずつ説明していきます。 今回はwith_items
のパラメーターを変数化していますので、その前提で説明します。
tasks/main.yml
ファイルとdefaults/main.yml
ファイルの関係は以下の画像のとおりです。
with_items
がuser
モジュールと同じインデントになっていることに注意してください。
これはuser
モジュールの機能でないことを意味しています。
もし共通の設定があるようでしたら、そこだけwith_items
とは別の変数として定義すれば、defaults/main.yml
ファイルのハッシュの数が減ります。 ではここで、user-ika
だけ削除してみましょう。
defaults/main.yml
ファイルを変更
※user-ikaユーザーでログインしている場合は、exit でAnsibleサーバーへ戻ってください。 cd ~/hands-on-01 vi roles/hands-on/defaults/main.yml
以下の内容で保存
--- users: # hands-on - name: hands-on-user01 home: yes state: present remove: no password: hands-on # ika - name: user-ika home: yes state: absent remove: yes password: ika # tako - name: user-tako home: yes state: present remove: no password: tako
# ika
のstate:
とremove:
の値だけ変更しています。
※ここのために今回のハンズオンにてremove:
を追加しました。
詳しくはこちらのremoveの説明を参照ください。
- Playbookを実行し、SSH接続確認、ユーザー確認
sudo ansible-playbook -i inventory/hosts site.yml ssh user-ika@192.168.20.4 ※パスワード、ika を入力しEnter ※接続できないことを確認 ssh user-tako@192.168.20.4 ※パスワード、tako を入力しEnter cat /etc/passwd ※user-ika の表示が消えていれば成功
このようにして1つのタスクで複数のユーザーを同時に作成したり、特定のユーザーだけ削除したりということができました!
3.Playbookを暗号化してみよう
最後はPlaybookを暗号化してみましょう! ときに平文で載せたくない情報もあると思われます。
例えば、OSユーザーのパスワードですね。
主な暗号化のパターンとしては、Playbookのファイル内全てを暗号化するもの、
ファイル内の一部を暗号化するものの2パターンになります。
今回はファイル内の一部を暗号化するansible-vault encrypt_string
を使っていきます。
- パラメーターを暗号化する
※user-takoユーザーでログインしている場合は、exit でAnsibleサーバーへ戻ってください。
cd ~/hands-on-01 ansible-vault encrypt_string 'hands-on' --name 'password'
パスワードの入力とを求められるため、serverworks と入力、確認用にもう1回
以下の文字列が出力されるため、Encryption successful
の上の行までコピー
password: !vault | $ANSIBLE_VAULT;1.1;AES256 63623934306536633137313638633733336134393731656239343334393461313834383137303439 6231326361336363373730393964643064363632616637340a623163636466326231623164636334 35313834613065316134616234396433303766313662306634653230396532623133626434663138 3630636133306365650a633061323137313334633139366566656163616335396537323330373232 6238 Encryption successful
defaults/main.yml
ファイルを変更する
vi roles/hands-on/defaults/main.yml
以下のように前の手順でコピーした値で、# hands-on
のpassword:
を上書きする
users: # hands-on - name: hands-on-user01 home: yes state: present remove: no password: !vault | $ANSIBLE_VAULT;1.1;AES256 63623934306536633137313638633733336134393731656239343334393461313834383137303439 6231326361336363373730393964643064363632616637340a623163636466326231623164636334 35313834613065316134616234396433303766313662306634653230396532623133626434663138 3630636133306365650a633061323137313334633139366566656163616335396537323330373232 6238 # ika - name: user-ika home: yes state: present remove: no password: ika # tako - name: user-tako home: yes state: present remove: no password: tako
- Playbookを実行
sudo ansible-playbook -i inventory/hosts site.yml --ask-vault-pass ※パスワードを聞かれるため、serverworks と入力しEnter
エラーがなければ完了
実行結果には以下のように暗号化されていたパラメーターが平文で出力されてしまいます。
ここからの情報流出には注意が必要ですね! ansible-vault encrypt_string
で暗号化するときは、以下のような構文となります。
ansible-vault encrypt_string '暗号化する値' --name '変数名'
このようにピンポイントで暗号化をしておくと、暗号化されたファイルをいちいち複合化して編集、という手間が減ります。
そして、Playbookが暗号化されている場合は、ansible-playbook
コマンドに--ask-vault-pass
オプションを付与する必要があることにもご注意ください。
オプションなしで実行しますと、当然のようにエラーになるだけですので大きな問題はないです。 ほかにも方法はございますが、今回はおまけ程度ということでサラッと暗号化に触れてみました。
さいごに
今回の内容だけでも、それなりにAnsibleを触れるようになると思われます。
ここからは、複数台のサーバーを管理するイメージを持ちつつ、Playbookをどのように書けば効率的か、保守性が高いかを意識していくことで、
オレ流のベストプラクティスが生まれてくるものと思います。
私もまだまだ知らないことばかりですので、ここはこうした方がいいよ!などの情報がありましたら、教えていただけますとうれしいです。