AnsibleでUbuntu 14.04にLAMPをセットアップ


管理ホスト、対象ホスト共にUbuntu 14.04の環境でAnsibleを利用する手順について調べたことをまとめました。

インストール、動作確認、LAMP環境構築の順に解説しています。

LAMP環境を構築するPlaybookについてはGithubに公開していますので、全体のコードはこちらを参照ください:
https://github.com/hrendoh/ansible-lamp-simple

動作確認は、Ansibleの実行をVagrant上で、環境構築の対象サーバーはAWS EC2インスタンスで行っています。
Ansibleを実行する管理ホスト用のVagrantfileもGithubプロジェクトにいれてあるので、プロジェクトをClone後、この記事の内容をすぐに試せるようにしています。

また、LAMP構築のPlaybookは、公式のサンプル集 ansible/ansible-examples のLAMPサンプル lamp_simple をUbuntu 14.04用に修正したものになります。
CentOS、RHELを利用の場合は、公式のPlaybookが利用できます。

インストール

Ubuntu 14.04にAnsibleをインストールします。

デフォルトのAptリポジトリからインストールすると古い1.5.xがインストールされてしまうので、公式のPPAリポジトリを追加してインストールします。

$ sudo apt-get install software-properties-common
$ sudo apt-add-repository ppa:ansible/ansible
$ sudo apt-get update
$ sudo apt-get install ansible

公式ドキュメント Installation — Ansible Documentation には、 Latest Releases Via Apt (Ubuntu) に記述されています。

バージョンを確認すると2.1.1.0がインストールされました(2016年8月時点)

$ ansible --version
ansible 2.1.1.0
  config file = /etc/ansible/ansible.cfg
  configured module search path = Default w/o overrides

動作確認

動作確認として、Ansibleで対象ホストにディレクトリを作成してみます。

対象ホストへのSSH設定

Ansibleを実行するためは、管理ホストから対象ホストに対してssh接続できるようにしておきます。

Ansibleを、実行時に--private-keyオプションでSSHキーを指定する方法もありますが、ここでは、.ssh/configを利用します。

対象ホストのSSHキーansible-target.pem.sshディレクトリに置いたとすると、.ssh/configは以下のように記述します。

// .ssh/config
Host 192.168.33.10
  User vagrant
  Port 22
  IdentityFile ~/.ssh/ansible-target.pem

対象ホストもVagrantで試す場合は、Tipsの「VagrantのSSH秘密鍵をコピーするには」を参考に対象ホストの秘密鍵を管理ホストにコピーしてください。

参考: ansible.cnfでssh_configを設定する

テスト実行 (ディレクトリの作成)

管理ホストにsshしてhostsファイルとdir.ymlを作成します

# hosts
test ansible_ssh_host=192.168.33.10

hostsファイルの設定は、ホストとホストのグループを定義するInventoryと呼ばれる仕組みです。
Inventoryの設定ファイルは、コマンド実行時に-iオプションで渡すか、デフォルトで /etc/ansible/hosts に置きます。

# dir.yml
- hosts: test
  tasks:
    - file: path=/tmp/ansible-test state=directory

YAMLファイルは、PlaybookというChefのレシピに当たる環境構築の手順書です。

Playbookは、ansible-playbookコマンドで実行します。
ここでは、Inventoryのhostsファイル -iオプションでを指定しています。

$ ansible-playbook -i hosts dir.yml

Ansibleの実行結果は以下のように、色分けして表示されます。

ansible-test-run

対象ホストにログインすると、ディレクトリが作成されていることが確認できるはずです。

LAMP環境の構築

LAMP環境構築のPlaybookの全体はGithubを参照ください。
https://github.com/hrendoh/ansible-lamp-simple
(このPlaybookは、Vagrant box ubuntu/trusty64とAWS EC2の Ubuntu Server 14.04 LTS (HVM), SSD Volume Type – ami-2d39803a で動作を確認しています)

サーバーは、Apache + PHPのWebサーバーとMySQLをインストールするDBサーバーの2台を用意します。

対象ホストへのSSH接続準備

それぞれにsshで接続するための.ssh/configを作成します。

// .ssh/config
Host ec2-web
 User ubuntu
 HostName xx.yy.33.10
 Port 22
 IdentityFile ~/.ssh/ansible-lamp.pem
Host ec2-db
 User ubuntu
 HostName xx.yy.33.20
 Port 22
 IdentityFile ~/.ssh/ansible-lamp.pem

今回は、Hostにわかりやすい名前をつけています。

Inventory

Inventoryは、WebサーバーとDBサーバーでグループに分けています。

// hosts
[webservers]
web ansible_ssh_host=ec2-web

[dbservers]
db ansible_ssh_host=ec2-db

webserversが、Webサーバーとしてセットアップするグループ、dbserversはデータベースをセットアップするグループです。

ディレクトリ構造

LAMP構築のPlaybookは以下のようにディレクトリに分けて管理しています。

$ tree
.
├── group_vars
│   ├── all
│   └── dbservers
├── hosts
├── roles
│   ├── common
│   │   ├── handlers
│   │   │   └── main.yml
│   │   ├── tasks
│   │   │   └── main.yml
│   │   └── templates
│   │       └── ntp.conf.j2
│   ├── db
│   │   ├── handlers
│   │   │   └── main.yml
│   │   ├── tasks
│   │   │   └── main.yml
│   │   └── templates
│   │       └── my.cnf.j2
│   └── web
│       ├── handlers
│       │   └── main.yml
│       ├── tasks
│       │   ├── copy_code.yml
│       │   ├── install_httpd.yml
│       │   └── main.yml
│       └── templates
│           └── index.php.j2
└── site.yml

Inventoryがhosts、Playbookはsite.ymlなのは動作確認と同じです。
新しくgroup_varsとrolesを追加しています。

Roles

Roleは、大きなPlaybookを再利用しやすい単位に分割するしくみです。
公式ドキュメントでは「Playbook Roles and Include Statements」にRoleの使い方が説明されています。
AnsibleのRole入門」も参考になります。

各Roleのディレクトリは以下のように構成します。

  • tasks: タスクを定義します
  • handlers: ハンドラーを定義します
  • templates: templateモジュールで使うテンプレートJinja2を置きます
  • files: copyモジュールで使うファイルを置きます
  • vars: 変数を定義します
  • default: インクルードまたは、依存するロール用に変数のデフォルトをセットします。参照: Role Default Variables
  • meta: 依存するロールを指定します

ansible-lamp-simpleでは、common,dbおよびwebの3つのroleに分割しています。

  • common: すべてのホスト(ここでは、dbとweb)に適用するタスクを記述
  • db: MySQLをセットアップするタスクを記述
  • web: ApacheおよびPHPをインストールするタスクを記述

利用するroleの指定は、site.ymlのrolesに記述します。

// site.yml
---
- name: apply common configuration to all nodes
  hosts: all
  become: yes
  roles:
    - common

- name: configure and deploy the webservers and application code
  hosts: webservers
  become: yes
  roles:
    - web

- name: deploy MySQL and configure the databases
  hosts: dbservers
  become: yes
  roles:
    - db

group_vars

group_vars/<グループ名>のファイルには、以下のようにグループごとに利用する変数を設定しておけます。

例えば、dbserversグループで利用する変数は、groups_vars/dbserversに以下のようにMySQLのインストールに使用する値を指定しています。

// groups_vars/dbservers
---
mysqlservice: mysqld
mysql_port: 3306
dbuser: foouser
dbname: foodb
upassword: abc

これらの値は、db roleのmain.ymlやtemplates/my.cnf.j2で利用します。

公式ドキュメントでは「Splitting Out Host and Group Specific Data」に説明があります。

template: Jinja2

変数は、templateで利用可能です。
Ansibleは、templateにJinja2を利用しています。

以下は、dbロールで、MySQLインストール後に設定ファイルを作成するタスクで読み込まれるmy.cnfのテンプレートの一部ですが、このように変数を組み込んだmy.cnfを作成することができます。

// roles/db/templates/my.cnf.j2

# This will be passed to all mysql clients
# It has been reported that passwords should be enclosed with ticks/quotes
# escpecially if they contain &quot;#&quot; chars...
# Remember to edit /etc/mysql/debian.cnf when changing the socket location.
[client]
port        = {{ mysql_port }}
socket      = /var/run/mysqld/mysqld.sock
...

handlers

Handlerは、設定ファイルの変更した時などに、必要に応じてサービスを再起動する処理などをフックする仕組みです。

以下は、MySQLサービスを再起動するrestart mysqlという名前のHandlerを定義しています。

// roles/db/handlers/main.yml
---
- name: restart mysql
  service: name=mysql state=restarted

(参照: service – Manage services.)

Handlerを起動するには、各Taskの最後にnotifyを指定します。

以下のように、MySQLのセットアップTaskの場合、設定ファイルmy.cnfを生成するタスクのnotifyrestart mysqlを指定しています。

//roles/db/tasks/main.yml" firstline="10"] 
- name: Create Mysql configuration file
  template: src=my.cnf.j2 dest=/etc/mysql/my.cnf
  notify:
  - restart mysql

参考: Handlers: Running Operations On Change

Playbookを実行

$ ansible-playbook -i hosts site.yml

ブラウザで、http://<Webサーバーのアドレス>/index.php を開くと以下のように接続したデータベースのリストが表示されます。
ansible-lamp-sample

TIPS

VagrantのSSH秘密鍵をコピーするには

対象ホストもVagrantの場合は、以下のコマンドで管理ホストのVagrantに秘密キーをコピーします。

以下のコマンドをansibleを実行する管理ホストのVagrantホームで実行

$ vagrant ssh-config &gt; ssh-config
$ scp -F ssh-config path/to/ansible-target-node/.vagrant/machines/default/virtualbox/private_key default:.ssh/ansible-target.pem

対象ホストの変数を参照するには

$ ansible hostname -m setup

参照: Information discovered from systems: Facts

, ,