##■初めに
前回の記事からの続編です。
前回まででDocker環境にJenkinsとAnsibleのコンテナを作り、JenkinsからAnsible実行までをやりました。今回は最終としてPlaybookを作成しAzureの環境にVMを作成します。またAzureで作成するリソースは「ResourceGroup」「VNET」「SUBNET」「NSG」「VM」の5つを作成します。最終的にプレイブックをJenkinsジョブで実行するところまで行います。
これができることによりPlaybookを作りこむことでサーバ一台でWEBUI(Jenkins)からAzureのリソースを手軽に作れる環境になるかと思います。
■予定
V1 : Dockerインストール,Dockerfile(Jenkins)作成からイメージ起動,コンテナへの直接SSH
URL : DockerのインストールとDockerFile
V2 : Ansibleイメージ起動,コンテナ間のSSH設定,Ansibleの稼働確認
URL : DockerコンテナでAnsible実行
V3 : Jenkins設定(JenkinsでのSSH接続)、リモートホストへのジョブ実行
URL : Jenkinsでコンテナ間接続とジョブ実行
V4 : AnsiblePlaybook(AZVMと関連リソースの作成)、稼働確認(Jenkinsからの実行)
■イメージ
■環境
-AzureVM
host : VMDO001
OSType : CentOS 7.3
Size : Standard D2s v3
-NSG
SSH (Any/Any) Accept
7033 (Any/Any) Accept ※後述するコンテナとホストのポートバインドで使用
8033 (Any/Any) Accept ※後述するコンテナとホストのポートバインドで使用
■playbookで作成する環境
リソース | 名称 | 種別 |
---|---|---|
ResourceGroup | RG02 | リソースグループ |
Vnet | VN02 | 仮想ネットワーク |
Subnet | SN02 | サブネット |
NSG | NSG02 | ネットワークセキュリティグループ |
VM | VMCE02 | 仮想マシン |
※ルールに関しては「SSH」「RDP」を許可 |
■注意
・Azureのアカウントを持っている事
・マシンがAzureへログイン可能であること
■やること
【0】Docker コンテナ起動
【1】Azure環境へのログイン
【2】サービスプリンシパルの作成
【3】プレイブック作成
【4】Jenkinsジョブ作成,実行
【5】稼働確認
##■手順
####【0】Docker コンテナ起動
(1).[Dockerホスト]にログインし[Jenkinsコンテナ]と[Ansibleコンテナ]を起動する
docker run -p <hostport(8033):8080> -p <hostport(7033):22> -itd --privileged <REPOSITORY(Jenkinsコンテナ):TAG> /sbin/init
docker run -p <hostport(9033):22> -itd --privileged <REPOSITORY(Ansibleコンテナ):TAG> /sbin/init
[root@VMDO001 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@VMDO001 ~]# docker run -p 8033:8080 -p 7033:22 -itd --privileged centos/jenkinsbuild:latest /sbin/init
efadf1d923a41d08ff413bbb06d71818e5d201a3b648a2108f2191cbc8e5e006
[root@VMDO001 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
efadf1d923a4 centos/jenkinsbuild:latest "/sbin/init" 38 seconds ago Up 36 seconds 0.0.0.0:7033->22/tcp, 0.0.0.0:8033->8080/tcp cocky_keller
[root@VMDO001 ~]# docker run -p 9033:22 -itd --privileged centos/ansiblebuild:1 /sbin/init
1650f986860ebb59f505055af5f2c52719e81530d056f70e827f0f275a335208
[root@VMDO001 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1650f986860e centos/ansiblebuild:1 "/sbin/init" 7 seconds ago Up 5 seconds 0.0.0.0:9033->22/tcp thirsty_kare
efadf1d923a4 centos/jenkinsbuild:latest "/sbin/init" 3 minutes ago Up 3 minutes 0.0.0.0:7033->22/tcp, 0.0.0.0:8033->8080/tcp cocky_keller
[root@VMDO001 ~]#
(2).[Ansibleコンテナ]と[Jenkinsコンテナ]を起動
※「前記事」でSSH設定済みの為「SSHクライアント」からつなげます
※ 左が[Jenkinsコンテナ]で右が[Ansibleコンテナ]になります
####【1】Azure環境へのログイン
[Ansibleコンテナ]からAzureCLIを使用しAzure環境へログインする
(1).[Ansibleコンテナ]よりAzure環境へログインする
※<SubScriptionID>は記憶しておく。
az login -u <Azureaccount> -p <password>
[root@1650f986860e /]# az login -u <AzureAccount> -p <password>
[
{
"cloudName": "AzureCloud",
"id": "<SubScriptionID>",
"isDefault": true,
"name": "<SubScriptionNAME>",
"state": "<Status>",
"tenantId": "<TenantID>",
"user": {
"name": "<AzureAccount>",
"type": "<AccountType>"
}
}
[root@1650f986860e /]#
(2).[SubScription]をセットし使用するAzure環境を決定
az account set --subscription <SubScriptionID>
[root@1650f986860e /]# az account set --subscription <SubScriptionID>
[root@1650f986860e /]#
####【2】サービスプリンシパルと資格情報ファイルの作成
サービスプリンシパルとはユーザーによって作成されたアプリやサービス、オートメーション ツールが特定の Azure リソースにアクセスする際に使うセキュリティ IDになります。AnsibleのplaybookをAzure環境へ実行させる際に必要になります。
【2-1】サービスプリンシパルの作成
(1).以下「Azureコンテナ」よりコマンドを実行し「サービスプリンシパル」を作成する
※実行結果をテキスト等へ保存
az ad sp create-for-rbac --query [appId,password,tenant]
[
"<appId>",
"<password>",
"<tenant>"
]
【2-2】資格情報ファイルの作成
(1).以下「Azureコンテナ」よりコマンドを実行し[資格情報ファイル]を作成する
※実行ユーザのホームディレクトリに作成すること(今回はroot)
# 実行前に存在しているか確認しなければ作成
mkdir ~/.azure
vi ~/.azure/credentials
# 【2-1】実行時に得た情報を記載する
[default]
subscription_id=<SubScriptionID>
client_id=<appId>
secret=<password>
tenant=<tenant>
####【3】プレイブック作成
プロビジョニングを行うファイルを作成します。基本的な構造はベストプラティクスを採用しているつもりですが、違っていたらごめんなさい。筆者の勉強不足です。とりあえず言える事は以下の構成で目的を達成することはできました。
(1).以下コマンドを実行しディレクトリを作成
mkdir /playbook
mkdir /playbook/host_vars
mkdir /playbook/roles
mkdir -p /playbook/roles/1_azrg/tasks/
mkdir -p /playbook/roles/2_aznsg/tasks/
mkdir -p /playbook/roles/3_azvnet/tasks/
mkdir -p /playbook/roles/4_aznicpub/tasks/
mkdir -p /playbook/roles/5_azvm/tasks/
(2).以下コマンドを実行し、[roles]を作成
※これから作成するファイルでAzure環境へ処理を行わせます。
【1_azrg】
vi /playbook/roles/1_azrg/tasks/main.yml
# {{ 文字列 }}は変数
# 変数の値はパラメータとなる
---
- name: Create resourcegroup
azure_rm_resourcegroup: name={{ rgname }} location={{ reasion }}
【2_aznsg】
vi /playbook/roles/2_aznsg/tasks/main.yml
---
- name: Create NSG
azure_rm_securitygroup: #モジュール名称
resource_group: "{{ rgname }}" #リソースグループ
name: "{{ nsgname }}" #NSG名
rules: #NSGに関連付けるルール
- name: SSH #ルール名
protocol: Tcp #使用するプロトコル
destination_port_range: 22 #ポート番号の指定
access: Allow #アクセスのタイプ(Allow,Deny)
priority: 1001 #ルールの優先度
direction: Inbound #ルールのタイプ(受信か送信か)
- name: RDP
protocol: Tcp
destination_port_range: 3389
access: Allow
priority: 1002
direction: Inbound
【3_azvnet】
「サブネット」も同時作成。またネットワークセキュリティグループはサブネットに付与している。
vi /playbook/roles/3_azvnet/tasks/main.yml
---
- name: Create VNET
azure_rm_virtualnetwork: # VNET作成モジュール
resource_group: "{{ rgname }}" # リソースグループ
name: "{{ vnname }}" # VNETの名前
address_prefixes: "{{ vnaddress }}" # VNETに付与するアドレス帯
- name: Create SUBNET
azure_rm_subnet: # SubNet作成モジュール
resource_group: "{{ rgname }}" # リソースグループ
name: "{{ snname }}" # SubNetの名前
address_prefix: "{{ snaddress }}" # SubNetに付与するアドレス帯
virtual_network: "{{ vnname }}" # SubNetが関連するVNET
security_group_name: "{{ nsgname }}" # SubNetに紐づくNSG
【4_aznicpub】
vi /playbook/roles/4_aznicpub/tasks/main.yml
---
- name: Create a public ip address
azure_rm_publicipaddress: # publicip作成モジュール
resource_group: "{{ rgname }}" # リソースグループ
name: "{{ pubname }}" # publicipの名前
allocation_method: Static # 動的か静的か
- name: Create NIC
azure_rm_networkinterface: # Nic作成モジュール
resource_group: "{{ rgname }}" # リソースグループ
name: "{{ nicname }}" # NICの名前
virtual_network: "{{ vnname }}" # 関連付けを行うVNET
subnet: "{{ snname }}" # 関連付けを行うSubNet
public_ip_name: "{{ pubname }}" # 関連付けを行うpublicip
security_group: "{{ nsgname }}" # 関連付けを行うNSG(指定なしでも既定のルールで作られる)
【5_azvm】
vi /playbook/roles/5_azvm/tasks/main.yml
---
- name: Create VM
azure_rm_virtualmachine: # VM作成モジュール
resource_group: "{{ rgname }}" # リソースグループ
name: "{{ machinename }}" # VM名
vm_size: "{{ machinesize }}" # VMサイズ
network_interface_names: "{{ nicname }}"# 関連付けるNIC
admin_username: "{{ machineuser }}" # ログインユーザ名
admin_password: "{{ userpass }}" # ユーザパスワード
os_type: "{{ machinetype }}" # OStype(Linux Or Windows)
image: # OSイメージの設定
offer: "{{ machineos }}" # OS(例:CentOS,Windows)
publisher: "{{ machinepubli }}" # Publisher名(例:OpenLogic,MicrosoftWindowsServer)
sku: "{{ machinesku }}" # エディション(7.3,2016-Datacenter)
version: "{{ machinever }}" # イメージファイルVersion
(3).以下コマンドを実行し、[VARS(インベントリファイル)]を作成
※このファイルに上記[roles]で記載した変数の値を記載
vi /playbook/host_vars/localhost
---
### var ###
machinename: vmce02 # VM名
rgname: RG02 # リソースグループ
reasion: japaneast # リージョン
nsgname: NSG022 # ネットワークセキュリティグループ
vnname: VN02 # 仮想ネットワーク
vnaddress: <VNETipaddress> # 仮想ネットワークのアドレス帯
snname: SN02 # サブネット
snaddress: <SubNetipaddress> # サブネットのアドレス帯
pubname: "{{ machinename }}-pub" # PublicIP名
nicname: "{{ machinename }}-nic" # NIC名
machinesize: Standard_DS1_v2 # VMサイズ
machineuser: <user> # ログインユーザ
userpass: <userpassword> # ログインユーザのパスワード
machinetype: Linux # OS種別
machineos: CentOS # OSオファー
machinepubli: OpenLogic # Publisher
machinesku: '7.3' # エディション
machinever: latest # イメージのバージョン
(4).以下コマンドを実行し、[Site.yml]を作成
※role名を書いて記載純通りに実行させる
vi /playbook/site.yml
---
- name: azresorcegroupmake
hosts: localhost # 実行させるグループ
connection: local # localhostに対してつなげるときの宣言。SSHではなく直接実行する
roles: # 実行させる処理(記載された順番に実行される
- 1_azrg
- 2_aznsg
- 3_azvnet
- 4_aznicpub
- 5_azvm
####【4】Jenkinsジョブ作成,実行
前記事で作成したJenkinsコンテナにプレイブックを実行させるためのジョブを作成する。本稿は前の記事と同様の作成手順になりますので詳細は割愛します。
前記事URL:Jenkinsでコンテナ間接続とジョブ実行
(1).JenkinsのWEBにアクセスしログイン
URL:https://<hostserverIP>:8033
login : jenkinsadmin … 前記事で作成
pass : … 前記事で作成
(2).[新規ジョブ]をクリック
(3).以下を入力し「フリースタイル・プロジェクトのビルド」をクリック
[Enter an item name] : ジョブ名(AnsibleJOB2)
(4).[ビルド]、[ビルド手順の追加]より[リモートホストでシェルを実行]を選択する
(5).SSHサイトとシェルスクリプトにそれぞれ設定を行い保存する
SSHサイト:前記事で作成したSSHサイト
シェルスクリプト : Ansibleコンテナで実行させるコマンド
#実行ユーザ確認
whoami
#Ansible実行
ansible-playbook /playbook/site.yml
(6).「保存」して「ビルドを実行」する
(7).[実行したビルド]をクリックする
(8).「コンソール出力」をクリックして「コンソール出力内」で「Success」を確認
####【5】稼働確認
ここまでで目標を達成することはできました。最後は作成した「AzureVM」にログインできることを確認して終了。
本記事で作成したAzureリソースはページ上部の(■playbookで作成する環境)に記載。
【5-1】稼働確認
(1).「Azure Portal」へログイン
(2).「作成したリソースグループ(RG02)」へ移動
(3).「作成したリソースグループ(RG02)」ないのリソースが「Playbookで作成した内容」と同じかどうか判断する
(4).「作成した仮想マシン」に実際にログインできるかどうか確認する
【5-2】コンテナイメージのコミット
現段階で構築は終了となるため次回実行の為に今現在の「Ansibleコンテナ」と「Jenkinsコンテナ」の状態をコミットします
(1).「Ansibleコンテナ」と「Jenkinsコンテナ」を[Exit]で閉じる
(2).[Dockerホスト]にて以下のコマンドを実行し、「Ansibleコンテナ」と「Jenkinsコンテナ」をコミットする
# コミット前状況確認
docker images
# dockerプロセスの確認
docker ps -a
# dockerプロセスをコミット(「Ansibleコンテナ」)
docker commit <containerID> centos/ansiblebuild:2
# dockerプロセスをコミット(「Jenkinsコンテナ」)
docker commit <containerID> centos/jenkinsbuild:2
# コミット後状況確認
docker images
[root@VMDO001 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1650f986860e centos/ansiblebuild:1 "/sbin/init" 27 hours ago Up 27 hours 0.0.0.0:9033->22/tcp thirsty_kare
efadf1d923a4 centos/jenkinsbuild:latest "/sbin/init" 27 hours ago Up 27 hours 0.0.0.0:7033->22/tcp, 0.0.0.0:8033->8080/tcp cocky_keller
[root@VMDO001 ~]# docker commit 1650f986860e centos/ansiblebuild:2
sha256:a072db3085eaefd6e3937d275e2de703aea5abd3ed4ef07d46ef454b16d2e244
[root@VMDO001 ~]# docker commit efadf1d923a4 centos/jenkinsbuild:2
sha256:6eb530cfca1230c1b3cf74ff790e60949ac65c3374fb5ff8a95c2eebee0e9cb7
[root@VMDO001 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos/jenkinsbuild 2 6eb530cfca12 6 seconds ago 1.12 GB
centos/ansiblebuild 2 a072db3085ea About a minute ago 738.8 MB
centos/ansiblebuild 1 5ff360895e08 27 hours ago 738.8 MB
centos/jenkinsbuild latest 0640197d6307 47 hours ago 728.7 MB
docker.io/centos latest ff426288ea90 6 weeks ago 207.2 MB
[root@VMDO001 ~]#
⇒ 次回からは以下のイメージを起動させる事でコミット時の状況で起動する
docker run -p 9033:22 -itd --privileged --name ansible centos/ansiblebuild:2 /sbin/init
docker run -p 8033:8080 -p 7033:22 -itd --privileged --name jenkins centos/jenkinsbuild:2 /sbin/init
##■最後に
全4回にわたり、Dockerを起動させてPublicクラウドへのリソース作成環境を作成してみました。
Ansibleの作成していた時に思ったのですが、モジュールはAWSもありました。という事はアカウントとプレイブック次第ではAWSでも同様のことができると思います。
またDockerでSSH設定を行ったのは2台のコンテナを切り替えながらやるのが面倒だった為それぞれの環境にSSHで切るようにしていました。
一台のサーバで複数のコンテナを上げることができるDockerは今後外せない技術になるのではないでしょうか?
また、同時複数のエージェントに対し、ソフトウェアを使用しないでプロビジョニングを行えるAnsibleもやっぱり外せない技術だと思います。