Playbook@Ansible¶
はじめに¶
本サイトにつきまして、以下をご認識のほど宜しくお願いいたします。
01. playbook ファイル¶
playbook ファイルとは¶
サーバーのセットアップ処理を設定する。
処理を roles ディレクトリに切り分けてもよい。
切り分ける場合、roles ディレクトリを作業ディレクトリとし、相対パスでファイルを指定することになる。
*実装例*
App サーバー、DB サーバー、Web サーバーをセットアップする。
各コンポーネントは roles ディレクトリに切り分けている。
# role ファイル
# App サーバー
- hosts: app
become: yes
force_handlers: "true"
# roles ディレクトリ以下に処理を切り分ける。上から順に roles を実行する。
roles:
- shared
- app
# DB サーバー
- hosts: db
become: yes
force_handlers: "true"
roles:
- shared
- db
# Web サーバー
- hosts: web
become: yes
force_handlers: "true"
roles:
- shared
- web
repository/
├── playbook.yml
├── roles/
│ ├── shared/
│ │ └── tasks/
│ │ └── main.yml
│ │
│ ├── app/
│ │ └── tasks/
│ │ └── main.yml
│ │
│ ├── db/
│ │ └── tasks/
│ │ └── main.yml
│ │
│ └── web/
│ └── tasks/
│ └── main.yml
│
01-02. playbook ファイルの切り分け¶
roles ディレクトリ¶
▼ roles ディレクトリとは¶
特定の機能に関するタスクが設定されたファイルを配置する。
playbook.yml ファイルを切り分けるために使用する。
▼ handlers ディレクトリ¶
task ファイルの後続処理が設定された handler ファイルを配置する。
task ファイルの notify オプションで指定できる。
# handler ファイル
- name: Restart php-fpm
service:
name: php-fpm
state: restarted
# task ファイル
- name: Upload www.conf
ansible.builtin.template:
src: php-fpm/www.conf.j2
dest: /etc/php-fpm.d/www.conf
notify:
# handler の名前を指定する。
- restart_php-fpm
▼ task ディレクトリ¶
playbook ファイルから切り分けたセットアップ処理が設定された task ファイルを配置する。
*実装例*
PHP 製のアプリケーションが稼働する App サーバーをセットアップする。
# task ファイル
- name: Install software-properties-common
ansible.builtin.apt:
name: software-properties-common
state: present
- name: Install packages
ansible.builtin.apt:
pkg:
- php
- php-fpm
- php-pdo
state: present
notify:
- restart_php-fpm
- name: Upload php.ini
ansible.builtin.template:
src: php.ini.j2
dest: /etc/php.ini
notify:
- restart_php-fpm
- name: Upload www.conf
ansible.builtin.template:
src: php-fpm/www.conf.j2
dest: /etc/php-fpm.d/www.conf
notify:
- restart_php-fpm
- name: Setup composer
ansible.builtin.shell: |
# Composer のセットアップ処理
...
▼ template ディレクトリ¶
アップロードファイルの鋳型となる j2 ファイルを配置する。
鋳型に変数を出力できる。
*実装例*
php.ini ファイルの鋳型として、php.ini.j2 ファイルを配置する。
; Start a new pool named 'www'.
; the variable $pool can we used in any directive and will be replaced by the
; pool name ('www' here)
[www]
...
group_vars ディレクトリ¶
▼ group_vars ディレクトリとは¶
複数の管理対象ノードで使用する変数に関するファイルやディレクトリを配置する。
inventories ディレクトリと同じ階層に配置し、加えて inventory ファイルで設定したグループ名やホスト名と同じ名前にする必要がある。
自動的に読み込まれ、playbook ファイルや inventory ファイルで出力できる。
▼ group_var ファイル¶
複数の管理対象ノードで使用する変数を設定する。
# group_var ファイル
env: prd
domain: example.com
ip_addresses:
- 192.168.0.1
- 192.168.0.2
- 192.168.0.3
ports:
- 22/tcp
- 80/tcp
- 443/tcp
ポート番号のリストを playbook ファイルで出力する
---
- name: Add port
firewalld:
port: "{{ item }}"
permanent: yes
state: enabled
zone: public
with_items:
- "{{ ports }}"
- name: Restart firewalld
systemd:
name: firewalld
state: reloaded
host_vars ディレクトリ¶
▼ host_vars ディレクトリとは¶
特定の管理対象ノードで使用する変数に関するファイルを配置する。
▼ host_var ファイル¶
特定の管理対象ノードで使用する変数を設定する。
inventoriesディレクトリ¶
▼ inventories ディレクトリとは¶
管理対象ノードの情報を設定する。
Ansible の実行時に、-i オプションでディレクトリを指定する。
$ ansible-playbook <playbookファイル> -i <inventoriesディレクトリ>
▼ inventory ファイル¶
管理対象ノードを設定する。
複数の拡張子 (ini 形式、yml 形式、json 形式) で定義でき、ansible-inventory コマンドで ini 形式から他の形式に変換できる。
ただし、ini 形式の場合は拡張子をつけないほうがよい。実行環境 (本番/ステージング) 別にファイルを切り分けるとよい。
また、サーバーを冗長化している場合は、これも別々に定義しておく。
プロビジョニングの実行対象はロードバランサーから一時的に切り離すようにすることにより、プロビジョニングに伴ってインシデントが起こっても、ユーザーへの影響を防げる。
*実装例*
もし yml 形式の場合は以下の通りとなる。
# inventory ファイル
# テスト環境
- all:
hosts:
app:
# 管理対象ノードの IP アドレス
ansible_host: 127.0.0.1
# 管理対象ノードにログインするためのユーザー名
ansible_user: vagrant
# 管理対象ノードにログインするためのパスワード
ansible_password: vagrant
web:
ansible_host: 127.0.0.1
ansible_user: vagrant
ansible_password: vagrant
db:
ansible_host: 127.0.0.1
ansible_user: vagrant
ansible_password: vagrant
# inventory ファイル
# 本番環境
- all:
children:
# 冗長化サーバーa
server_a:
hosts:
# App サーバー
app:
# 管理対象ノードの IP アドレス
ansible_host: 192.168.100.101
# 管理対象ノードにログインするためのユーザー名
ansible_user: ubuntu
# 管理対象ノードにログインするためのパスワード
ansible_password: ubuntu
# 管理対象ノードへの SSH 公開鍵認証に使用する秘密鍵
ansible_ssh_private_key_file: /etc/ansible/ssh_keys/prd-foo.pem
# Web サーバー
web:
ansible_host: 192.168.100.10
ansible_user: ubuntu
ansible_password: ubuntu
ansible_ssh_private_key_file: /etc/ansible/ssh_keys/prd-foo.pem
# 冗長化サーバーc
server_c:
hosts:
# App サーバー
app:
ansible_host: 192.168.100.102
ansible_user: ubuntu
ansible_password: ubuntu
ansible_ssh_private_key_file: /etc/ansible/ssh_keys/prd-foo.pem
# Web サーバー
web:
ansible_host: 192.168.100.11
ansible_user: ubuntu
ansible_password: ubuntu
ansible_ssh_private_key_file: /etc/ansible/ssh_keys/prd-foo.pem
*実装例*
もし ini 形式の場合は以下の通りとなる。
# inventoryファイル
# テスト環境
# -------------------
# 冗長化サーバーa
# -------------------
# Appサーバー
[server_a.hosts.app]
# 管理対象ノードのIPアドレス
ansible_host=192.168.100.101
# 管理対象ノードにログインするためのユーザー名
ansible_user=ubuntu
# 管理対象ノードにログインするためのパスワード
ansible_password=ubuntu
# 管理対象ノードへのSSH公開鍵認証に使用する秘密鍵
ansible_ssh_private_key_file=/etc/ansible/ssh_keys/prd-foo.pem
# Webサーバー
[server_a.hosts.web]
ansible_host=192.168.100.10
ansible_user=ubuntu
ansible_password=ubuntu
ansible_ssh_private_key_file=/etc/ansible/ssh_keys/prd-foo.pem
# -------------------
# 冗長化サーバーc
# -------------------
# Appサーバー
[server_c.hosts.app]
ansible_host=192.168.100.102
ansible_user=ubuntu
ansible_password=ubuntu
ansible_ssh_private_key_file=/etc/ansible/ssh_keys/prd-foo.pem
# Webサーバー
[server_c.hosts.web]
ansible_host=192.168.100.11
ansible_user=ubuntu
ansible_password=ubuntu
ansible_ssh_private_key_file=/etc/ansible/ssh_keys/prd-foo.pem
# inventoryファイル
# 本番環境
# -------------------
# 冗長化サーバーa
# -------------------
# Appサーバー
[server_a.hosts.app]
ansible_host=192.168.100.101
ansible_user=ubuntu
ansible_password=ubuntu
ansible_ssh_private_key_file=/etc/ansible/ssh_keys/prd-foo.pem
# Webサーバー
[server_a.hosts.web]
ansible_host=192.168.100.10
ansible_user=ubuntu
ansible_password=ubuntu
ansible_ssh_private_key_file=/etc/ansible/ssh_keys/prd-foo.pem
# -------------------
# 冗長化サーバーc
# -------------------
# Appサーバー
[server_c.hosts.app]
ansible_host=192.168.100.102
ansible_user=ubuntu
ansible_password=ubuntu
ansible_ssh_private_key_file=/etc/ansible/ssh_keys/prd-foo.pem
# Webサーバー
[server_c.hosts.web]
ansible_host=192.168.100.11
ansible_user=ubuntu
ansible_password=ubuntu
ansible_ssh_private_key_file=/etc/ansible/ssh_keys/prd-foo.pem
02. /roles/handlers セクション¶
handlers セクションとは¶
task セクションの後に実行するセットアップ処理を設定する。
02-02. /roles/targets セクション¶
targets セクションとは¶
プレイの実行先のノードを設定する。
必須である。
name¶
▼ name とは¶
プレイの名前を設定する。
- name: Setup nginx
hosts¶
▼ hosts とは¶
プレイの実行先のノードを設定する。
- hosts: all
become¶
▼ become とは¶
プレイを root 権限 (sudo 権限) で実行するか否かを設定する。
root 以外であれば、become_user キーを設定する。
- become: yes
become_user: foo-user
gather_facts¶
▼ gather_facts とは¶
ファクト変数を収集するか否かを設定する。
- gather_facts: no
02-03. /roles/tasks セクション¶
tasks セクションとは¶
管理対象ノードで実行するセットアップ処理を手続き的に設定する。
必須である。
ansible.builtin.apt¶
▼ ansible.builtin.apt とは¶
管理対象ノードで、パッケージを apt リポジトリからインストールする。
任意のバージョンのパッケージをインストールする場合は、name キーにそれを指定し、state キーの値は present とする。
*実装例*
# nginx をインストールします。
- name: Install Nginx
ansible.builtin.apt:
name: nginx=1.0.0
state: present
ansible.builtin.dnf¶
▼ ansible.builtin.dnf とは¶
管理対象ノードで、パッケージを dnf リポジトリからインストールする。
*実装例*
# cloudwatch エージェントをインストールする。
- name: install amazon-cloudwatch-agent
ansible.builtin.dnf:
name: amazon-cloudwatch-agent
state: present
# カスタムメトリクスの元になるデータポイントを収集するために、collectd をインストールする。
- name: install collectd
ansible.builtin.dnf:
name: collectd
state: present
# 設定ファイルを配置する。
- name: copy amazon-cloudwatch-agent.json
ansible.builtin.copy:
src: amazon-cloudwatch-agent.json
dest: /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json
owner: root
group: root
mode: 0644
# cloudwatch エージェントを起動する。
- name: fetch-config config.json
ansible.builtin.shell: |
/opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl \
-a fetch-config \
-m ec2 \
-c file:/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json \
-s
# cloudwatch エージェントを systemd で管理する。
- name: enable cloudwatch-agent
ansible.builtin.systemd:
name: amazon-cloudwatch-agent
enabled: yes
daemon_reload: yes
▼ バージョン指定¶
任意のバージョンのパッケージをインストールする場合は、name キーにそれを指定し、state キーの値は present とする。
*実装例*
# nginx をインストールします。
- name: Install Nginx
ansible.builtin.yum:
# バージョンを指定する
name: nginx=1.0.0
state: present
# epel リポジトリをインストールします。
- name: Install epel-release
ansible.builtin.yum:
name: https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm
state: present
ansible.builtin.lineinfile¶
▼ ansible.builtin.lineinfile とは¶
管理対象ノードにあるファイルを行単位で編集する。
*実装例*
SELinux を無効化する。
*実装例*
# SELinux を無効化します。
- name: Disable SELinux
ansible.builtin.lineinfile:
path: /etc/selinux/config
regexp: "^SELINUX="
line: "SELINUX=disabled"
*実装例*
# unlimit の設定を追加します
- name: Add ulimit setting
lineinfile:
path: /etc/systemd/system.conf.d/50-limits.conf
regexp: "^DefaultLimitNOFILE=.*$"
line: "DefaultLimitNOFILE=65536:65536"
*実装例*
# rsyslog_conf_file に stat を格納する
- name: Check if /etc/rsyslog.conf exists
ansible.builtin.stat:
path: /etc/rsyslog.conf
register: rsyslog_conf_file
- name: Create rsyslog.conf
ansible.builtin.lineinfile:
line: "$FileCreateMode 0640"
regexp: "^$FileCreateMode"
path: /etc/rsyslog.conf
# もし rsyslog_conf_file 内にデータがあれば、実行する
when: rsyslog_conf_file.stat.exists
ansible.builtin.copy¶
▼ ansible.builtin.copy とは¶
管理対象ノードのディレクトリにファイルをコピーする。
*実装例*
# 設定ファイルを配置します。
- name: Copy foo.json
ansible.builtin.copy:
src: foo.json
dest: /etc/foo.json
owner: root
group: root
mode: 0644
ansible.builtin.file¶
▼ ansible.builtin.file とは¶
管理対象ノードでファイルを操作する。
*実装例*
管理対象ノードで chown コマンドを実行することで、ファイルの所有権を設定する。
- name: Update foo-binary permission
ansible.builtin.file:
path: /usr/local/bin/foo-binary
owner: root
group: root
ansible.builtin.get_url¶
▼ ansible.builtin.get_url とは¶
管理対象ノードで curl コマンドを実行する。
- name: Download tool
ansible.builtin.get_url:
url: https://github.com/hiroki-hasegawa/foo-tool.tar.gz
dest: .
ansible.builtin.service¶
▼ ansible.builtin.service とは¶
管理対象ノードで service コマンドの実行を設定する。
*実装例*
# service コマンドを使用して、nginx を起動します。
- name: Start nginx service
ansible.builtin.service:
name: Start nginx
state: started
enabled: "yes"
ansible.builtin.shell¶
▼ ansible.builtin.shell とは¶
管理対象ノードでシェルを実行する。複数行に渡る場合は、『|』を使用する。
*実装例*
- name: Echo foo
ansible.builtin.shell: |
echo foo
*実装例*
- name: fetch-config amazon-cloudwatch-agent.json
ansible.builtin.shell: |
/opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl \
-a fetch-config \
-m ec2 \
-c file:/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json \
-s
ansible.builtin.systemd¶
▼ ansible.builtin.systemd とは¶
管理対象ノードで systemctl コマンドの実行を設定する。
*実装例*
# systemd で nginx のプロセスを管理します。
- name: Start nginx systemd
ansible.builtin.systemd:
name: Start nginx
state: started
enabled: yes
daemon_reload: yes
*実装例*
# systemd で cloudwatch エージェントのプロセスを管理します。
- name: Start cloudwatch-agent systemd
ansible.builtin.systemd:
name: amazon-cloudwatch-agent
state: started
enabled: yes
daemon_reload: yes
▼ state¶
ユニットの最終的な状態を設定する。
| 設定値 | 説明 |
|---|---|
reloaded |
最終的な状態として deamon_reload するように、ユニットを再読み込みする。 |
restarted |
最終的な状態として再起動するように、ユニットを再起動する。 |
started |
最終的な状態として停止しているように、ユニットを起動する。 |
stopped |
最終的な状態として停止しているさうに、ユニットを停止する。 |
ansible.builtin.template¶
▼ ansible.builtin.template とは¶
テンプレート (.j2 ファイル) から作成したファイルを管理対象ノードのディレクトリに配置する。
*実装例*
- name: Upload foo.conf
ansible.builtin.template:
src: foo.conf.j2
dest: /etc/foo/foo.conf
ansible.builtin.unarchive¶
▼ ansible.builtin.unarchive とは¶
コントロールノードまたは管理対象ノードで tar コマンドを実行することで、圧縮ファイルを解凍する。
*実装例*
- name: Unarchive file
ansible.builtin.unarchive:
src: /tmp/foo-tool.tar.gz
dest: /usr/local/bin
remote_src: yes # 管理対象ノード上の圧縮ファイルを指定する場合は yes とする。
ansible.builtin.user¶
▼ ansible.builtin.user とは¶
シェルのユーザーを操作する。
*実装例*
ユーザーを作成する。
無効なシェルを設定し、ログインできないようにしておく。
- name: add user
ansible.builtin.user:
name: foo
shell: /bin/false
ansible.builtin.yum¶
▼ ansible.builtin.yum とは¶
管理対象ノードで、パッケージを yum リポジトリからインストールする。
代わりに ansible.builtin.dnf モジュールを使うとよい。
ansible_env¶
▼ ansible_env とは¶
管理対象ノードに設定された環境変数を出力する。
gather_facts オプションを有効化する必要がある。
*実装例*
管理対象ノードの環境変数の FOO を出力する。
gather_facts オプションを有効化しておく。
- gather_facts: yes
- vars:
FOO: ansible_env.FOO
environment¶
▼ environment とは¶
task 内で出力できる環境変数を設定する。
*実装例*
- name: Echo foo
ansible.builtin.shell: |
echo foo
echo "${FOO}"
environment:
FOO: FOO
02-04. /roles/vars セクション¶
vars セクションとは¶
プレイで使用する設定値を変数として設定する。
設定した変数は、ansible.builtin.template オプションを使用して j2 ファイルに出力できる。
*実装例*
- name: Upload foo.conf
ansible.builtin.template:
src: foo.conf.j2
dest: /etc/foo/foo.conf
vars:
foo: FOO
bar: BAR
# foo.conf.j2 ファイル
{{foo}}
02-05. プラグイン¶
lookup¶
▼ env¶
コントロールノードに設定された環境変数を出力する。
*実装例*
コントロールノードの環境変数の FOO を出力する。
- name: Upload foo.conf
ansible.builtin.template:
src: foo.conf.j2
dest: /etc/foo/foo.conf
vars:
foo: 'lookup("env", "FOO")'
03. AWS¶
amazon.aws.ec2_ami¶
Amazon EC2 を作成する。
これは Terraform でも代替できる。
- name: Basic AMI Creation
amazon.aws.ec2_ami:
instance_id: i-xxxxxx
wait: true
name: newtest
architecture: x86_64
virtualization_type: hvm
root_device_name: /dev/xvda
device_mapping:
- device_name: /dev/sda1
size: XXX
delete_on_termination: true
volume_type: gp2
- device_name: /dev/sdb
size: YYY
delete_on_termination: false
volume_type: gp2
tags:
Name: newtest
Service: TestService