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権限で実行するか否かを設定する。
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
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リポジトリからインストールする。
任意のバージョンのパッケージをインストールする場合は、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_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¶
AWS 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