オフライン環境でのAnsibleのインストール方法

ここではオフライン環境でAnsibleをインストール方法について記載します。

Ansibleのインストール方法は
https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html#running-ansible-from-source-devel
を見れば、一通りの環境についてのインストール方法を確認することができますが、オフライン環境でインストールする方法はあまり見かけないです。
実際仕事で基盤構築をする場合、インターネットから隔離されている環境が多いので、オフライン環境でインストールする方法の１つを紹介します。

## インストール環境

今回Ansibleをインストールするオフライン環境は以下の通りです。

* CentOS7
  * CentOS-7-x86_64-DVD-1810.iso
  * 最小インストール
  * ネットワーク設定済み
  * 上記のISOをマウント済み
  * インストールDVD内のパッケージからyumが利用できるように/etc/yum.repos.d配下の下記の設定ファイルを変更済み
     * CentOS-Base.repo(不要なrepo定義にenabled=0を追記)
     * CentOS-Media.repo（baseurlにDVDマウントしたディレクトリを設定）

## インストール方法

オンライン環境のAnsibleでインストールする場合は、EPELリポジトリを利用できるように設定して、yumコマンドを打てばよいのですが、オフライン環境だとEPELリポジトリにアクセスできません。

そのため、Ansbileや依存関係のあるrpmを１つずつダウンロードして依存関係を解決しながらインストールする必要があります。

依存関係やバージョンを調査したり、必要なパッケージをインターネット上から探すのってつらいですよね？？

一番良いのが、インターネットがつながる環境を用意してyumコマンドで依存関係を先に調査しておくことですが、その環境さえ用意できない場合は、トライアンドエラーでやるしかないです。

### Ansible rpmファイルのダウンロード

①まず下記のサイトからAnsibleのrpmをダウンロードします。

https://releases.ansible.com/ansible/rpm/release/epel-7-x86_64/

今回は2020年5月30日時点（執筆時点）で最新のansible-2.9.9-1.el7.ans.noarch.rpmにしました。

### Ansible rpmファイルの依存関係の確認

②次にAnsibleのrpmに不足している依存パッケージを確認します。

yum installコマンドを実行してみましょう。

```
yum install ansible-2.9.9-1.el7.ans.noarch.rpm
```
yum installコマンドは失敗しエラーとなりますが、Ansbileに必要な依存パッケージや不足しているパッケージが表示されます。

```
yum install ansible-2.9.9-1.el7.ans.noarch.rpm ansible-2.9.9-1.el7.ans.noarch.rpm
読み込んだプラグイン:fastestmirror
ansible-2.9.9-1.el7.ans.noarch.rpm を調べています: ansible-2.9.9-1.el7.ans.noarch
ansible-2.9.9-1.el7.ans.noarch.rpm をインストール済みとして設定しています
ansible-2.9.9-1.el7.ans.noarch.rpm を調べています: ```
ansible-2.9.9-1.el7.ans.noarch
ansible-2.9.9-1.el7.ans.noarch.rpm をインストール済みとして設定しています
依存性の解決をしています
--> トランザクションの確認を実行しています。
---> パッケージ ansible.noarch 0:2.9.9-1.el7.ans を インストール
---> パッケージ ansible.noarch 0:2.9.9-1.el7.ans を インストール
--> 依存性の処理をしています: python-jinja2 のパッケージ: ansible-2.9.9-1.el7.ans.noarch

～略～

--> 依存性の処理をしています: sshpass のパッケージ: ansible-2.9.9-1.el7.ans.noarch
---> パッケージ python-backports.x86_64 0:1.0-8.el7 を インストール
---> パッケージ python-ply.noarch 0:3.4-11.el7 を インストール
--> 依存性解決を終了しました。
エラー: パッケージ: ansible-2.9.9-1.el7.ans.noarch (/ansible-2.9.9-1.el7.ans.noarch)
             要求: python-jinja2
エラー: パッケージ: ansible-2.9.9-1.el7.ans.noarch (/ansible-2.9.9-1.el7.ans.noarch)
             要求: sshpass
 問題を回避するために --skip-broken を用いることができます。
 これらを試行できます: rpm -Va --nofiles --nodigest
```

エラーログを見ていくと、最後のエラーメッセージの部分でpython-jinja2とsshpassを要求していることがわかります。python-jinja2とsshpassはインストールDVDに存在するパッケージ群には見たらないとのことでした。

### Ansible 依存ライブラリのダウンロード

③次に、その2つのパッケージについて下記のサイトからダウンロードします。

* sshpass
  https://centos.pkgs.org/7/centos-extras-x86_64/sshpass-1.06-2.el7.x86_64.rpm.html
  sshpass-1.06-2.el7.x86_64.rpm
 

* python-jinja2
  https://centos.pkgs.org/7/centos-x86_64/python-jinja2-2.7.2-4.el7.noarch.rpm.html
  python-jinja2-2.7.2-4.el7.noarch.rpm

インストールする環境によって不足しているパッケージは変わる可能があるため、エラーとなっているパッケージに注目して個別にダウンロードしましょう。

本来であれば下記のような依存関係を確認しつつ、一つ一つパッケージをrpmコマンドでインストールしていくのですが、yumコマンドなら複数のrpmファイルを一気にインストールすることができます。

* ansibleインストールに必要な依存パッケージ（※）

```
ansible
  ┣━PyYAML
  ┣━python-jinja2
  ┣━python-paramiko
  ┣━python-six
  ┣━python2-cryptography
  ┃　┣━python-ipaddress
  ┃　┣━python-enum34
  ┃　┣━python-six
  ┃　┗━python2-pyasn1
  ┗━sshpass
     ┗━python2-pyasn1
```

※全てのライブラリ依存関係は多すぎるため、省略しています。

### Ansibleのインストール

④それでは、以下のコマンドでAnsibleをインストールしていきましょう。

ダウンロードしたrpmファイル3つを任意のディレクトリにコピーして、以下のコマンドを実行します。
（今回は/tmp配下にrpmファイルを格納し、cdコマンドで/tmpディレクトリに移動しています。）

```
# yum install ansible-2.9.9-1.el7.ans.noarch.rpm sshpass-1.06-2.el7.x86_64.rpm python-jinja2-2.7.2-4.el7.noarch.rpm
```

依存するパッケージの順番とか関係なしに、rpmファイルをスペースで区切って実行すると、yumが勝手に依存順を考慮してインストールしてくれます。

コマンドの実行結果は以下の通りです。


```
読み込んだプラグイン:fastestmirror
ansible-2.9.9-1.el7.ans.noarch.rpm を調べています: ansible-2.9.9-1.el7.ans.noarch
ansible-2.9.9-1.el7.ans.noarch.rpm をインストール済みとして設定しています
sshpass-1.06-2.el7.x86_64.rpm を調べています: sshpass-1.06-2.el7.x86_64
sshpass-1.06-2.el7.x86_64.rpm をインストール済みとして設定しています
python-jinja2-2.7.2-4.el7.noarch.rpm を調べています: python-jinja2-2.7.2-4.el7.noarch
python-jinja2-2.7.2-4.el7.noarch.rpm をインストール済みとして設定しています
依存性の解決をしています
--> トランザクションの確認を実行しています。
---> パッケージ ansible.noarch 0:2.9.9-1.el7.ans を インストール
--> 依存性の処理をしています: PyYAML のパッケージ: ansible-2.9.9-1.el7.ans.noarch
Loading mirror speeds from cached hostfile

～略～

---> パッケージ python-pycparser.noarch 0:2.14-1.el7 を インストール
--> 依存性の処理をしています: python-ply のパッケージ: python-pycparser-2.14-1.el7.noarch
--> トランザクションの確認を実行しています。
---> パッケージ python-backports.x86_64 0:1.0-8.el7 を インストール
---> パッケージ python-ply.noarch 0:3.4-11.el7 を インストール
--> 依存性解決を終了しました。

依存性を解決しました

================================================================================
 Package           アーキテクチャー
                          バージョン      リポジトリー                     容量
================================================================================
インストール中:
 ansible           noarch 2.9.9-1.el7.ans /ansible-2.9.9-1.el7.ans.noarch 103 M
 python-jinja2     noarch 2.7.2-4.el7     /python-jinja2-2.7.2-4.el7.noarch
                                                                          3.0 M
 sshpass           x86_64 1.06-2.el7      /sshpass-1.06-2.el7.x86_64       38 k
依存性関連でのインストールをします:
 PyYAML            x86_64 3.10-11.el7     c7-media                        153 k
 libyaml           x86_64 0.1.4-11.el7_0  c7-media                         55 k
 python-babel      noarch 0.9.6-8.el7     c7-media                        1.4 M
 python-backports  x86_64 1.0-8.el7       c7-media                        5.8 k
 python-backports-ssl_match_hostname
                   noarch 3.5.0.1-1.el7   c7-media                         13 k
 python-cffi       x86_64 1.6.0-5.el7     c7-media                        218 k
 python-enum34     noarch 1.0.4-1.el7     c7-media                         52 k
 python-idna       noarch 2.4-1.el7       c7-media                         94 k
 python-ipaddress  noarch 1.0.16-2.el7    c7-media                         34 k
 python-markupsafe x86_64 0.11-10.el7     c7-media                         25 k
 python-paramiko   noarch 2.1.1-5.el7     c7-media                        268 k
 python-ply        noarch 3.4-11.el7      c7-media                        123 k
 python-pycparser  noarch 2.14-1.el7      c7-media                        104 k
 python-setuptools noarch 0.9.8-7.el7     c7-media                        397 k
 python-six        noarch 1.9.0-2.el7     c7-media                         29 k
 python2-cryptography
                   x86_64 1.7.2-2.el7     c7-media                        502 k
 python2-pyasn1    noarch 0.1.9-7.el7     c7-media                        100 k

トランザクションの要約
================================================================================
インストール  3 パッケージ (+17 個の依存関係のパッケージ)

合計容量: 109 M
総ダウンロード容量: 3.5 M
インストール容量: 122 M
Is this ok [y/d/N]: y
Downloading packages:
警告: /media/dvd/Packages/PyYAML-3.10-11.el7.x86_64.rpm: ヘッダー V3 RSA/SHA256 Signature、鍵 ID f4a80eb5: NOKEY
PyYAML-3.10-11.el7.x86_64.rpm の公開鍵がインストールされていません
--------------------------------------------------------------------------------
合計                                                12 MB/s | 3.5 MB  00:00
file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 から鍵を取得中です。
Importing GPG key 0xF4A80EB5:
 Userid     : "CentOS-7 Key (CentOS 7 Official Signing Key) <security@centos.org>"
 Fingerprint: 6341 ab27 53d7 8a78 a7c2 7bb1 24c6 a8a7 f4a8 0eb5
 Package    : centos-release-7-6.1810.2.el7.centos.x86_64 (@anaconda)
 From       : /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
上記の処理を行います。よろしいでしょうか？ [y/N]y
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  インストール中          : python-six-1.9.0-2.el7.noarch                  1/20
  インストール中          : python2-pyasn1-0.1.9-7.el7.noarch              2/20
  インストール中          : python-ipaddress-1.0.16-2.el7.noarch           3/20
  インストール中          : sshpass-1.06-2.el7.x86_64                      4/20
  インストール中          : python-backports-1.0-8.el7.x86_64              5/20
  インストール中          : python-backports-ssl_match_hostname-3.5.0.1    6/20
  インストール中          : python-setuptools-0.9.8-7.el7.noarch           7/20
  インストール中          : python-babel-0.9.6-8.el7.noarch                8/20
  インストール中          : libyaml-0.1.4-11.el7_0.x86_64                  9/20
  インストール中          : PyYAML-3.10-11.el7.x86_64                     10/20
  インストール中          : python-enum34-1.0.4-1.el7.noarch              11/20
  インストール中          : python-ply-3.4-11.el7.noarch                  12/20
  インストール中          : python-pycparser-2.14-1.el7.noarch            13/20
  インストール中          : python-cffi-1.6.0-5.el7.x86_64                14/20
  インストール中          : python-markupsafe-0.11-10.el7.x86_64          15/20
  インストール中          : python-jinja2-2.7.2-4.el7.noarch              16/20
  インストール中          : python-idna-2.4-1.el7.noarch                  17/20
  インストール中          : python2-cryptography-1.7.2-2.el7.x86_64       18/20
  インストール中          : python-paramiko-2.1.1-5.el7.noarch            19/20
  インストール中          : ansible-2.9.9-1.el7.ans.noarch                20/20
  検証中                  : python-idna-2.4-1.el7.noarch                   1/20
  検証中                  : python-markupsafe-0.11-10.el7.x86_64           2/20
  検証中                  : python-paramiko-2.1.1-5.el7.noarch             3/20
  検証中                  : python-ply-3.4-11.el7.noarch                   4/20
  検証中                  : ansible-2.9.9-1.el7.ans.noarch                 5/20
  検証中                  : python-enum34-1.0.4-1.el7.noarch               6/20
  検証中                  : libyaml-0.1.4-11.el7_0.x86_64                  7/20
  検証中                  : python-babel-0.9.6-8.el7.noarch                8/20
  検証中                  : python-backports-1.0-8.el7.x86_64              9/20
  検証中                  : python-cffi-1.6.0-5.el7.x86_64                10/20
  検証中                  : python-ipaddress-1.0.16-2.el7.noarch          11/20
  検証中                  : sshpass-1.06-2.el7.x86_64                     12/20
  検証中                  : python-jinja2-2.7.2-4.el7.noarch              13/20
  検証中                  : python2-pyasn1-0.1.9-7.el7.noarch             14/20
  検証中                  : PyYAML-3.10-11.el7.x86_64                     15/20
  検証中                  : python-pycparser-2.14-1.el7.noarch            16/20
  検証中                  : python-six-1.9.0-2.el7.noarch                 17/20
  検証中                  : python-setuptools-0.9.8-7.el7.noarch          18/20
  検証中                  : python2-cryptography-1.7.2-2.el7.x86_64       19/20
  検証中                  : python-backports-ssl_match_hostname-3.5.0.1   20/20

インストール:
  ansible.noarch 0:2.9.9-1.el7.ans      python-jinja2.noarch 0:2.7.2-4.el7
  sshpass.x86_64 0:1.06-2.el7

依存性関連をインストールしました:
  PyYAML.x86_64 0:3.10-11.el7
  libyaml.x86_64 0:0.1.4-11.el7_0
  python-babel.noarch 0:0.9.6-8.el7
  python-backports.x86_64 0:1.0-8.el7
  python-backports-ssl_match_hostname.noarch 0:3.5.0.1-1.el7
  python-cffi.x86_64 0:1.6.0-5.el7
  python-enum34.noarch 0:1.0.4-1.el7
  python-idna.noarch 0:2.4-1.el7
  python-ipaddress.noarch 0:1.0.16-2.el7
  python-markupsafe.x86_64 0:0.11-10.el7
  python-paramiko.noarch 0:2.1.1-5.el7
  python-ply.noarch 0:3.4-11.el7
  python-pycparser.noarch 0:2.14-1.el7
  python-setuptools.noarch 0:0.9.8-7.el7
  python-six.noarch 0:1.9.0-2.el7
  python2-cryptography.x86_64 0:1.7.2-2.el7
  python2-pyasn1.noarch 0:0.1.9-7.el7

完了しました!
```

はい、インストールできました。

### Ansible インストール後の確認

⑤念のため、Ansibleのコマンドが使えるか確認しておきましょう。

```
# ansible --version
ansible 2.9.9
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/root/.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.5 (default, Oct 30 2018, 23:45:53) [GCC 4.8.5 20150623 (Red Hat 4.8.5-36)]
```

ちゃんと2.9.9のバージョンのAnsibleがインストールされています。
これでCentOS 7.6のオフライン環境でのAnsibleインストールは完了となります。