Posted at

今更だけどAnsibleでUbuntuにLAMPを構築する

More than 1 year has passed since last update.

この記事はほぼAnsibleでやっていることを解説するだけの記事です。コード読める人はコード読んだほうがいいと思います。

なんと仮想環境は使いません!実行確認したバージョンは以下の通り。

バージョン

Ansible
2.2.1.0

Ubuntu Server
14.04.4 LTS 64bit

Apache
2.4.7

MySQL
5.5.54

PHP
5.6.29

作ったもの:Yaruki00/ansible_ubuntu_lamp


はじめに

今回作ったものはphansibleというサイトで生成できるplaybookを元にしています。と言うかほぼそのままです。

もともとはVagrantを使って仮想UbuntuにAnsibleでLAMPを構築するようになっているのですが、わざわざVagrant部分は削除してます。

仮想環境でやりたいよ、という人はphansibleでポチポチしてplaybookを生成してみてください。


中身はどうなっているの


ディレクトリ構成

.

├── inventories
│   ├── dev
│   └── local
├── playbook.yml
├── roles
│   ├── apache
│   │   ├── handlers
│   │   │   └── main.yml
│   │   ├── tasks
│   │   │   └── main.yml
│   │   └── templates
│   │   ├── vhost22.conf.tpl
│   │   └── vhost24.conf.tpl
│   ├── mysql
│   │   └── tasks
│   │   └── main.yml
│   ├── php
│   │   ├── handlers
│   │   │   └── main.yml
│   │   ├── tasks
│   │   │   ├── configure.yml
│   │   │   ├── main.yml
│   │   │   ├── mod-php.yml
│   │   │   ├── pecl.yml
│   │   │   ├── php-cli.yml
│   │   │   └── php-fpm.yml
│   │   └── templates
│   │   └── extension.tpl
│   └── server
│   ├── tasks
│   │   └── main.yml
│   └── templates
│   └── timezone.tpl
└── vars
└── all.yml


実行

本当はsshで実行したいのですが、sudoで上手く行かなくなってしまうので、UbuntuにAnsibleをインストールした後、ローカルで実行します。

まずはAnsibleをインストールします。

$ sudo apt-get install software-properties-common

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

そして、playbook.ymlがあるディレクトリに移動し、以下のコマンドを叩きます。

$ ansible-playbook -i inventories/local -c local playbook.yml

-iでインベントリファイルを指定します。-cは接続方法を指定するオプションで-c localでローカル接続になります。普通はsshが使われます。

ローカル接続の場合でもインベントリファイルは何かしら指定しないといけないみたいです。

その他オプションについてはansible -helpなり調べるなりしてください。


インベントリファイル

対象ホストの情報を書くファイルです。グルーピングしたり、変数を用意してホストまたはグループで使うことができます。

書き方は以下を参照。

Ansibleのインベントリファイルでステージを切り替える

Ansibleのインベントリファイル

ポートやユーザを指定することもできます。

Ansibleでsshユーザを指定する

ローカル接続の場合は特に書くことないです。


inventories/local

[local]

localhost


変数ファイル

プレイブックやテンプレート内で使える変数を定義します。

phansibleで生成されるものでは、インストールするパッケージやユーザ情報などを記述しています。


vars/all.yml

---

server:
install: '1'
packages: [git]
timezone: Asia/Tokyo
locale: ja_JP.UTF-8
apache:
install: '1'
docroot: '/var/www/html'
servername: 'localhost'
mysql:
install: '1'
root_password: root
database: db
user: user
password: password
php:
install: '1'
ppa: php
packages: [php5.6-cli, php5.6-intl, php5.6-mcrypt, php5.6-curl, php5.6-fpm, php5.6-gd, php5.6-mbstring, php5.6-mysql]
config:
- regexp: '^;(mbstring.language) =.*'
line: '\1 = Japanese'
- regexp: '^;(mbstring.internal_encoding) =.*'
line: '\1 = UTF-8'
- regexp: '^;(mbstring.http_input) =.*'
line: '\1 = pass'
- regexp: '^;(mbstring.http_output) =.*'
line: '\1 = pass'
- regexp: '^;(mbstring.encoding_translation) =.*'
line: '\1 = off'


プレイブック

Ansibleに実行させる内容を記述します。

書き方は公式ページをどうぞ。

Playbooks


playbook.yml

---

- hosts: all
become: true
vars_files:
- vars/all.yml
roles:
- server
- apache
- mysql
- php

vars_filesで先程定義した変数ファイルを指定します。

rolesというのがディレクトリのrolesに対応していて、4つの役割があることがわかります。


ロール

roles以下は今回は3つのディレクトリがあります。tasksのみ必須で、後は無くても大丈夫です。


ディレクトリ


タスク

tasks以下に配置します。mainという名前のものが最初に実行されます。


ハンドラ

handlers以下に配置します。タスクからnotifyで呼び出すことができます。


テンプレート

templates以下に配置します。タスクからtemplateで使うことができます。設定ファイルなどのテンプレートに使われます。

他にも幾つかあるので、必要に応じて適宜用意してください。

AnsibleのRole入門

Ansibleのroleを使いこなす


server

名前が微妙な気もしますが、内容はUbuntuでできることをやってます。


  1. apt-getのアップデート

  2. 基本パッケージのインストール

  3. その他のパッケージのインストール

  4. タイムゾーン設定

  5. 言語設定

といった流れです。


roles/server/tasks/main.yml

---

- name: Update apt
become: true
apt: update_cache=yes

- name: Install System Packages
become: yes
apt: pkg={{ item }} state=latest
with_items:
- curl
- wget
- python-software-properties

- name: Install Extra Packages
become: yes
apt: pkg={{ item }} state=latest
with_items: "{{server.packages}}"
when: server.packages is defined

- name: Configure the timezone
become: yes
template: src=timezone.tpl dest=/etc/timezone

- name: More Configure the timezone
become: yes
file: src=/usr/share/zoneinfo/{{server.timezone}} dest=/etc/localtime state=link force=yes backup=yes

- name: Set default system language pack
shell: locale-gen {{server.locale}}
become: yes

- name: Update locale
shell: update-locale LANG={{server.locale}}
become: yes



apache

Webサーバをインストールします。


  1. 最新のApacheをインストール

  2. モジュールをインストールして再起動

  3. バージョン確認して変数に入れる

  4. 変数のバージョンを見て、バーチャルホストの設定ファイル生成

といった流れです。バーチャルホストの設定ファイル生成がApache2.4と2.2向けに2つありますが、2.2はもはやいらなさそうな気がします。


roles/apache/tasks/main.yml

---

- name: Install Apache
become: yes
apt: pkg=apache2 state=latest

- name: Install Apache Modules
apache2_module: state=present name={{ item }}
notify: restart apache
with_items:
- rewrite
- vhost_alias
- headers
- expires
- filter

- shell: apache2 -v
register: apache_version

- name: Change default apache2.4 site
become: yes
template: src=vhost24.conf.tpl dest=/etc/apache2/sites-available/000-default.conf
notify: restart apache
when: apache_version.stdout.find('Apache/2.4.') != -1

- name: Change default apache2.2 site
become: yes
template: src=vhost22.conf.tpl dest=/etc/apache2/sites-available/default
notify: restart apache
when: apache_version.stdout.find('Apache/2.2.') != -1



mysql

DBをインストールします。


  1. ホスト名を変数に入れる

  2. mysqlのインストール

  3. パスワード設定

  4. データベース作成

  5. 不正なユーザがいないか確認

  6. ユーザ作成

といった流れです。


roles/mysql/tasks/main.yml

---

# Retrieve the current hostname, because {{ ansible_hostname }} still contains the old name
- shell: hostname
register: current_hostname

- name: mysql | Install MySQL Packages
become: yes
apt: pkg={{ item }} state=latest
with_items:
- mysql-server
- mysql-client
- python-mysqldb

- name: mysql | Update root password for all root accounts
mysql_user: name=root host={{ item }} check_implicit_admin=yes password={{ mysql.root_password }} login_user=root login_password={{ mysql.root_password }}
with_items:
- "{{ current_hostname.stdout | lower }}"
- 127.0.0.1
- ::1
- localhost

- name: mysql | Create databases
mysql_db: name={{ mysql.database }} state=present login_user=root login_password={{ mysql.root_password }}
when: mysql.database is defined

- name: mysql | Ensure anonymous users are not in the database
mysql_user: name='' host={{ item }} state=absent login_user=root login_password={{ mysql.root_password }}
with_items:
- localhost
- "{{ current_hostname.stdout | lower }}"

- name: mysql | Create users
mysql_user: name={{ mysql.user }} password={{ mysql.password }} priv={{ mysql.database }}.*:ALL state=present login_user=root login_password={{ mysql.root_password }}



php

PHPをインストールします。


  1. aptのリポジトリ追加

  2. aptのアップデート

  3. PHP5.6のインストール

  4. パッケージのインストール

  5. 次のプレイブックへ

といった流れです。Apacheを使う場合はphp-fpmのインストールは無くても大丈夫です。


roles/php/tasks/main.yml

---

- name: Add ppa Repository
become: yes
apt_repository: repo=ppa:ondrej/{{ php.ppa }}

- name: Update apt
become: yes
apt: update_cache=yes

- name: Install php5.6
become: yes
apt: pkg=php5.6 state=latest

- name: Install php5-fpm
sudo: yes
apt: pkg=php5-fpm state=latest

- name: Install PHP Packages
become: yes
apt: pkg={{ item }} state=latest
with_items: "{{php.packages}}"
when: php.packages is defined

- include: configure.yml
- include: pecl.yml


configure.ymlではPHPの実装ごとに設定を行っていきます。Apacheを使う場合はmod-php.ymlだけ実行されれば大丈夫です。


roles/php/tasks/configure.yml

---

- stat: path=/etc/php/5.6/apache2/php.ini
register: modphp

- stat: path=/etc/php/5.6/fpm/php.ini
register: phpfpm

- stat: path=/etc/php/5.6/cli/php.ini
register: phpcli

- include: php-fpm.yml
when: phpfpm.stat.exists

- include: php-cli.yml
when: phpcli.stat.exists

- include: mod-php.yml
when: modphp.stat.exists


mod-php.ymlでは主に各モジュールを有効化します。


roles/php/tasks/mod-php.yml

---

- name: ensure timezone is set in apache2 php.ini
lineinfile: dest=/etc/php/5.6/apache2/php.ini
regexp='date.timezone ='
line='date.timezone = {{ server.timezone }}'

- name: enabling opcache
lineinfile: dest=/etc/php/5.6/apache2/php.ini
regexp=';?opcache.enable=\d'
line='opcache.enable=1'

- name: enabling modules
lineinfile:
dest: /etc/php/5.6/apache2/php.ini
backrefs: yes
regexp: '{{item.regexp}}'
line: '{{item.line}}'
with_items: '{{php.config}}'
when: php.config is defined


pecl.ymlではPECLで扱っているパッケージのインストールができます。今回は特に使っていませんが。


roles/php/tasks/pecl.yml

- name: Install

apt: pkg="php5-dev" state=present
when: php.pecl_packages is defined

- name: Install Package
shell: echo "\n\n\n\n\n\n\n\n\n" | pecl install {{ item }}
register: pecl_result
changed_when: "'already installed' not in pecl_result.stdout"
failed_when: "pecl_result.stderr or ('ERROR' in pecl_result.stdout)"
with_items: "{{php.pecl_packages}}"
when: php.pecl_packages is defined

- name: Create extension .ini file
template: >
src="extension.tpl"
dest="/etc/php5/mods-available/{{ item }}.ini"
owner="root"
group="root"
mode=0644
with_items: "{{php.pecl_packages}}"
when: php.pecl_packages is defined

- name: Enable extension
shell: php5enmod {{ item }}
with_items: "{{php.pecl_packages}}"
when: php.pecl_packages is defined



おわりに

phansibleがほぼほぼ使えるものを作ってくれるので、少し修正するだけですぐに動かすことができました。今までは環境構築を割と手動でやっていたので、かなり楽になりました。

たぶん最近は仮想環境が主流だと思うのですが、VagrantやDockerと組合せても使えそうなので、積極的に使っていきたいですね!

環境もコードで管理しよう!