【連載01】108.最小構成CentOS7からAnsibleに制御されるCentOS7を構築する（On Vagrant）

<b><font color="#ff6633">当記事はケーススタディの連載となっています。目次は[【こちら】](http://qiita.com/CsFactoryitter/items/6b8308b96afafd61ce5f
)です。</font></b>
<b><font color="#ff6633">最新のソースコードは[【GitHub】](https://github.com/csfactorygihubblog001/blogvagrant)で公開中です。</font></b>

今回は赤い部分のサーバ構成(adminserv01、apserv01、dbserv01)をVagrantで構築し、「manageterm」からAnsibleを実行し操作可能な設定を行います。

必要に応じて過去の記事を参照ください。

- 全体像について
[Vagrant-Ansible-Serverspecによるサーバ構築とサーバテスティング](http://qiita.com/CsFactoryitter/items/35977a5d18aa121bb24c)

- Windows構成は、
[VirtualBox内のLinuxイメージをVagrantBoxファイルに変換する](http://qiita.com/CsFactoryitter/items/60b65ae685a3ea4ee16f)

- Vagrantの基本的な操作の流れは、
[VagrantBoxの初期化から複数サーバ起動までの一般的な流れ](http://qiita.com/CsFactoryitter/items/1f3935d3b0f04c1ad49d)

![サーバ構成](https://qiita-image-store.s3.amazonaws.com/0/98085/ba1130c1-f9c5-2fd1-431b-a03b76a1921f.png)

---
#Vagrantコマンドで「basecent7」(ベースとなる最小構成CentOS7)からVagrantBoxファイルを作成する

[最小構成Centos7からansible実行可能な操作用Linux7を作成する](http://qiita.com/CsFactoryitter/items/ab7e749169c79672bef1)とほぼ同じ設定です。これが終わっている前提で進めます。
Vagrantfileは既に作成されている為、今回はVagrantfileは作らず、Vagrantfileを修正して3台(adminserv01,apserv01,dbserv01)を作成します。

##Windows設定編(主にPowershell操作)

###1.VagrantfileのDIRに移動
Vagrant実行のルートDIRに移動する。

```ps1:
cd D:\_BLOG\BG001\vagrant_box
```

###2.サーバ3台を構築
[最小構成Centos7からansible実行可能な操作用Linux7を作成する](http://qiita.com/CsFactoryitter/items/ab7e749169c79672bef1)で作成済のbasepackage.boxをベースにサーバを構築する。

書式：
>vagrant box add \${box内での名前} {$ベースとなる.boxファイル}

例：adminserv01

```ps1:
vagrant box add adminserv01 ../vagrant_boxfiles/basepackage.box
```

実行イメージ：
![image](https://qiita-image-store.s3.amazonaws.com/0/98085/dec372fc-3984-0cad-28a2-fab1a3725257.png)


例：dbserv01

```ps1:
vagrant box add dbserv01 ../vagrant_boxfiles/basepackage.box
```

実行イメージ：
![image](https://qiita-image-store.s3.amazonaws.com/0/98085/c67749d4-dd56-41ef-6b28-40c47fa3d9de.png)

例：apserv01

```ps1:
vagrant box add apserv01 ../vagrant_boxfiles/basepackage.box
```

実行イメージ：
![image](https://qiita-image-store.s3.amazonaws.com/0/98085/d5f224be-76f6-0c06-75da-dc1818473267.png)


実行結果コンソール

```ps1:
PS D:\_BLOG\BG001\vagrant_box> vagrant box add adminserv01 ../vagrant_boxfiles/basepackage.box
==> box: Box file was not detected as metadata. Adding it directly...
==> box: Adding box 'adminserv01' (v0) for provider:
    box: Unpacking necessary files from: file://D:/_BLOG/BG001/vagrant_boxfiles/basepackage.box
    box: Progress: 100% (Rate: 43.2M/s, Estimated time remaining: --:--:--)
==> box: Successfully added box 'adminserv01' (v0) for 'virtualbox'!
 
PS D:\_BLOG\BG001\vagrant_box> vagrant box add dbserv01 ../vagrant_boxfiles/basepackage.box
==> box: Box file was not detected as metadata. Adding it directly...
==> box: Adding box 'dbserv01' (v0) for provider:
    box: Unpacking necessary files from: file://D:/_BLOG/BG001/vagrant_boxfiles/basepackage.box
    box: Progress: 100% (Rate: 66.7M/s, Estimated time remaining: --:--:--)
==> box: Successfully added box 'dbserv01' (v0) for 'virtualbox'!
 
PS D:\_BLOG\BG001\vagrant_box> vagrant box add apserv01 ../vagrant_boxfiles/basepackage.box
==> box: Box file was not detected as metadata. Adding it directly...
==> box: Adding box 'apserv01' (v0) for provider:
    box: Unpacking necessary files from: file://D:/_BLOG/BG001/vagrant_boxfiles/basepackage.box
    box: Progress: 100% (Rate: 76.7M/s, Estimated time remaining: --:--:--)
==> box: Successfully added box 'apserv01' (v0) for 'virtualbox'!
```

###3.Vagrantへの登録を確認
boxの一覧を表示し、Vagrantに登録されたかを確認する。

書式：

>vagrant box list

例：

```ps1:
vagrant box list
```

実行イメージ：
![image](https://qiita-image-store.s3.amazonaws.com/0/98085/0bb8cdb5-29b0-bfc7-71f3-84f4d0872451.png)

実行結果コンソール：

```ps1:
PS D:\_BLOG\BG001\vagrant_box> vagrant box list
adminserv01 (virtualbox, 0)
apserv01    (virtualbox, 0)
dbserv01    (virtualbox, 0)
manageterm  (virtualbox, 0)
```

###4.Vagrantfileの修正
「[最小構成Centos7からansible実行可能な操作用Linux7を作成する](http://qiita.com/CsFactoryitter/items/ab7e749169c79672bef1)」で作成したVagrantfileを修正する。

参照ファイル：
D:\_BLOG\BG001\vagrant_box\Vagrantfile

Vagrantfileは以下の通り設定済み。

```bash:vagrantfile
Vagrant.configure(2) do |config|
  config.vm.box = "manageterm"
  #ホスト名の設定
  config.vm.hostname = "manageterm"
  #ネットワークの設定(ホストとゲスト間のプライベートネットワーク（不要ならコメント)
  config.vm.network "private_network", ip: '192.168.134.195'
  #ネットワークの設定(ホストと同じセグメントのネットワークに入る設定)
  config.vm.network "public_network", ip: '192.168.102.195'
 
  config.vm.provider "virtualbox" do |vb|
  #VirtualBoxが起動している時にGUIで表示する
  vb.gui = true
  #メモリを1Gに増やす
  vb.memory = "1024"
  end
end
```

![image](https://qiita-image-store.s3.amazonaws.com/0/98085/2cca1ae1-7ebf-e31c-b465-fb0e727f1c46.png)

###5.Vagrantfileを複数のサーバ設定用に変更
4.の設定ファイルを以下のように編集する。
（編集というより新規に書き直すことをお勧めします。）

4.の設定ファイルでは「manageterm」のみの設定。
アプリケーションサーバ、DBサーバ、管理サーバの追加と既存の「manageterm」を編集する。

編集ファイル：
D:\_BLOG\BG001\vagrant_box\Vagrantfile

編集箇所はサーバ単位に以下を追加。

```bash:vagrantfile
config.vm.define :${サーバ名} do |${サーバ名}|
#このブロックに設定を記述
#1台管理の場合はconfigでしたが複数台の場合は当該ブロックに渡されるapserv01のvmの設定を編集する為
#config.vm.hostname  →${サーバ名}.vm.hostname に変更する。
end
```

![image](https://qiita-image-store.s3.amazonaws.com/0/98085/72b5a99b-562d-5df2-ace4-2a5fc2bf8b70.png)

```bash:vagrantfile
Vagrant.configure(2) do |config|

#   vagrant init ${boxname} で作成したhost名を指定する。
#   当該boxをベースにして以下の１－４は作成される
  config.vm.box = "manageterm"

#   *************** １：アプリケーションサーバ用 *************** 
  config.vm.define :apserv01 do |apserv01|
#   ホスト名の指定
    apserv01.vm.hostname = "apserv01"
    #   ネットワークのタイプをＤＨＣＰではなくｓｔａｔｉｃにする。
    #ネットワークの設定(ホストとゲスト間のプライベートネットワーク（不要ならコメント)
    apserv01.vm.network "private_network", ip: '192.168.134.196'
    #ネットワークの設定(ホストと同じセグメントのネットワークに入る設定)
    apserv01.vm.network "public_network", ip: '192.168.102.196'

    apserv01.vm.provider "virtualbox" do |vb|
      #VirtualBoxが起動している時にGUIで表示する
                         vb.gui = true
      #メモリを1Gに設定
    end
  end

#   *************** ２：ＤＢサーバ用(IPアドレスとconfigの変数名のみ変更) *************** 
  config.vm.define :dbserv01 do |dbserv01|
    dbserv01.vm.hostname = "dbserv01"
    dbserv01.vm.network "private_network", ip: '192.168.134.197'
    dbserv01.vm.network "public_network", ip: '192.168.102.197'
    dbserv01.vm.provider "virtualbox" do |vb|
      vb.gui = true
    end
  end

#   *************** ３：管理サーバ用 IPアドレスとconfigの変数名のみ変更*************** 
  config.vm.define :adminserv01 do |adminserv01|
    adminserv01.vm.hostname = "adminserv01"
    adminserv01.vm.network "private_network", ip: '192.168.134.198'
    adminserv01.vm.network "public_network", ip: '192.168.102.198'
    adminserv01.vm.provider "virtualbox" do |vb|
      vb.gui = true
    end
  end

#   *************** ４：元々設定してたmanagetermも複数起動に際し変更 *************** 
  config.vm.define :manageterm do |manageterm|
  #   ホスト名の指定
    manageterm.vm.hostname = "manageterm"
    manageterm.vm.network "private_network", ip: '192.168.134.195'
    manageterm.vm.network "public_network", ip: '192.168.102.195'
    manageterm.vm.provider "virtualbox" do |vb|
      vb.gui = true
      vb.memory = "1024"
    end
  end
end
```

以下に続く起動ログからも分かるように、VirtualBoxをプロバイダーにVagrantfileに記述した仮想マシンの構築が開始される。
1台の時はdefaultで起動していたのが、それぞれに起動しているサーバのログが表示されるようになる。

```ps1:
Bringing machine 'apserv01' up with 'virtualbox' provider...
Bringing machine 'dbserv01' up with 'virtualbox' provider...
Bringing machine 'adminserv01' up with 'virtualbox' provider...
Bringing machine 'manageterm' up with 'virtualbox' provider...
==> apserv01: Importing base box 'manageterm'...
==> apserv01: Matching MAC address for NAT networking...
==> apserv01: Setting the name of the VM: vagrant_box_apserv01_1450880453736_83292
==> apserv01: Clearing any previously set network interfaces...
==> apserv01: Preparing network interfaces based on configuration...
    apserv01: Adapter 1: nat
    apserv01: Adapter 2: hostonly
    apserv01: Adapter 3: bridged
==> apserv01: Forwarding ports...
    apserv01: 22 => 2222 (adapter 1)
==> apserv01: Booting VM...
==> apserv01: Waiting for machine to boot. This may take a few minutes...
    apserv01: SSH address: 127.0.0.1:2222
    apserv01: SSH username: vagrant
    apserv01: SSH auth method: private key
    apserv01: Warning: Connection timeout. Retrying...
    apserv01: Warning: Remote connection disconnect. Retrying...
    apserv01: Warning: Remote connection disconnect. Retrying...
    apserv01: Warning: Remote connection disconnect. Retrying...
    apserv01:
    apserv01: Vagrant insecure key detected. Vagrant will automatically replace
    apserv01: this with a newly generated keypair for better security.
    apserv01:
    apserv01: Inserting generated public key within guest...
    apserv01: Removing insecure key from the guest if it's present...
    apserv01: Key inserted! Disconnecting and reconnecting using new SSH key...
==> apserv01: Machine booted and ready!
==> apserv01: Checking for guest additions in VM...
==> apserv01: Setting hostname...
==> apserv01: Configuring and enabling network interfaces...
==> apserv01: Mounting shared folders...
    apserv01: /vagrant => D:/_BLOG/BG001/vagrant_box
==> dbserv01: Importing base box 'manageterm'...
==> dbserv01: Matching MAC address for NAT networking...
==> dbserv01: Setting the name of the VM: vagrant_box_dbserv01_1450880551191_79254
==> dbserv01: Fixed port collision for 22 => 2222. Now on port 2200.
==> dbserv01: Clearing any previously set network interfaces...
==> dbserv01: Preparing network interfaces based on configuration...
    dbserv01: Adapter 1: nat
    dbserv01: Adapter 2: hostonly
    dbserv01: Adapter 3: bridged
==> dbserv01: Forwarding ports...
    dbserv01: 22 => 2200 (adapter 1)
==> dbserv01: Booting VM...
==> dbserv01: Waiting for machine to boot. This may take a few minutes...
    dbserv01: SSH address: 127.0.0.1:2200
    dbserv01: SSH username: vagrant
    dbserv01: SSH auth method: private key
    dbserv01: Warning: Connection timeout. Retrying...
    dbserv01: Warning: Remote connection disconnect. Retrying...
    dbserv01: Warning: Remote connection disconnect. Retrying...
    dbserv01: Warning: Remote connection disconnect. Retrying...
    dbserv01:
    dbserv01: Vagrant insecure key detected. Vagrant will automatically replace
    dbserv01: this with a newly generated keypair for better security.
    dbserv01:
    dbserv01: Inserting generated public key within guest...
    dbserv01: Removing insecure key from the guest if it's present...
    dbserv01: Key inserted! Disconnecting and reconnecting using new SSH key...
==> dbserv01: Machine booted and ready!
==> dbserv01: Checking for guest additions in VM...
==> dbserv01: Setting hostname...
==> dbserv01: Configuring and enabling network interfaces...
==> dbserv01: Mounting shared folders...
 
    dbserv01: /vagrant => D:/_BLOG/BG001/vagrant_box
==> adminserv01: Importing base box 'manageterm'...
==> adminserv01: Matching MAC address for NAT networking...
==> adminserv01: Setting the name of the VM: vagrant_box_adminserv01_1450880646683_29815
==> adminserv01: Fixed port collision for 22 => 2222. Now on port 2201.
==> adminserv01: Clearing any previously set network interfaces...
==> adminserv01: Preparing network interfaces based on configuration...
    adminserv01: Adapter 1: nat
    adminserv01: Adapter 2: hostonly
    adminserv01: Adapter 3: bridged
==> adminserv01: Forwarding ports...
    adminserv01: 22 => 2201 (adapter 1)
==> adminserv01: Booting VM...
==> adminserv01: Waiting for machine to boot. This may take a few minutes...
    adminserv01: SSH address: 127.0.0.1:2201
    adminserv01: SSH username: vagrant
    adminserv01: SSH auth method: private key
    adminserv01: Warning: Connection timeout. Retrying...
    adminserv01: Warning: Remote connection disconnect. Retrying...
    adminserv01: Warning: Remote connection disconnect. Retrying...
    adminserv01: Warning: Remote connection disconnect. Retrying...
    adminserv01:
    adminserv01: Vagrant insecure key detected. Vagrant will automatically replace
    adminserv01: this with a newly generated keypair for better security.
    adminserv01:
    adminserv01: Inserting generated public key within guest...
    adminserv01: Removing insecure key from the guest if it's present...
    adminserv01: Key inserted! Disconnecting and reconnecting using new SSH key...
==> adminserv01: Machine booted and ready!
==> adminserv01: Checking for guest additions in VM...
==> adminserv01: Setting hostname...
==> adminserv01: Configuring and enabling network interfaces...
==> adminserv01: Mounting shared folders...
 
    adminserv01: /vagrant => D:/_BLOG/BG001/vagrant_box
==> manageterm: Importing base box 'manageterm'...
==> manageterm: Matching MAC address for NAT networking...
==> manageterm: Setting the name of the VM: vagrant_box_manageterm_1450880743407_45891
==> manageterm: Fixed port collision for 22 => 2222. Now on port 2202.
==> manageterm: Clearing any previously set network interfaces...
==> manageterm: Preparing network interfaces based on configuration...
    manageterm: Adapter 1: nat
    manageterm: Adapter 2: hostonly
    manageterm: Adapter 3: bridged
==> manageterm: Forwarding ports...
    manageterm: 22 => 2202 (adapter 1)
==> manageterm: Running 'pre-boot' VM customizations...
==> manageterm: Booting VM...
==> manageterm: Waiting for machine to boot. This may take a few minutes...
    manageterm: SSH address: 127.0.0.1:2202
    manageterm: SSH username: vagrant
    manageterm: SSH auth method: private key
    manageterm: Warning: Connection timeout. Retrying...
    manageterm: Warning: Remote connection disconnect. Retrying...
    manageterm: Warning: Remote connection disconnect. Retrying...
    manageterm: Warning: Remote connection disconnect. Retrying...
    manageterm:
    manageterm: Vagrant insecure key detected. Vagrant will automatically replace
    manageterm: this with a newly generated keypair for better security.
    manageterm:
    manageterm: Inserting generated public key within guest...
    manageterm: Removing insecure key from the guest if it's present...
    manageterm: Key inserted! Disconnecting and reconnecting using new SSH key...
==> manageterm: Machine booted and ready!
==> manageterm: Checking for guest additions in VM...
==> manageterm: Setting hostname...
==> manageterm: Configuring and enabling network interfaces...
==> manageterm: Mounting shared folders...
    manageterm: /vagrant => D:/_BLOG/BG001/vagrant_box
```

###6.起動状態を確認
Vagrantfileにて設定したサーバがすべて起動していることを確認する。

書式：

>vagrant status

例：

```ps1:
vagrant status
```

実行イメージ：
![image](https://qiita-image-store.s3.amazonaws.com/0/98085/1fd80f70-e654-20f8-b400-8ceb1ee0da17.png)

実行結果コンソール：

```ps1:
PS D:\_BLOG\BG001\vagrant_box> vagrant status
Current machine states:

apserv01                  running (virtualbox)
dbserv01                  running (virtualbox)
adminserv01               running (virtualbox)
manageterm                running (virtualbox)
```

###7.Vagrantで起動されているVirtualBoxVMの終了
一旦全てのサーバをシャットダウンする。

書式：

>vagrant halt

例：

```ps1:
vagrant halt
```

実行結果コンソール：

```ps1:
PS D:\_BLOG\BG001\vagrant_box> vagrant halt
==> manageterm: Attempting graceful shutdown of VM...
==> adminserv01: Attempting graceful shutdown of VM...
==> dbserv01: Attempting graceful shutdown of VM...
==> apserv01: Attempting graceful shutdown of VM...
```

###8.Vagrantの状態を確認
全てpoweroffになっていることが確認できる。

書式：

>vagrant status

例：
```ps1:
vagrant status
```

実行イメージ：
![image](https://qiita-image-store.s3.amazonaws.com/0/98085/231755da-5e80-4783-9ec7-7de03e5e3ad4.png)

実行結果コンソール：

```ps1:
PS D:\_BLOG\BG001\vagrant_box> vagrant status
Current machine states:

apserv01                  poweroff (virtualbox)
dbserv01                  poweroff (virtualbox)
adminserv01               poweroff (virtualbox)
manageterm                poweroff (virtualbox)
```

###9.Ansible操作端末「manageterm」のリパッケージング
Ansibleは操作される端末に特にエージェントを入れる必要がない。
その為、今回は「manageterm」のみ「yum -y install ansible」(「[最小構成Centos7からansible実行可能な操作用Linux7を作成する](http://qiita.com/CsFactoryitter/items/ab7e749169c79672bef1)」参照)のみインストールした。

折角なので「manageterm」のみリパッケージし、VagrantBoxファイルを作成する。
 
書式：
>vagrant package \${Vagrantで管理されている名前} --output ${出力するファイルパス名}

例：
>vagrant package manageterm --output  ..\vagrant_boxfiles/manageterm.box

実行結果コンソール：

```ps1:
PS D:\_BLOG\BG001\vagrant_box> vagrant package manageterm --output ..\vagrant_boxfiles/manageterm.box
==> manageterm: Exporting VM...
==> manageterm: Compressing package to: D:/_BLOG/BG001/vagrant_boxfiles/manageterm.box
```

実際に作成されたかをlsで確認する。

```ps1:
PS D:\_BLOG\BG001\vagrant_box> ls ..\vagrant_boxfiles
 
 
    ディレクトリ: D:\_BLOG\BG001\vagrant_boxfiles
 
 
Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---        2015/12/23     16:40  686164629 basepackage.box
-a---        2015/12/24      0:21  686028022 manageterm.box
```

###10.まとめ
以上でAnsibleにてサーバを構築する準備ができました。
実際のところVagrantを使用せずにAnsibleを実行しても構いません。

Vagrantを使用してAnsibleの実行できる環境を使用した理由は、サーバ設定コーディングがプログラムやデータベースと違いロールバックやコミットが容易に出来ないからです。その為、サーバ設定は変更を加えると戻すのが難しいのです。
サーバ設定において冪統性（何度やっても同じで有る事）を担保するには簡単にサーバの設定を戻せるVagrantがあると非常に楽にロールバックができます。
今回は使用していませんが、VagarntではVirtualBoxのスナップショット機能を使用して設定した状態をロールバック/コミットするプラグインがあります。サーバ構築もプログラミングの世界同様の環境が「Vagrant + Ansible(chefでもいいです) + Serverspec」により実現可能な時代になったと思います。

この先
・プログラマーはシステム開発だけでなく<b>サーバ構築</b>を
・インフラ技術者はサーバ構築<b>プログラミング</b>を
する時代になってきたと思います。

サーバ構築は難しく、プログラミングも難しい世界です。

両者が相互の領域に踏み込み、インフラ構築技術者とプログラム実装者が<b>スクラムを組みシステムを作り上げる事が出来ればバスワードでないDevOpsの時代</b>が来ると思います。
「Infrastructure as Code」が単なるツールではなく両者の垣根を超えるホントの意味の道具になってくれたらなっと思います。

っとまだ続くのですが。。ブログ書くの大変ｗ

次回は「[AnsibleでCentOS7サーバ群に接続し、サーバの状態をコミットするまで](http://qiita.com/CsFactoryitter/items/032cc339048e52ee3586)」について。

<b><font color="#ff6633">連載の目次は[【こちら】](http://qiita.com/CsFactoryitter/items/6b8308b96afafd61ce5f
)です。</font></b>