Ansible をインストールする


Ansible とは

Ansible とは、オープンソースの構成管理ツールの一種です。次のような特徴があります。

  • エージェントレスのため、管理対象ノードに追加でインストールするソフトウェアは一部を除き不要です。(ssh 経由での接続は必要)
  • Playbook と呼ばれる処理内容を記述したファイルを実行することによって、同じ処理を異なるホスト上で実行可能です。
  • Playbook は YAML 形式であり、容易に記述できます。

Ansible 構成

下図に、Ansible の構成を示します。Ansible は

  • コントロールノード
  • 管理対象ノード

によって構成されています。

コントロールノードとは、Ansible がインストールされたサーバのことです。 このノードには、ホストやホストグループを定義したインベントリと、 一連の処理内容を記述した Playbook と呼ばれるファイルが配置されます。 ユーザがこれらのファイルを元に Playbook を実行することで、管理対象ノードでの操作を実現します。

管理対象ノードとは、コントロールノードによって管理されるノードを指します。 Ansible はエージェントレス型のため、管理対象ノードにエージェントは不要です。 コントロールノードから管理対象ノードへは ssh 経由で接続し、 Playbook に記載されたタスクが実行されます。 実行されたタスクの結果はコントロールノードに通知されます。

コントロールノードの必要要件

コントロールノードは、次の要件を満たす必要があります。

  • Python 2 (2.7 以上) または Python3 (3.5 以上) が使用可能
  • OS が Windows でないこと

なお実行するタスクによって、追加でソフトウェアのインストールが必要になることがあります。

管理対象ノードの必要要件

管理対象ノードの必要条件は以下のとおりです。

  • コントロールノードから ssh で接続可能
  • Python 2 (2.6 以上) または Python3 (3.5 以上) が使用可能
  • 管理対象ノード上で SELinux を有効にしている場合、一部のファイル関連操作のために libselinux-python パッケージが必要になります。

※ Windows ホストを管理対象ノードにすることも可能ですが、接続は ssh ではなく WinRM 経由になります。Windows ホストに対する ssh 経由での操作は、現時点では実験的なサポートに留まっています。

コントロールノードをインストールする (DNF, yum, apt)

  • Red Hat Enterprise Linux 8

    1. Ansible Engine チャネル を有効にします。

      # subscription-manager repos --enable ansible-2.8-for-rhel-8-x86_64-rpms

    2. Ansible をインストールします。

      # dnf install ansible

  • Red Hat Enterprise Linux 7

    1. Ansible Engine チャネル を有効にします。

      # subscription-manager repos --enable rhel-7-server-ansible-2.8-rpms

    2. Ansible をインストールします。

      # yum install ansible

  • CentOS 8

    1. EPEL リポジトリを有効にします。

      # dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm

    2. Ansible をインストールします。

      # dnf install ansible

  • CentOS 7

    1. EPEL リポジトリを有効にします。

      # yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm

    2. Ansible をインストールします。

      # yum install ansible

  • CentOS 6

    1. EPEL リポジトリを有効にします。

      # yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-6.noarch.rpm

    2. Ansible をインストールします。

      # yum install ansible

  • Ubuntu 18LTS/16LTS

    Ubuntu では、PPA のバイナリパッケージを利用できます。

    1. リポジトリの追加を容易にするため、software-properties-common パッケージをインストールします。

      $ sudo apt update
      $ sudo apt install software-properties-common

    2. リポジトリを追加します。

      $ sudo apt-add-repository --yes --update ppa:ansible/ansible

    3. Ansible をインストールします。

      $ sudo apt install ansible

  • Debian 10/9.0

    Debian では Ubuntu と同様に、PPA のバイナリパッケージを利用できます。

    1. Ansible の PPA のソースを sources.list に追加します。

      エディタで /etc/apt/sources.list を開いてください。

      $ sudo vi /etc/apt/sources.list

      ファイルの末尾に次の行を追加し、保存してください。

      /etc/apt/sources.list:

      deb http://ppa.launchpad.net/ansible/ansible/ubuntu trusty main

    2. パッケージの署名の検証に必要な公開鍵を追加します。

      [HTTP Proxy が必要無い場合]

      $ sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 93C4A3FD7BB9C367

      [HTTP Proxy が必要な場合]

      apt-key adv コマンドの実行の際に --keyserver-option を使用し Proxy を指定します。 なおホスト名 (proxy.example.com) やポート番号 (8080) は、自組織の設定に合わせて設定してください。

      $ sudo apt-key adv --keyserver keyserver.ubuntu.com --keyserver-option http-proxy=http://proxy.example.com:8080/ --recv-keys 93C4A3FD7BB9C367

    3. Ansible をインストールします。

      $ sudo apt update
      $ sudo apt install ansible

コントロールノードをインストールする (pip)

  • CentOS 8

    1. Ansible を実行するユーザでログインしてください。

    2. HTTP Proxy が必要な場合、HTTP Proxy に関する環境変数を設定します。(スキップ可)

      [HTTP Proxy が必要な場合]

      apt-key adv コマンドの実行の際に --keyserver-option を使用し Proxy を指定します。 なおホスト名 (proxy.example.com) やポート番号 (8080) は、自組織の設定に合わせて設定してください。

      $ export http_proxy="http://proxy.example.com:8080/"
      $ export https_proxy="http://proxy.example.com:8080/"

    3. pip がインストール済みでない場合、pip をインストールします。(スキップ可)

      $ curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
      $ python3 get-pip.py --user

    4. Ansible をインストールします。

      $ pip install --user ansible

    [virtualenv を利用する場合]

    1. Ansible を実行するユーザでログインしてください。

    2. HTTP Proxy が必要な場合、HTTP Proxy に関する環境変数を設定します。(スキップ可)

      [HTTP Proxy が必要な場合]

      apt-key adv コマンドの実行の際に --keyserver-option を使用し Proxy を指定します。 なおホスト名 (proxy.example.com) やポート番号 (8080) は、自組織の設定に合わせて設定してください。

      $ export http_proxy="http://proxy.example.com:8080/"
      $ export https_proxy="http://proxy.example.com:8080/"

    3. pip がインストール済みでない場合、pip をインストールします。(スキップ可)

      $ curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
      $ python3 get-pip.py --user

    4. virtualenv をインストールします。(スキップ可)

      $ pip install virtualenv --user

    5. Ansible 用の仮想環境を作成します。

      $ python3 -m virtualenv ansible

    6. 仮想環境を有効化します。

      $ source ansible/bin/activate

    7. Ansible をインストールします。

      (ansible) $ pip install ansible

  • pywinrm パッケージ

    コントロールノードと Windows ホストの通信には通常 WinRM を利用します。 しかしながらデフォルトの Ansible は、WinRM を使用するためのパッケージ (pywinrm) をインストールしないため、これを別途インストールする必要があります。

    1. Ansible を実行するユーザでログインしてください。

    2. HTTP Proxy が必要な場合、HTTP Proxy に関する環境変数を設定します。(スキップ可)

      [HTTP Proxy が必要な場合]

      apt-key adv コマンドの実行の際に --keyserver-option を使用し Proxy を指定します。 なおホスト名 (proxy.example.com) やポート番号 (8080) は、自組織の設定に合わせて設定してください。

      $ export http_proxy="http://proxy.example.com:8080/"
      $ export https_proxy="http://proxy.example.com:8080/"

    3. pip がインストール済みでない場合、pip をインストールします。(スキップ可)

      $ curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
      $ python3 get-pip.py --user

    4. pywinrm パッケージをインストールします。

      $ pip install --user pywinrm

インストール後に行う作業

Ansible ユーザの作成 (推奨)

Ansible を利用するためのユーザ (以下、ansible ユーザと呼びます) を作成します。

なお ansible ユーザの作成は必須ではありません。 既存のユーザを Ansible のために使用することもできますが後述する公開鍵認証の鍵管理の観点や、 別途ご説明する Ansible のベストプラクティスのためには、 ansible ユーザを作成するほうが都合がよいため、ansible ユーザの作成をお勧めします。

[Red Hat Enterprise Linux, CentOS]

  1. ユーザを追加します。

    # adduser <user>
  2. パスワードを設定します。

    # passwd <user>
    Changing password for user ansible.
    New password:
    Retype new password:
    passwd: all authentication tokens updated successfully.

[Debian/Ubuntu]

  1. ユーザを追加します。パスワードは適切なものを設定します。

    (質問項目は空でも構いません。)

    # adduser <user>
    Adding user `<user>' ...
    Adding new group `<user>' (xxxxx) ...
    Adding new user `<user>' (xxxxx) with group `<user>' ...
    Creating home directory `/home/<user>' ...
    Copying files from `/etc/skel' ...
    Enter new UNIX password:
    Retype new UNIX password:
    passwd: password updated successfully
    Changing the user information for <user>
    Enter the new value, or press ENTER for the default
            Full Name []:
            Room Number []:
            Work Phone []:
            Home Phone []:
            Other []:
    Is the information correct? [Y/n] Y

管理対象ノードの設定

コントロールノードから操作できるように管理対象ノードを設定します。 手順については

を参照してください。

公開鍵認証の設定 (推奨)

コントロールノードから管理対象ノードへの認証のために、コントロールノード上で公開鍵認証を設定します。

この項目も必須ではありませんが、Ansible はデフォルトで管理対象ノードへの接続に SSH 公開鍵認証の使用を想定します。 パスワード認証での接続も可能ですが、--ask-pass オプションの指定が必要となります。 可能であれば SSH 公開鍵での認証をお勧めします。

  1. 鍵ペアを生成します。(初回のみ)

    (以下の操作は Ansible を使用するユーザで実施してください。)

    $ cd
    $ ssh-keygen
    Generating public/private rsa key pair.
    Enter file in which to save the key (/home/<user>/.ssh/id_rsa):
    Created directory '/home/<user>/.ssh'.
    Enter passphrase (empty for no passphrase):
    Enter same passphrase again:
    Your identification has been saved in /home/<user>/.ssh/id_rsa.
    Your public key has been saved in /home/<user>/.ssh/id_rsa.pub.
    The key fingerprint is:
    SHA256:...
    The key's randomart image is:
    ...
  2. 生成した公開鍵を管理対象ノードへコピーします。 (ここでは管理対象ノードを host0、ユーザ名を auser としています。実際に設定する際には適切な値を設定してください。)

    $ ssh-copy-id -i .ssh/id_rsa.pub auser@host0
  3. 接続テストを行ないます。

    $ ssh auser@host0

    管理対象ノードにログインできれば公開鍵認証の設定は成功です。

Ping モジュールを利用した接続テスト (Linux ホスト)

コントロールノードから管理対象ノードへの疎通確認を行ないます。疎通確認には ping モジュールを利用します。

  1. 管理対象ノードをインベントリへ追加します。

    インベントリとは、Ansible の操作対象となるホストやホストのグループを定義したファイルのことです。 この接続テストではカレントディレクトリにインベントリを作成します。

    エディタで hosts という名前のファイルを作成あるいは編集してください。

    $ vi hosts

    疎通を確認したいノードのホスト名をファイルに追記し、保存してください。なおホスト名 (host0) は適宜変更してください。

    hosts ファイル:

    host0

  2. Ping モジュールを使用し、疎通確認を行ないます。

    [ホストへの接続が公開鍵認証の場合]

    $ ansible -i hosts -m ping host0

    [ホストへの接続がパスワード認証の場合]

    $ ansible -i hosts -m ping host0 --ask-pass
    SSH password:

    接続に成功した場合、次のような結果が出力されます。

    接続成功例:

    host0 | SUCCESS => {
        "ansible_facts": {
            "discovered_interpreter_python": "/usr/bin/python3"
        },
        "changed": false,
        "ping": "pong"
    }

    接続に失敗した場合の出力例は以下のとおりです。

    接続失敗例:

    host0 | UNREACHABLE! => {
        "changed": false,
        "msg": "Failed to connect to the host via ssh: ssh: connect to host host0 port 22: No route to host",
        "unreachable": true
    }

    トラブルシューティングをご参照ください。

Ping モジュールを利用した接続テスト (Windows ホスト)

コントロールノードから Windows ホストへの疎通確認を行ないます。疎通確認には win_ping モジュールを利用します。

  1. インベントリファイルを作成あるいは編集します。

    インベントリとは、Ansible の操作対象となるホストやホストのグループを定義したファイルのことです。 この接続テストではカレントディレクトリにインベントリを作成します。

    エディタで hosts という名前のファイルを作成あるいは編集してください。

    $ vi hosts

  2. グループを作成します。(設定する際には適切な値を設定してください。)

    [windows_servers]
  3. グループにホストを追加します。

    [windows_servers]
    winserver0.example.com
  4. グループ変数を定義し、Windows ホストへ接続情報を追加します。(設定する際には適切な値を設定してください。)

    [HTTPS 経由でのパスワード認証の場合]

    [windows_servers:vars]
    ansible_user: auser
    ansible_password: 'YourPasswd'
    ansible_port: 5986
    ansible_connection: winrm
    ansible_winrm_server_cert_validation: ignore
  5. 保存後、閉じます。

    編集後の hosts ファイル:

    [windows_servers]
    winserver0.example.com
     
    [windows_servers:vars]
    ansible_user: auser
    ansible_password: 'YourPasswd'
    ansible_port: 5986
    ansible_connection: winrm
    ansible_winrm_server_cert_validation: ignore
  6. win_ping モジュールを使用し、疎通確認を行ないます。

    $ ansible -i hosts -m win_ping winserver0.example.com

    接続に失敗した場合の出力例は以下のとおりです。

    接続失敗例:

    winserver0.example.com | UNREACHABLE! => {
        "changed": false,
        "msg": "ssl: HTTPSConnectionPool(host='winserver0.example.com', port=5986): Max retries exceeded with url: /wsman (Caused by ConnectTimeoutError(, 'Connection to winserver0.example.com timed out. (connect timeout=30)'))",
        "unreachable": true
    }

    トラブルシューティングをご参照ください。

トラブルシューティング

接続テスト (パスワード認証) でエラーが発生する

  • 必要なパッケージ sshpass が存在しない

    $ ansible -i hosts -m ping host0 --ask-pass
    SSH password:
    host0 | FAILED! => {
        "msg": "to use the 'ssh' connection type with passwords, you must install the sshpass program"
    }

    --ask-pass オプションの使用には sshpass が必要です。sshpass パッケージをインストールしてください。

    [CentOS 8]

    # dnf install epel-release
    # dnf install sshpass
  • ホストの公開鍵チェック未実施時

    ssh を使用したリモートホストへの初回接続時にはホスト認証が行われますが、sshpass はその処理をサポートしないため、エラーとなります。

    $ ansible -i hosts -m ping host0 --ask-pass
    SSH password:
    host0 | FAILED! => {
        "msg": "Using a SSH password instead of a key is not possible because Host Key checking is enabled and sshpass does not support this.  Please add this host's fingerprint to your known_hosts file to manage this host."
    }

    ssh コマンドを実行し、リモートホストへの初回接続を実施してください。 なおこの例のユーザ名 (auser) やホスト名 (host0) は適切な値に変更してください。

    $ ssh auser@host0
  • 接続ユーザが適切でない

    Ansible では ssh と同様に、管理対象ノードへの接続に現在のユーザを使用します。 このため、管理対象ノードにおいて現在のユーザが存在しない場合は接続エラーとなります。

    host0 | UNREACHABLE! => {
        "changed": false,
        "msg": "Failed to connect to the host via ssh: user@host0: Permission denied (publickey,password).",
        "unreachable": true
    }

    ansible コマンド実行時に --user (-u) オプションを使用するか、インベントリにホスト変数 ansible_user を設定することで、 接続ユーザを指定してください。

    [ansible コマンドの -u オプション指定による方法]

    $ ansible -i hosts -m ping host0 --ask-pass --user auser

    [インベントリでの ansible_user ホスト変数指定による方法]

    host0 ansible_user: auser

接続テスト (公開鍵認証) でエラーが発生する

ホストへの接続に失敗する場合は、次の 2 点を確認してください。

  1. コントロールノードから管理対象ノードへ ssh 経由でアクセス可能
  2. インベントリ (hosts ファイル) で定義されているホスト名が正しいこと

Connection timed out が発生し、ホストへの接続に失敗した際には、下記のエラーが出力されます。

Connection timed out による接続失敗例

TASK [Gathering Facts] *********************************************************
fatal: [host0]: UNREACHABLE! => {
    "changed": false, 
    "msg": "Failed to connect to the host via ssh: ssh: connect to host host0 port 22: Connection timed out", 
    "unreachable": true
}

前記の 2 項目をチェック後、 再度 Ping モジュールを利用した接続テストを行ってください。

未定義のホストやグループを指定している

下記の例では、ping の対象に hostxxxxyyyy を指定しているにもかかわらず、 インベントリ (hosts ファイル) でそのホスト名 (あるいはグループ名) が存在しないため、ホスト hostxxxxyyyy が無視されています。

hosts ファイルにホスト名やグループ名を追加してください。

host パターンの不一致による警告メッセージ

$ ansible -i hosts -m ping hostxxxxyyyy
 [WARNING]: Could not match supplied host pattern, ignoring: hostxxxxyyyy