LoginSignup
4

posted at

updated at

今さらAnsibleに入門してみた(EC2でハンズオン)

パブリッククラウド全盛の現代ですが、OSレイヤーの構築自動化や構成管理用途でAnsible使われてる方は結構いるんじゃないでしょうか。

私もちゃんと勉強したことなかったので、Kindle Unlimitedでこの本を読みつつ、手元のAWS環境でハンズオンもしてみました。

Ansibleとは

  • Python製のIT自動化ツール
  • OSSだが、Red Hat社が「Red Hat Ansible Automation Platform」としてサポートを提供している
  • 自動化対象のノードにエージェントのインストールが不要。SSH接続できてPythonが利用できればOK

基本概念

  • 自動化したい内容を「プレイブック」としてYAMLで定義する
  • 自動化可能な処理は「モジュール」として提供されている。モジュールは日々追加開発されている

私はもともと、AnsibleってシェルスクリプトのようにOSコマンドを羅列して自動化定義するものかとイメージしていたので、実際のプレイブックのサンプルを見て少し驚きました。

配布形態

リリースサイクル短縮のため、本体と追加機能が別パッケージになっている。

  • ansible-core:本体+基本モジュール
  • コレクション:その他のモジュールやプラグイン
    • Ansible Community Packageを利用すれば、本体+推奨コレクションをまとめてインストールできる

構成

  • コントロールノード:Ansibleをインストールするノード
    • Python 2.7以上 or 3.5以上が入っていること
  • マネージドノード:自動化対象のノード
    • Python 2.6以上 or 3.5以上が入っていること
    • SSH接続ができること
    • SFTP or SCPでファイル転送ができること

Ansibleのコンポーネントは以下。

  • モジュール
    • 特定の処理が作り込まれた機能の単位のこと
    • パラメータを指定することで詳細を定義する
    • 冪等性が考慮されているため、現在の状態を確認して分岐…などの考慮は不要
  • インベントリ
    • 自動化対象ノードの一覧。INI or YAMLで記述する
    • ホストをまとめるグループも定義できる
    • ホストやグループ内で共用できる「インベントリ変数」を定義できる
  • プレイブック
    • マネージドノードへの処理をYAMLで記述する
    • いくつかのセクションに分かれている
      • hosts:対象ホストやグループを指定する
      • vars:プレイ内で利用する変数を定義する
      • tasks:処理内容をモジュール+パラメータで指定する
    • ファイル内で上から順にタスク処理される。繰り返しや条件制御も可能
    • ansible-playbook コマンドで実行できる
  • プラグイン
    • 補完機能。いくつかの種別がある
      • コネクションプラグイン:マネージドノードへの接続に関するプラグイン群
      • コールバックプラグイン:プレイブック実行結果の出力に関するプラグイン群
  • 設定ファイル(ansible.cfg)
    • INIで記述する。いくつかのセクションに分かれる
    • 配置可能な場所がいくつかある。どこにも無ければデフォルト設定で動作する
    • ansible-config コマンドで設定状況を確認できる
  • コレクション
    • ansible-core に含まれないモジュール、プラグイン、プレイブックの管理単位
    • FQCNという名前空間で指定する
    • Ansible Galaxyというサイトで配布されている
    • ansible-galaxy コマンドでコレクション確認やインストールができる
    • requirements.yml を記述して一括インストールも可能

実際に触ってみた

AWSでサーバーを立てて、Ansibleを使ってみることにします。
サーバーワークスさんのこちらの記事を参考にさせていただきました。

環境準備

  • VPCを作成
    • マルチAZ(利用するのは片方のAZのみ)
    • パブリックサブネットにEC2を作成
      • ansible-controller:コントロールノード
    • プライベートサブネットにEC2を作成
      • ansible-managed:マネージドノード

コントロールノードにAnsibleをインストール
※Amazon Linux 2ではExtrasで有効化するとyumから利用できる(参考記事

$ sudo amazon-linux-extras enable ansible2
$ sudo yum install -y ansible

インストールされたことを確認

$ ansible --version
ansible 2.9.23
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/home/ec2-user/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 2.7.18 (default, May 25 2022, 14:30:51) [GCC 7.3.1 20180712 (Red Hat 7.3.1-15)]

etc/ansible 配下にインベントリおよび設定ファイルがあるようです。

$ ls /etc/ansible
ansible.cfg  hosts  roles

nanoエディターでhostsを開き、インベントリーにマネージドノードのIPアドレスを追加してみます。

$ sudo nano /etc/ansible/hosts

スクリーンショット 2022-12-24 14.44.28.png

プレイブック作成&SSH接続

Apacheを起動するだけの簡単なプレイブックを作成してみます。

$ nano playbook.yml

ファイル内には以下を記述。Tabを使うとエラーになるため注意!

playbook.yml
---
- hosts: 10.0.141.23

  tasks:
    -  name: start httpd
       ansible.builtin.systemd:
         name: httpd
         state: started

試しに一度、このプレイブックを実行してみます。

$ ansible-playbook playbook.yml 

PLAY [10.0.141.23] *************************************************************************************************

TASK [Gathering Facts] *********************************************************************************************
The authenticity of host '10.0.141.23 (10.0.141.23)' can't be established.
ECDSA key fingerprint is SHA256:Ul7RSyNiC5QWSEF0ov88qucD1OQMs303BY7oeCLjBQI.
ECDSA key fingerprint is MD5:28:57:5b:9b:89:32:3e:d6:fc:92:ed:42:94:e9:12:9e.
Are you sure you want to continue connecting (yes/no)? yes
fatal: [10.0.141.23]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: Warning: Permanently added '10.0.141.23' (ECDSA) to the list of known hosts.\r\nPermission denied (publickey,gssapi-keyex,gssapi-with-mic).", "unreachable": true}

PLAY RECAP *********************************************************************************************************
10.0.141.23                : ok=0    changed=0    unreachable=1    failed=0    skipped=0    rescued=0    ignored=0

エラーになりました。
Ansibleコントローラー → マネージドノードへのSSH接続で認証失敗しているようですね。

それでは、マネージドノードのSSH秘密鍵をAnsibleコントローラーへ配置します。
まずSCPで作業用MacからコントローラーEC2のホームディレクトリーへ秘密鍵をアップロードします。

scp -i "onda-ansible.pem" "onda-ansible.pem" ec2-user@ec2-***-***-***-***.ap-east-1.compute.amazonaws.com:/home/ec2-user

一度、AnsibleコントローラーからマネージドノードへSSH接続を試しておきます。
また、Playbookの実行前にApacheの起動状態も確認しておきます。

$ ssh -i "onda-ansible.pem" ec2-user@10.0.141.23

$ systemctl status httpd
Unit httpd.service could not be found.

そもそもApacheがインストールされていなさそうなことが確認できました。

プレイブック実行&トラブルシューティング

それでは、先ほどの秘密鍵を指定して再度Playbookを実行します。
ユーザーは指定していませんが、SSH接続元のコントローラーEC2で利用している ec2-user が利用されるため結果的に問題ありません。

$ ansible-playbook playbook.yml --private-key onda-ansible.pem

PLAY [10.0.141.23] *************************************************************************************************

TASK [Gathering Facts] *********************************************************************************************
[WARNING]: Platform linux on host 10.0.141.23 is using the discovered Python interpreter at /usr/bin/python, but
future installation of another Python interpreter could change this. See
https://docs.ansible.com/ansible/2.9/reference_appendices/interpreter_discovery.html for more information.
ok: [10.0.141.23]

TASK [start httpd] *************************************************************************************************
fatal: [10.0.141.23]: FAILED! => {"changed": false, "msg": "Could not find the requested service httpd: host"}

PLAY RECAP *********************************************************************************************************
10.0.141.23                : ok=1    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0  

今度は実行成功しました!
しかしApacheがインストールされていないので、 failed で終了してしまいました。流石にインストールまではやってくれないですよね。

それでは再度マネージドノードにSSHログインし、Apacheをインストールします。

$ sudo yum install httpd

$ systemctl status httpd #起動状態の確認
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)
   Active: inactive (dead)
     Docs: man:httpd.service(8)

httpdがインストールされ、起動していないことまで確認できました。
それでは再度Ansibleコントローラーへ戻り、先ほどのプレイブックを実行します。

$ ansible-playbook playbook.yml --private-key onda-ansible.pem 

PLAY [10.0.141.23] *************************************************************************************************

TASK [Gathering Facts] *********************************************************************************************
[WARNING]: Platform linux on host 10.0.141.23 is using the discovered Python interpreter at /usr/bin/python, but
future installation of another Python interpreter could change this. See
https://docs.ansible.com/ansible/2.9/reference_appendices/interpreter_discovery.html for more information.
ok: [10.0.141.23]

TASK [start httpd] *************************************************************************************************
fatal: [10.0.141.23]: FAILED! => {"changed": false, "msg": "Unable to start service httpd: Failed to start httpd.service: The name org.freedesktop.PolicyKit1 was not provided by any .service files\nSee system logs and 'systemctl status httpd.service' for details.\n"}

PLAY RECAP *********************************************************************************************************
10.0.141.23                : ok=1    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0 

今度は別のエラーでApache起動失敗です。
ググるとPythonインタープリターの指定で改善しそうなので、 -e オプションを追加してみます。

$ sudo ansible-playbook playbook.yml --private-key onda-ansible.pem -e ansible_python_interpreter=/usr/bin/python3

PLAY [10.0.141.23] *************************************************************************************************

TASK [Gathering Facts] *********************************************************************************************
[WARNING]: sftp transfer mechanism failed on [10.0.141.23]. Use ANSIBLE_DEBUG=1 to see detailed information
[WARNING]: scp transfer mechanism failed on [10.0.141.23]. Use ANSIBLE_DEBUG=1 to see detailed information
fatal: [10.0.141.23]: FAILED! => {"ansible_facts": {}, "changed": false, "failed_modules": {"setup": {"failed": true, "module_stderr": "Shared connection to 10.0.141.23 closed.\r\n", "module_stdout": "Please login as the user \"ec2-user\" rather than the user \"root\".\r\n\r\n", "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", "rc": 0}}, "msg": "The following modules failed to execute: setup\n"}

PLAY RECAP *********************************************************************************************************
10.0.141.23                : ok=0    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0

メッセージを見ると「rootではなくec2-userで実行せよ」的なことが書いてありますね。
それでは sudo を外して実行してみます。

$ ansible-playbook playbook.yml --private-key onda-ansible.pem -e ansible_python_interpreter=/usr/bin/python3

PLAY [10.0.141.23] *************************************************************************************************

TASK [Gathering Facts] *********************************************************************************************
ok: [10.0.141.23]

TASK [start httpd] *************************************************************************************************
fatal: [10.0.141.23]: FAILED! => {"changed": false, "msg": "Unable to start service httpd: Failed to start httpd.service: The name org.freedesktop.PolicyKit1 was not provided by any .service files\nSee system logs and 'systemctl status httpd.service' for details.\n"}

PLAY RECAP *********************************************************************************************************
10.0.141.23                : ok=1    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0

また権限エラーらしき状態に戻りました。
そろそろホリデーエンジニアの週末カフェタイムが終わってしまうので、残念ですがトラシューはここまでとします。

まとめ

綺麗にエラー解消できなかったのが残念ですが、Ansibleの概念や実装方法がかなりイメージ湧きました。
やっぱり実際に触ってみるのが大事ですね!

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
4