Vagrant + Ansible で環境構築+ベンチマークテスト実行自動化(IDCFクラウド)
1. 概要
クラウドサーバーサービス(IaaS)の性能比較・ディスク編~IOPSの計測~ の番外編です。
Vagrantでクラウド上にインスタンスを作成し、Ansibleでアプリインストール・実行・結果取得まで自動化します。
今回はIDCFクラウドを対象に記事をまとめます。
1.1 実行環境(ホスト側)
- OS : Linux AMI release 2017.03
- Vagrant : 1.9.4
- Ansible : ansible 2.3.0.0
1.2 構築対象
- Iaas: IDCFクラウド
- OS:CentOS 7.3
- インストール及び実行するアプリケーション: fio
2. 事前準備
2.1. Vagrantにdotenvプラグインをインストール
Vagrant上で .env
から変数の読み込みができるように、dotenvプラグインをインストールしておきます。
$ vagrant plugin install dotenv
2.2 VagrantにCloudStackのプラグインをインストール
VagrantからIDCFクラウドのインスタンスを扱うために、CloudStackのプラグインをインストールします。
バージョン指定でインストールしています。
$ vagrant plugin install vagrant-cloudstack --plugin-version 1.3.0
3. Vagrantの設定
3.1 Vagrantfile
Vagrantの設定ファイルであるVagrantfile(最初は大文字、拡張子なし)を作成します。
以下の例では、CloudStackを使ってIDCFクラウド上に仮想サーバを作成し、完了後にAnsibleを呼び出しています。
Vagrantfile
Dotenv.load
Vagrant.configure(2) do |config|
config.vm.box = "dummy"
# CloudStack Setting For IDCF Cloud
config.vm.provider :cloudstack do |cloudstack, override|
# Dummy Box
override.vm.box = "dummy"
override.vm.box_url = "https://github.com/klarna/vagrant-cloudstack/raw/master/dummy.box"
# API Parameters
cloudstack.host = "compute.jp-east-2.idcfcloud.com"
cloudstack.path = "/client/api"
cloudstack.port = "443"
cloudstack.scheme = "https"
cloudstack.api_key = "#{ENV['CLOUDSTACK_API_KEY']}"
cloudstack.secret_key = "#{ENV['CLOUDSTACK_SECRET_KEY']}"
expunge_on_destroy = true
# Virtual Machine Settings
cloudstack.display_name = "Vagrant-CentOS-7"
cloudstack.template_name = "CentOS 7.3 64-bit"
cloudstack.zone_name = "#{ENV['CLOUDSTACK_ZONE_NAME']}"
cloudstack.service_offering_name = "#{ENV['COUDSTACK_SERVICE_OFFERING_NAME']}"
# Network Settings
cloudstack.pf_ip_address_id = "#{ENV['CLOUDSTACK_PF_IP_ADDRESS_ID']}"
cloudstack.pf_public_port = "2201"
cloudstack.keypair = "#{ENV['CLOUDSTACK_SSH_KEYPAIR']}"
override.ssh.private_key_path = "#{ENV['VAGRANT_SSH_PRIVATE_KEY']}"
override.ssh.username = "#{ENV['VAGRANT_SSH_USERNAME']}"
cloudstack.instance_ready_timeout = 1800
end
#
# Run Ansible from the Vagrant Host
#
config.vm.provision "ansible" do |ansible|
ansible.playbook = "site.yaml"
ansible.inventory_path = "hosts"
ansible.limit = 'all'
ansible.verbose = true
end
end
CloudStack 参考 :
Vagrantを使ってCloudStack上の環境構築をしてみよう
vagrant-cloudstackを試してみた
Ansible呼び出し参考 :
Vagrant公式 : Ansible Provisioner
3.2 .env
認証情報等の変数を .env というファイルに記述し、.envはVagrantfileと同じ場所に保存しておきます。
CLOUDSTACK_API_KEY = '**********'
CLOUDSTACK_SECRET_KEY = '**********'
CLOUDSTACK_ZONE_NAME = 'lux'
COUDSTACK_SERVICE_OFFERING_NAME = 'light.S1'
CLOUDSTACK_PF_IP_ADDRESS_ID = '**********'
CLOUDSTACK_SSH_KEYPAIR = '**********'
VAGRANT_SSH_USERNAME = 'root'
VAGRANT_SSH_PRIVATE_KEY = '~/.ssh/id_rsa'
ANSIBLE_PLAYBOOK = 'site.yml'
ANSIBLE_INVENTORY_PATH = 'hosts'
4. Ansibleの設定
4.1 Hostsファイル
Vagrantfileの中の ansible.inventory_path
で指定した場所に置いておきます。今回の例では Vagrantfileと同じ階層にあります。
hosts
***.***.**.***:2201
- Vagrantで作成する仮想マシンのIPアドレスを指定します。
- Vagrantfileの中の
cloudstack.pf_public_port
でパブリックポートを2201
に変更しているので、IPアドレスの後ろにポート番号を指定します。未指定の場合Ansibleはデフォルトの22
でSSH接続するので、接続に失敗してしまいます。
4.2 PlayBook
自動構築したい内容を、AnsibleのPlaybook(拡張子.yml)に書いていきます。
4.2.1 Role
AnsibleはPlaybookをRoleごとに分けて書くことができます。決まったルールで roles のディレクトリを構成しておくと、自動的にPlaybookに include される仕組みです。実行内容ごとにRoleを分けて作っておけば、可読性や再利用性が高まります。
今回はVagrantfileを含め以下のようなファイル配置にしました。
hosts
roles/
iops/ # roleの名前(任意)
files/ # role内で使用するファイルを配置
Rand-Read-4k.fio
Rand-ReadWrite-4k.fio
Rand-Write-4k.fio
tasks/ # roleで実行されるtaskの定義
main.yml
vars/ # role内で使用する変数定義
main.yml
site.yml # Vagrantから呼ばれるPlaybook
Vagrantfile
4.2.2 最初に呼ばれるPlaybook
Vagrantfileの中の ansible.playbook
に指定したPlaybookが最初に実行されます。今回の例では Vagrantfileと同じ階層にある site.yaml
という名前のPlaybookです。
このPlaybookの中では、iops
というRoleを呼び出しています。
---
- hosts: servers
become: true
roles:
- iops
4.2.3 RoleごとのPlaybook (tasks/main.yml)
site.yaml
から呼び出されるPlaybookです。
今回はIOPSテストを行うため、以下の作業を実施します。
- fioをインストール
- fioの計測パラメータファイルをリモートに送信
- fioを実行
- 結果ファイルを受信
---
- name: install epel
yum:
name: epel-release
state: installed
- name: install fio
yum:
name: fio
state: installed
- name: copy Rand-Read-4k.fio
copy:
src: Rand-Read-4k.fio
dest: "{{ dest_dir }}"
- name: copy Rand-ReadWrite-4k.fio
copy:
src: Rand-ReadWrite-4k.fio
dest: "{{ dest_dir }}"
- name: copy Rand-Write-4k.fio
copy:
src: Rand-Write-4k.fio
dest: "{{ dest_dir }}"
- name: run fio Rand-Read-4k
command: "fio -f /tmp/Rand-Read-4k.fio -filename=/tmp/fio_test -output Rand-Read-4k.result"
- name: run fio Rand-ReadWrite-4k
command: "fio -f /tmp/Rand-ReadWrite-4k.fio -filename=/tmp/fio_test -output Rand-ReadWrite-4k.result"
- name: run fio Rand-Write-4k
command: "fio -f /tmp/Rand-ReadWrite-4k.fio -filename=/tmp/fio_test -output Rand-Write-4k.result"
- name: search files
find:
paths: "/root"
patterns: "*.result"
register: files_to_copy
- name: receive result
fetch:
src: "{{ item.path }}"
dest: "{{ receive_dir }}"
flat: yes
with_items: "{{ files_to_copy.files }}"
4.2.4 変数定義(vars/main.yml)
RoleごとのPlaybookで使用する変数を定義します。
dest_dir: /tmp/
receive_dir: ./results/
4.2.5 Playbookの確認テスト
これでAnsibleの設定は終了なので、間違いがないか確認しておきましょう。
■ Playbookの構文をチェック:
ansibleコマンドに「–syntax-check」オプションをつけて実行すると、Playbookの構文をチェックできます。
$ ansible-playbook site.yml --syntax-check
■ Dry Run:
ansibleコマンドに「–check」オプションをつけて実行すると、対象への変更は行わずに、Playbookを適用した結果起きる変化を確認できます。
$ ansible-playbook site.yml --check
■ 冗長モード:
もしインスタンスを起動した状態であれば、以下のようにAnsible単独で実行して確認することも可能です。ansibleコマンドに「-v(–verbose)」 オプションをつけて実行すると、詳細な出力を確認することができます。「-vvv」と指定すると、さらに詳細な出力になります。
$ ansible-playbook -i hosts site.yml --private-key=~/.ssh/id_rsa -u root -v
なお、前述のVagrantfile内のAnsibleの呼び出し部分でansible.verbose = true
とすると、冗長モードを指定したことになります。
■ ansible-lint:
Ansibleの機能ではありませんが、Playbookのチェックをしてくれるツールです。別途インストールが必要ですが、Playbookの改善点も指摘してくれます。
下記のように使います。
$ ansible-lint site.yml
参考:
Ansible:さらにPlaybookをきわめる
Ansible公式:Check Mode (“Dry Run”)
GitHub - willthames/ansible-lint: Best practices checker for Ansible
5. 実行
さあ、Vagrantから実行してみましょう。
Vagrantfile のある場所に移動して以下のコマンドを実行します。
$ vagrant up
4.2.4の変数定義で receive_dir
に指定した場所に、結果ファイルが入っていれば成功です。
おまけ.Vagrantの基本コマンド
- 起動:
$ vagrant up
- 停止:
$ vagrant halt
- 削除:
$ vagrant destroy
- 再読込:
$ vagrant reload
※–provisonでプロビジョニングも実施 - プロビジョンだけ実施:
$ vagrant provision