DockerコンテナでAnsible実行

###■初めに

　前回の記事からの続編です。前回はAzureVMにDocker積んで｢Jenkins｣のDokerfileを作成してビルドする事とそれぞれのコンテナに直接SSHを接続することをやりました。今回はDockerホストにAnsibleのDockerfileを作成してコンテナとホストそれぞれにプレイブックを実行します。
　また以下の環境にある通り最終的にはAzure環境へアクセスすることになるのでAnsibleコンテナからAzure環境への接続設定も行います

■予定

　V1　：　Dockerインストール,Dockerfile（Jenkins）作成からイメージ起動,コンテナへの直接SSH
　URL　：　[DockerのインストールとDockerFile](https://qiita.com/yo_dazy/private/30b696bb7bf60daa2854)
　<Font Color="Red">
　V2 　：　Ansibleイメージ起動,コンテナ間のSSH設定,Ansibleの稼働確認
　</font>
　V3 　：　Jenkins設定（JenkinsでのSSH接続）、リモートホストへのジョブ実行
　URL　：　[Jenkinsでコンテナ間接続とジョブ実行](https://qiita.com/yo_dazy/private/34f9f5986155d2044b45)
　V4 　：　AnsiblePlaybook（AZVMと関連リソースの作成）、稼働確認(Jenkinsからの実行)
　URL　：　[Ansibleでクラウド構築(Azure)](https://qiita.com/yo_dazy/private/2cd34b7a07b114b77fcb)
###■イメージ
![DOC02.png](https://qiita-image-store.s3.amazonaws.com/0/150678/bc2e7974-5876-244c-b754-b6835466cc9c.png)

###■環境
【Docker　ホスト】
　　AzureVM　：　CentOS
　　hostname ：　VMDO01 
　　ポート　　:  ssh,7033,8033
【Container 1(jenkinsコンテナ)】
　　Container役割　: jenkins
　　※前記事で作成したコンテナです。

■注意
・Azureのアカウントを持っている事
・マシンがAzureへログイン可能であること

■やること
　【1】Ansibleコンテナの作成
　【2】SSH接続
　【3】Ansible稼働確認

---

###■手順
####【1】. Ansibleコンテナの作成

---

　（１）．Dockerホストにログイン
　（２）．Dockerfile格納用ディレクトリの作成

```Ruby:コマンド(root)
mkdir -p /doc.file/docansible
```

　（３）．Dokerfile(ansible)の作成
※　この手順で[Ansibleコンテナ]に必要なパッケージインストールと設定を一括で行います。Dockerfileを作成することでどの環境でもDockerがあれば使用可能になります。

```Ruby:コマンド(root)
vi /doc.file/docansible/dockerfile
```

```Ruby:/doc.file/docansible/dockerfile内容
# OS
FROM centos

# SSH,Python,PIP等 pkg install
RUN yum install -y gcc libffi-devel python-devel openssl-devel epel-release
RUN yum install -y openssh-server openssh-clients sshpass
RUN curl -kL https://bootstrap.pypa.io/get-pip.py | python

# Ansible Install
RUN pip install ansible[azure]

# ms azurecli 2.0 public key import
RUN rpm --import https://packages.microsoft.com/keys/microsoft.asc

# azurecli repogistory 
RUN sh -c 'echo -e "[azure-cli]\nname=Azure CLI\nbaseurl=https://packages.microsoft.com/yumrepos/azure-cli\nenabled=1\ngpgcheck=1\ngpgkey=https://packages.microsoft.com/keys/microsoft.asc" > /etc/yum.repos.d/azure-cli.repo'

# ms azurecli 2.0 install
RUN yum install -y azure-cli

# root password
RUN echo p@ssw0rd | passwd --stdin root

# ssh root login (非推奨)
RUN sed -ri "s/#PermitRootLogin yes/PermitRootLogin yes/g" /etc/ssh/sshd_config
```

　（４）．Dokerfile(ansibleコンテナ)のビルド

```Ruby:実行前状況
[root@VMDO001 docansible]# docker images
REPOSITORY            TAG                 IMAGE ID            CREATED             SIZE
centos/jenkinsbuild   latest              0640197d6307        17 hours ago        728.7 MB
docker.io/centos      latest              ff426288ea90        6 weeks ago         207.2 MB
[root@VMDO001 docansible]#
```

```ruby:ビルド実行
docker build -t centos/ansiblebuild .
```

```Ruby:実行後状況
[root@VMDO001 docansible]# docker images
REPOSITORY            TAG                 IMAGE ID            CREATED             SIZE
centos/ansiblebuild   latest              d76b6362598e        5 minutes ago       713.7 MB
centos/jenkinsbuild   latest              0640197d6307        17 hours ago        728.7 MB
docker.io/centos      latest              ff426288ea90        6 weeks ago         207.2 MB
[root@VMDO001 docansible]#
```

　（５）．コンテナ（annsibleコンテナ）の起動

```Ruby:コマンド(root)
docker ps -a
docker exec -it <containerID> /bin/bash
```

```Ruby:実行結果
[root@VMDO001 docansible]# docker ps -a
CONTAINER ID        IMAGE                        COMMAND             CREATED             STATUS              PORTS                                          NAMES
1f04c65ff3b0        centos/ansiblebuild:latest   "/sbin/init"        14 seconds ago      Up 12 seconds                                                      tiny_aryabhata
30aaa962d65f        centos/jenkinsbuild          "/sbin/init"        17 hours ago        Up 17 hours         0.0.0.0:7033->22/tcp, 0.0.0.0:8033->8080/tcp   elated_hawking
[root@VMDO001 docansible]# docker exec -it 1f04c65ff3b0 /bin/bash
[root@1f04c65ff3b0 /]#

```

　（６）．[ansible]と[Azure cli]を確認

```Ruby:コマンド(root)
# Ansible Version check
ansible --version

# AzureCLI
az
```

```Ruby:実行結果
[root@1f04c65ff3b0 /]# ansible --version
ansible 2.4.3.0
  config file = None
  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, Aug  4 2017, 00:39:18) [GCC 4.8.5 20150623 (Red Hat 4.8.5-16)]
[root@1f04c65ff3b0 /]# az

Welcome to Azure CLI!
---------------------
Use `az -h` to see available commands or go to https://aka.ms/cli.

Telemetry
---------
The Azure CLI collects usage data in order to improve your experience.
The data is anonymous and does not include commandline argument values.
The data is collected by Microsoft.

You can change your telemetry settings with `az configure`.


     /\
    /  \    _____   _ _  ___ _
   / /\ \  |_  / | | | \'__/ _\
  / ____ \  / /| |_| | | |  __/
 /_/    \_\/___|\__,_|_|  \___|


Welcome to the cool new Azure CLI!
<…>

[root@1f04c65ff3b0 /]#
```

####【2】. SSH接続
　[Jenkinsコンテナ]、[ホスト]に対してrootでSSHできるか確認します。前提としては接続させる双方にSSHのサーバパッケージとクライアントパッケージが入っている事と[root]でのログインが可能である事になります。
　こちらはDockerfileですでに導入＋設定済みの為、設定を確認して接続確認で終了となります。

　（１）．設定確認

```Ruby:コマンド(root)(ansibleコンテナから)
[root@1f04c65ff3b0 /]# cat /etc/ssh/sshd_config | grep PermitRootLogin
PermitRootLogin yes
# the setting of "PermitRootLogin without-password".
[root@1f04c65ff3b0 /]#
```

```Ruby:コマンド(root)(Container-1（Jenkinsコンテナから）)
[root@30aaa962d65f ~]# cat /etc/ssh/sshd_config | grep PermitRootLogin
PermitRootLogin yes
# the setting of "PermitRootLogin without-password".
[root@30aaa962d65f ~]#
```

　（２）．接続確認
※AnsibleコンテナとJenkinsコンテナの双方から実行可能であることが条件です。

```Ruby:コマンド(root)(ansibleコンテナから)
ssh root@<hostIP>
ssh root@<Container1-IP>
```

```Ruby:実行結果
[root@1f04c65ff3b0 /]# ssh root@<hostIP>
The authenticity of host '<hostIP> (<hostIP>)' can't be established.
ECDSA key fingerprint is SHA256:olqZGuW0g+q2EwXoM5bBidy9b1CiEbGMcylPDjuR/Lc.
ECDSA key fingerprint is MD5:4f:ea:fc:31:3e:b9:35:e8:c0:b0:23:04:76:1c:59:66.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '<hostIP>' (ECDSA) to the list of known hosts.
Password:　<Password>
Last login: Thu Feb 22 02:15:46 2018 from <接続先(作業端末)IP>
[root@VMDO001 ~]#exit
[root@1f04c65ff3b0 /]#
[root@1f04c65ff3b0 /]#
[root@1f04c65ff3b0 /]# ssh root@<Jenkinsコンテナ-IP>
The authenticity of host '<Jenkinsコンテナ-IP> (<Jenkinsコンテナ-IP>)' can't be established.
ECDSA key fingerprint is SHA256:olqZGuW0g+q2EwXoM5bBidy9b1CiEbGMcylPDjuR/Lc.
ECDSA key fingerprint is MD5:4f:ea:fc:31:3e:b9:35:e8:c0:b0:23:04:76:1c:59:66.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '<Jenkinsコンテナ-IP>' (ECDSA) to the list of known hosts.
Password:　<Password>
Last login: Thu Feb 22 02:15:46 2018 from <接続先(作業端末)IP>
```

####【3】. Ansible稼働確認
　前記事で作った[jenkinsコンテナ]と[Dockerのホストマシン(VMDO01)]に対して[ansibleコンテナ]より[ansible]を実行します。
　これが成功することでAnsibleの稼働確認になります。

【注意】
　ansibleの条件としてはLinuxではSSHでの接続が条件になります。またインベントリファイルに記載していないとパスワードを求められます。その際にansibleコンテナ側でsshpath(Dockerfileでインストール済み)がインストールされていないとエラーが発生します。
　また以下で作成するインベントリファイルに変数を指定することでコマンド実行時パスワードを求められなくする設定もありますが、これは「V3」で行う予定なので今回はインベントリファイルに変数を指定しないで接続確認を行います。


　（１）．インベントリファイル作成

```Ruby:コマンド(root)(ansibleコンテナから)
mkdir /playbook
vi /playbook/hosts
```

```Ruby:/playbook/hosts内容
[con]
<Jenkinsコンテナ-IP>

[hostmachine]
<hostIP>
```

　（２）．双方にPing(ansible)の実行

```Ruby:コマンド(root)(ansibleコンテナから)
# for container
# -u <user> : <user>でのAnsibleの実行
# -k : SSHパスワードを自分で入力する
ansible con -i /playbook/hosts -m ping -u root -k
# for hostserver
ansible hostmachine -i /playbook/hosts -m ping -u root -k
```

```Ruby:実行結果
[root@1f04c65ff3b0 /]# ansible con -i /playbook/hosts -m ping -u root -k
SSH password:
<Jenkinsコンテナ-IP> | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
[root@1f04c65ff3b0 /]# ansible hostmachine -i /playbook/hosts -m ping -u root -k
SSH password:
<hostIP> | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
[root@1f04c65ff3b0 /]#
```

---
##まとめ
　今回はDockerコンテナにAnsibleを搭載させて実際に動かすまでをやっています。所感としてはコンテナマシンでAnsible構築する時はSSH周りを気を付ける必要があると感じました。実際にコンテナの初回起動時にSSHは入っていませんでした。なので今回はDockerfileで導入しています。
　またAnsibleを実行させるためには｢Open-ssh｣のserverとclientだけではなく｢sshpath｣も必要でした。｢sshpath｣をインストールしていないといくら接続が出来ていてもAnsibleは失敗します。

　現時点でJenkinsの環境とAnsibleの環境が作成することが出来ましたので、次はJenkinsの設定とプレイブック（Azureのリソース作成）を中心にやりたいと思います。