こんにちは、CI部の柿﨑です。
先日、洗濯槽の掃除をしようと専用の洗剤を入れたところ、黒い物体がたくさん浮いてきました。
どうやらn年間の汚れが溜まっていたようです。。。猛省。
つまり、何事も定期的なメンテナンスが必要ということですね!
と、いうことで!
定期的なメンテンスといえば、そう!!
Infrastructure as Code(以下Iac)ですね!
今回はIaCの中でも代表的なツールである、Ansible入門を題材にします。
なるべくシンプルな構成にしていますので、是非、ご一読いただければと思います。
本記事の対象者
- AWS環境にてサクッとAnsibleに触りたい方
- 初っ端Ansibleのベストプラクティスを見て、やる気を失った方
本記事のコンセプト
- なるべくシンプルに
- 最低限使えるディレクトリ構成でAnsibleの動作を理解する
- 今回はリモートにログインユーザーを作成し、パスワード認証でSSH接続します
前提条件
- 下記、構成図の環境を構築
- SSH接続にはteratermを使用
- 今回使用したAMIは
ami-0ff21806645c5e492
(Amazon Linux 2) - AnsibleサーバーはSSH接続、インターネット接続が可能なこと
- Client01サーバーはSGにてAnsibleサーバーからのSSH接続許可、秘密鍵名は
ansible-key.pem
、IPアドレスは192.168.20.4/32
目次
- Ansibleとは
- インストールからPlaybook実行
- さいごに
1.Ansibleとは
インフラ環境をコード化し、インフラ構成を管理するツール。→ 公式ドキュメント
Ansible用にコード化されたファイル群をPlaybookと呼び、Playbookを1度でも何度でも実行しようが、同じ結果が得られる冪等性という特徴がある。
対象ホストが多ければ多いほど、実行したPlaybookの処理が成功したときに気持ち良くなれる。(失敗したときは知りません。)
2.インストールからPlaybook実行
- Ansibleサーバーに
ec2-user
でSSH接続 - Ansibleサーバーにて以下コマンドを実行し、Ansibleをインストール
sudo yum -y install python-devel openssl-devel gcc git sudo easy_install pip sudo pip install ansible ansible --version ※最後にAnsibleのバージョンが表示されたら成功です。
- Client01サーバーの秘密鍵をAnsibleサーバーの
/home/ec2-user/.ssh/
配下に格納
以下のとおり、
ansible-key.pem
を確認できれば準備完了。
[ec2-user@ip-192-168-10-33 ~]$ ls -la .ssh/ total 8 drwx------ 2 ec2-user ec2-user 52 Sep 6 08:33 . drwx------ 4 ec2-user ec2-user 90 Sep 6 08:23 .. -rw-r--r-- 1 ec2-user ec2-user 1696 Sep 6 08:30 ansible-key.pem -rw------- 1 ec2-user ec2-user 394 Sep 6 08:02 authorized_keys [ec2-user@ip-192-168-10-33 ~]$
- 急いでる人用 (急いでいない人は、この手順を飛ばして5.の手順へお進みください。)
急いでいる人用にPlaybookをgitに上げましたので、そちらをAnsibleサーバーに格納して、Playbookを実行。
cd git clone https://github.com/ikayarou/hands-on-01.git cd hands-on-01 sudo ansible-playbook -i inventory/hosts site.yml ※SSHの接続確認をされるので、yesと入力しEnter
Playbookの実行に成功すると以下のように結果が出力される。
このPlaybookでは、Client01にパスワード認証でログインするユーザーを作成しました。
早速、接続確認を行ってみます。
ssh hands-on-user01@192.168.20.4 ※SSHの接続確認をされるので、yesと入力しEnter パスワード:hands-on を入力
SSH接続に成功出来たら完了です。
急いでいる人向けの内容は、ここで終わりです。 -
急いでいない人向け手順
以下のようなディレクトリ構造を順次作成していきます。まずはインベントリファイルから作成。
mkdir -p hands-on-01/inventory cd hands-on-01 cat << EOF > inventory/hosts [client_node] Clinet01 ansible_ssh_host=192.168.20.4 [client_node:vars] ansible_ssh_user=ec2-user ansible_ssh_private_key_file=/home/ec2-user/.ssh/ansible-key.pem EOF
[client_node]
はグループ名です。
グループ名を使うことで対象ホストをグルーピングすることができます。
この項目で対象ホストのIPアドレスを記述しています。
こちらに記載のansible_ssh_host=
はホスト変数と呼ばれ、このホストにのみ適用されます。
[client_node:vars]
は、[client_node]
グループに適用する変数を指定しています。
これをグループ変数と呼びます。
ansible_ssh_user=
では対象ホストにSSH接続するユーザー名、ansible_ssh_private_key_file=
ではSSH接続に使用する秘密鍵を指定しています。
このように設定することで、グループごとにSSH接続するユーザーを変えたり、パスワード認証でSSH接続したりすることが可能です。
続いて、site.yml
ファイルを作成します。
cd ~/hands-on-01 cat << EOF > site.yml --- - hosts: client_node become: True roles: - hands-on EOF
hosts:
では、Playbook実行対象のグループを指定します。
先ほど、hosts
ファイルに記述した[client_node]
ですね。
become:
を有効化することにより、リモートユーザーでの処理をsudo権限で実行してくれます。
roles:
では、実行するロールを指定します。今回はhands-on
ロールを実行します。
続いて、hands-on
ロールのtasks
ファイルを作成していきます。
cd ~/hands-on-01 mkdir -p roles/hands-on/tasks cat << EOF > roles/hands-on/tasks/main.yml --- - name: create user user: name: hands-on-user01 createhome: yes state: present password: "{{ 'hands-on' | password_hash('sha512') }}" - name: modify sshd_config lineinfile: dest: /etc/ssh/sshd_config state: present backrefs: yes regexp: '^PasswordAuthentication no' line: 'PasswordAuthentication yes' backup: yes notify: - restart sshd EOF
tasks
ファイルでは、リモートユーザーで実行したい処理を記述します。
ここで重要になってくるのが、user:
およびlineinfile:
です。
これらはモジュールと呼ばれ、各モジュールごとにAnsibleの処理が実装されています。
今回であれば、user
モジュールでユーザーを作成し、lineinfile
モジュールでsshd_config
ファイルの編集を行っています。
基本的には、各モジュールのドキュメントでパラメーターの内容を参照しつつ、Playbookを書いていきます。
user
モジュールのドキュメントはこちら、lineinfile
モジュールのドキュメントはこちら。
※細かいパラメーターの説明は公式ドキュメントにおまかせします。といいますのも、今回注目していただきたいパラメーターは
notify:
だからです。
このnotify:
が記述されているタスクが実行され、設定が変更された場合、notify:
に記述されているrestart sshd
が実行されます。
restart sshd
は後述するhandlers
にて定義されている処理です。
つまり、notify:
を記述することにより、sshd_config
ファイルの設定変更を契機として、handlers
ファイルの処理を呼び出すことが可能となります。それでは、最後に
handlers
ファイルを作成します。cd ~/hands-on-01 mkdir -p roles/hands-on/handlers cat << EOF > roles/hands-on/handlers/main.yml --- - name: restart sshd service: name: sshd state: restarted enabled: yes EOF
前述した
restart sshd
の正体がこのファイルになります。
service
モジュールにより、sshd
をリスタートすることで設定を反映させています。service
モジュールのドキュメントはこちら。
今回はディレクトリを分けましたが、1つのファイル内に記述することも可能です。
さて、これでPlaybookが完成しました。
早速、実行してみましょう。cd ~/hands-on-01 sudo ansible-playbook -i inventory/hosts site.yml ※SSHの接続確認をされるので、yesと入力しEnter
ansible-playbook
がPlaybookの実行コマンドで、-i
でインベントリファイルを指定、そしてPlaybookの起点となるsite.yml
を指定して実行しています。
エラーがなく正常に実行されたら、SSH接続の確認をして完了となります。ssh hands-on-user01@192.168.20.4 ※SSHの接続確認をされるので、yesと入力しEnter パスワード:hands-on を入力
hands-on-user-01
ユーザーで、パスワード:hands-on
を入力してSSH接続に成功すればハンズオンは完了です。
ちなみにですが、リモートユーザーでls -la /etc/ssh
と叩くと以下のようなファイルが存在するかと思われます。
-rw------- 1 root root 3957 Sep 9 08:06 sshd_config.3699.2019-09-09@08:11:41~
これは、lineinfile
モジュールのbackup: yes
とすることで、ファイル編集時に元ファイルのバックアップを作成してくれたりします。
便利ですね♪
3.さいごに
AnsibleはモジュールをベースにPlaybookを書いていきますので、コードが標準化されるという利点がございます。
そのため、誰が見てもコードが理解しやすく、IaCやコードに不慣れな方の入口として最適だと思われます。
逆をいえば、複雑に書かないでくださいということですね!
Ansibleの思想として、チームでコードを管理するために分かりやすい記述を心がける必要があります。
もし、複雑な処理を実行したい場合は、AnsibleではなくほかのIaCツールをご検討いただくのが無難です。
Ansibleのベストプラクティスについては、こちらの方が分かりやすく書いてくれています。
今回作成したPlaybookと見比べると、ずいぶん違いますね!
ベストプラクティスの方は、最初から手をつけるにはいろいろと知らなければいけないことが多いです。
そのため、今回のPlaybookを理解しつつ、改善を積み重ねていくことでベストプラクティスへの理解も深まっていくものと思われます。
例えばここで、変数を使っていったり・・・というのを書こうと思っていましたが、どうやら時間切れのようです。
また、機会がありましたら続きを書きます。
最後に簡単な課題としまして、余っているプライベートサブネットにサーバーを作成して、今回作成したサーバーと2台同時にPlaybookを実行してみてください。
これができますと、いくつものサーバーに対してPlaybookを実行するのも容易になるものと思われます。
本記事が、皆様のお役に立てれば幸いでございます。