LoginSignup
7

More than 5 years have passed since last update.

Ansibleでクラウド構築(Azure)

Last updated at Posted at 2018-02-27

■初めに

 前回の記事からの続編です。
 前回までで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からの実行)
 

■イメージ

DOC04.png

■環境
-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コンテナ]を起動する

コマンド(root)(Dockerhost(vmdo01)から)

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
Result
[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コンテナ]になります

DOC10.png

【1】Azure環境へのログイン

 [Ansibleコンテナ]からAzureCLIを使用しAzure環境へログインする

 (1).[Ansibleコンテナ]よりAzure環境へログインする
     ※<SubScriptionID>は記憶しておく。

コマンド(root)
az login -u <Azureaccount> -p <password>
Result
[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環境を決定

コマンド(root)
az account set --subscription <SubScriptionID>
Result
[root@1650f986860e /]# az account set --subscription <SubScriptionID>
[root@1650f986860e /]#

【2】サービスプリンシパルと資格情報ファイルの作成

 サービスプリンシパルとはユーザーによって作成されたアプリやサービス、オートメーション ツールが特定の Azure リソースにアクセスする際に使うセキュリティ IDになります。AnsibleのplaybookをAzure環境へ実行させる際に必要になります。

【2-1】サービスプリンシパルの作成
 (1).以下「Azureコンテナ」よりコマンドを実行し「サービスプリンシパル」を作成する
     ※実行結果をテキスト等へ保存

コマンド(root)
az ad sp create-for-rbac --query [appId,password,tenant]
Result
[
  "<appId>",
  "<password>",
  "<tenant>"
]

【2-2】資格情報ファイルの作成
 (1).以下「Azureコンテナ」よりコマンドを実行し[資格情報ファイル]を作成する
     ※実行ユーザのホームディレクトリに作成すること(今回はroot)

コマンド(root)
# 実行前に存在しているか確認しなければ作成
mkdir ~/.azure
vi ~/.azure/credentials
credentials内容
# 【2-1】実行時に得た情報を記載する
[default]
subscription_id=<SubScriptionID>
client_id=<appId>
secret=<password>
tenant=<tenant>

【3】プレイブック作成

 プロビジョニングを行うファイルを作成します。基本的な構造はベストプラティクスを採用しているつもりですが、違っていたらごめんなさい。筆者の勉強不足です。とりあえず言える事は以下の構成で目的を達成することはできました。

 (1).以下コマンドを実行しディレクトリを作成

コマンド(root)
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】

コマンド(root)
vi /playbook/roles/1_azrg/tasks/main.yml
1_azrg/tasks/main.yml内容
# {{ 文字列 }}は変数
# 変数の値はパラメータとなる
---
- name: Create resourcegroup
  azure_rm_resourcegroup: name={{ rgname }} location={{ reasion }}

【2_aznsg】

コマンド(root)
vi /playbook/roles/2_aznsg/tasks/main.yml
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】
「サブネット」も同時作成。またネットワークセキュリティグループはサブネットに付与している。

コマンド(root)
vi /playbook/roles/3_azvnet/tasks/main.yml
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】

コマンド(root)
vi /playbook/roles/4_aznicpub/tasks/main.yml
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】

コマンド(root)
vi /playbook/roles/5_azvm/tasks/main.yml
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]で記載した変数の値を記載

コマンド(root)
vi /playbook/host_vars/localhost
/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名を書いて記載純通りに実行させる

コマンド(root)
vi /playbook/site.yml
/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

DOC05.png

 (6).「保存」して「ビルドを実行」する

 (7).[実行したビルド]をクリックする

DOC06.png

 (8).「コンソール出力」をクリックして「コンソール出力内」で「Success」を確認

DOC07.png

【5】稼働確認

 ここまでで目標を達成することはできました。最後は作成した「AzureVM」にログインできることを確認して終了。
 本記事で作成したAzureリソースはページ上部の(■playbookで作成する環境)に記載。

【5-1】稼働確認
 (1).「Azure Portal」へログイン
 (2).「作成したリソースグループ(RG02)」へ移動
 (3).「作成したリソースグループ(RG02)」ないのリソースが「Playbookで作成した内容」と同じかどうか判断する
DOC08.png

 (4).「作成した仮想マシン」に実際にログインできるかどうか確認する
DOC09.png

【5-2】コンテナイメージのコミット
 現段階で構築は終了となるため次回実行の為に今現在の「Ansibleコンテナ」と「Jenkinsコンテナ」の状態をコミットします

 (1).「Ansibleコンテナ」と「Jenkinsコンテナ」を[Exit]で閉じる
 (2).[Dockerホスト]にて以下のコマンドを実行し、「Ansibleコンテナ」と「Jenkinsコンテナ」をコミットする

コマンド[Dockerホスト]
# コミット前状況確認
docker images
# dockerプロセスの確認
docker ps -a
# dockerプロセスをコミット(「Ansibleコンテナ」)
docker commit <containerID> centos/ansiblebuild:2
# dockerプロセスをコミット(「Jenkinsコンテナ」)
docker commit <containerID> centos/jenkinsbuild:2
# コミット後状況確認
docker images
Result
[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 ~]#

⇒ 次回からは以下のイメージを起動させる事でコミット時の状況で起動する

[Ansibleコンテナ]起動
docker run -p 9033:22 -itd --privileged --name ansible centos/ansiblebuild:2 /sbin/init
[Jenkinsコンテナ]起動
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もやっぱり外せない技術だと思います。

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
  3. You can use dark theme
What you can do with signing up
7