Ansible入門ガイド

第1章: Ansibleとは

Ansibleは、Red Hat社が開発・提供している構成管理・自動化ツールです。サーバーやネットワーク機器の設定を自動化し、インフラストラクチャをコードとして管理することができます。

主な特徴

ユースケース

第2章: インストールと設定

インストール方法

各OSごとのインストール方法を説明します:

Red Hat / CentOS:
sudo yum install epel-release
sudo yum install ansible
Ubuntu / Debian:
sudo apt update
sudo apt install software-properties-common
sudo apt-add-repository --yes --update ppa:ansible/ansible
sudo apt install ansible
pip経由(Python環境):
pip install ansible

基本設定

Ansibleの主な設定ファイルは以下の場所にあります:

/etc/ansible/ansible.cfg
[defaults]
inventory = ./inventory
remote_user = ansible
host_key_checking = False
forks = 5
timeout = 30
log_path = /var/log/ansible.log

[privilege_escalation]
become = True
become_method = sudo
become_user = root
become_ask_pass = False

設定項目の説明

第3章: インベントリファイル

インベントリファイルは、Ansibleで管理する対象ホストとそのグループを定義するファイルです。静的なファイルだけでなく、動的なインベントリスクリプトも利用できます。

インベントリの基本構造

inventory/hosts
# 単一ホストの定義
web1.example.com

# IPアドレスでの指定
192.168.1.50
192.168.1.51

# グループ定義
[webservers]
web1.example.com ansible_host=192.168.1.10
web2.example.com ansible_host=192.168.1.11

[dbservers]
db1.example.com ansible_host=192.168.1.20
db2.example.com ansible_host=192.168.1.21

# グループのグループ化
[production:children]
webservers
dbservers

# グループ変数の定義
[webservers:vars]
http_port=80
max_clients=100

# 全体に適用される変数
[all:vars]
ansible_python_interpreter=/usr/bin/python3
ansible_user=deploy

パターンを使用したホスト定義

inventory/numbered-hosts
[webservers]
web[01:50].example.com      # web01.example.com から web50.example.com まで

[dbservers]
db[a:f].example.com         # dba.example.com から dbf.example.com まで

[workers]
worker[01:20:2].example.com # 01から20まで2刻み (01,03,05...19)

高度なインベントリパラメータ

inventory/advanced-hosts
[webservers]
web1.example.com ansible_host=192.168.1.10 ansible_port=2222 ansible_user=deploy
web2.example.com ansible_host=192.168.1.11 ansible_connection=winrm

[dbservers]
db1.example.com ansible_host=192.168.1.20 ansible_ssh_private_key_file=/path/to/key
db2.example.com ansible_host=192.168.1.21 ansible_become=true ansible_become_user=postgres

[monitoring]
monitor.example.com ansible_connection=local

主要なインベントリパラメータの説明

動的インベントリ

クラウド環境やコンテナ環境では、動的にインベントリを生成することができます。

AWS動的インベントリの例

inventory/aws_ec2.yml
plugin: aws_ec2
regions:
  - ap-northeast-1
keyed_groups:
  - key: tags.Environment
    prefix: env
  - key: tags.Role
    prefix: role
  - key: instance_type
    prefix: aws_instance_type

compose:
  ansible_host: public_ip_address

カスタム動的インベントリスクリプトの例

inventory/custom_inventory.py
#!/usr/bin/env python3
import json

def get_inventory():
    return {
        "webservers": {
            "hosts": ["web1.example.com", "web2.example.com"],
            "vars": {
                "http_port": 80
            }
        },
        "dbservers": {
            "hosts": ["db1.example.com"],
            "vars": {
                "db_port": 5432
            }
        },
        "_meta": {
            "hostvars": {
                "web1.example.com": {
                    "ansible_host": "192.168.1.10"
                }
            }
        }
    }

if __name__ == '__main__':
    inventory = get_inventory()
    print(json.dumps(inventory, indent=2))

インベントリの検証とデバッグ

インベントリの設定を確認するための有用なコマンド:

# 全ホストの一覧表示
ansible all --list-hosts

# インベントリ内の特定グループのホスト表示
ansible webservers --list-hosts

# ホスト変数の確認
ansible web1.example.com -m debug -a "var=hostvars[inventory_hostname]"

# グループ構造の確認
ansible-inventory --list
ansible-inventory --graph

第4章: Playbookの基礎

Playbookは、実行したい一連のタスクをYAML形式で記述したものです。

基本的なPlaybook構造

playbooks/web-setup.yml
---
- name: Webサーバーのセットアップ
  hosts: webservers
  become: yes
  vars:
    http_port: 80
    server_name: example.com
  
  tasks:
    - name: nginxのインストール
      apt:
        name: nginx
        state: present
        update_cache: yes
        
    - name: nginxの設定ファイル配置
      template:
        src: templates/nginx.conf.j2
        dest: /etc/nginx/nginx.conf
        owner: root
        group: root
        mode: '0644'
      notify: restart nginx
        
    - name: nginxの起動と自動起動設定
      service:
        name: nginx
        state: started
        enabled: yes
        
  handlers:
    - name: restart nginx
      service:
        name: nginx
        state: restarted
templates/nginx.conf.j2
server {
    listen {{ http_port }};
    server_name {{ server_name }};
    
    location / {
        root /var/www/html;
        index index.html;
    }
}

第5章: モジュールとハンドラーの詳細

主要なモジュール

Ansibleの代表的なモジュールとその使用方法を説明します。

1. コピーモジュール (copy)

playbooks/copy-example.yml
- name: 設定ファイルのコピー
    copy:
      src: files/app.conf          # コピー元ファイル
      dest: /etc/app/app.conf      # コピー先パス
      owner: root                  # 所有者
      group: root                  # グループ
      mode: '0644'                 # パーミッション
      backup: yes                  # バックアップの作成
      force: no                    # 既存ファイルの上書き

2. テンプレートモジュール (template)

playbooks/template-example.yml
- name: Nginxの設定ファイル生成
    template:
      src: templates/nginx.conf.j2  # Jinja2テンプレート
      dest: /etc/nginx/nginx.conf
      validate: 'nginx -t -c %s'    # 構文チェック
      backup: yes
    notify: restart nginx

3. パッケージ管理モジュール (apt/yum)

playbooks/package-example.yml
- name: 複数パッケージのインストール
    apt:
      name: 
        - nginx
        - php-fpm
        - postgresql
      state: present              # present/absent/latest
      update_cache: yes          # apt update相当
      cache_valid_time: 3600     # キャッシュ有効時間(秒)

4. サービス管理モジュール (service/systemd)

playbooks/service-example.yml
- name: サービスの制御
    systemd:
      name: nginx
      state: started             # started/stopped/restarted/reloaded
      enabled: yes              # 自動起動の有効化
      daemon_reload: yes        # systemdの設定再読み込み

5. ファイル操作モジュール (file)

playbooks/file-example.yml
- name: ディレクトリ構造の作成
    file:
      path: /var/www/app/logs
      state: directory          # file/directory/link/absent
      mode: '0755'
      recurse: yes             # 再帰的に権限を設定

- name: シンボリックリンクの作成
    file:
      src: /etc/nginx/sites-available/myapp
      dest: /etc/nginx/sites-enabled/myapp
      state: link

ハンドラーの活用

ハンドラーは、特定のタスクが変更を行った場合にのみ実行される特別なタスクです。

ハンドラーの定義と使用例

playbooks/handlers-example.yml
---
- name: Webサーバーの設定
  hosts: webservers
  become: yes
  
  handlers:
    - name: restart nginx        # ハンドラーの定義
      service:
        name: nginx
        state: restarted
    
    - name: reload nginx         # 設定再読み込み用ハンドラー
      service:
        name: nginx
        state: reloaded
    
    - name: restart php-fpm      # PHP-FPM再起動用ハンドラー
      service:
        name: php-fpm
        state: restarted

  tasks:
    - name: Nginxの設定ファイル配置
      template:
        src: templates/nginx.conf.j2
        dest: /etc/nginx/nginx.conf
      notify: 
        - reload nginx          # 設定変更時にreloadを実行

    - name: PHP-FPMの設定変更
      template:
        src: templates/php-fpm.conf.j2
        dest: /etc/php-fpm.d/www.conf
      notify:
        - restart php-fpm       # PHP設定変更時に再起動を実行
        - reload nginx          # 複数のハンドラーを呼び出し可能

ハンドラーの特徴と注意点

ハンドラーの応用例

playbooks/advanced-handlers.yml
---
- name: アプリケーションのデプロイ
  hosts: application_servers
  become: yes
  
  handlers:
    - name: rebuild application cache
      command: /usr/local/bin/cache-rebuild.sh
      listen: "app cache rebuild"
    
    - name: clear temporary files
      file:
        path: /tmp/app_cache
        state: absent
      listen: "app cache rebuild"
    
    - name: reload application
      service:
        name: myapp
        state: reloaded
      listen: "app restart"

  tasks:
    - name: アプリケーションの設定更新
      template:
        src: app_config.j2
        dest: /etc/myapp/config.yml
      notify: "app cache rebuild"    # リスナー名での呼び出し
    
    - name: アプリケーションのデプロイ
      git:
        repo: https://github.com/example/myapp.git
        dest: /var/www/myapp
      notify: "app restart"

第6章: 変数とファクト

変数の定義方法

Ansibleでは、様々な方法で変数を定義できます:

1. インベントリ変数

inventory/hosts
[webservers:vars]
http_port=80
app_environment=production

[dbservers:vars]
mysql_port=3306
max_connections=100

2. グループ変数

group_vars/all.yml
---
# すべてのホストに適用される変数
timezone: "Asia/Tokyo"
ntp_servers:
  - ntp1.example.com
  - ntp2.example.com

basic_packages:
  - vim
  - curl
  - wget
group_vars/webservers.yml
---
# Webサーバーグループ特有の変数
nginx_worker_processes: auto
nginx_worker_connections: 1024
document_root: /var/www/html
php_version: "8.1"

3. ホスト変数

host_vars/web1.example.com.yml
---
# 特定ホスト専用の変数
server_name: "web1.example.com"
ssl_enabled: true
ssl_certificate: "/etc/ssl/certs/web1.crt"
ssl_certificate_key: "/etc/ssl/private/web1.key"

4. Playbook内での変数定義

playbooks/webapp-deploy.yml
---
- name: Webアプリケーションのデプロイ
  hosts: webservers
  vars:
    app_name: "myapp"
    app_version: "1.2.3"
    deploy_path: "/opt/{{ app_name }}"
    database_config:
      host: "db.example.com"
      port: 5432
      name: "myapp_db"
      user: "myapp_user"
  
  tasks:
    - name: アプリケーションディレクトリの作成
      file:
        path: "{{ deploy_path }}"
        state: directory
        mode: '0755'
        
    - name: 設定ファイルのテンプレート展開
      template:
        src: templates/config.yml.j2
        dest: "{{ deploy_path }}/config.yml"
        vars:
          extra_debug: true  # タスク固有の変数

5. 変数の優先順位

変数の優先順位は以下の順序で高くなります:

  1. インベントリのデフォルト変数
  2. group_vars/all での定義
  3. group_vars/グループ名 での定義
  4. host_vars/ホスト名 での定義
  5. Playbook内での変数定義
  6. ロール内のデフォルト変数
  7. ロール内の変数
  8. タスクレベルの変数
  9. コマンドラインでの指定(--extra-vars)

6. テンプレートでの変数使用

templates/nginx.conf.j2
server {
    listen {{ http_port }};
    server_name {{ server_name }};

    {% if ssl_enabled %}
    listen 443 ssl;
    ssl_certificate {{ ssl_certificate }};
    ssl_certificate_key {{ ssl_certificate_key }};
    {% endif %}

    root {{ document_root }};

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    {% for allow_ip in allowed_ips %}
    allow {{ allow_ip }};
    {% endfor %}
}

ファクトの利用

ファクトは、管理対象ホストから自動的に収集されるシステム情報です。

playbooks/system-info.yml
---
- name: システム情報の収集と表示
  hosts: all
  tasks:
    - name: システム情報の表示
      debug:
        msg: |
          OS: {{ ansible_distribution }} {{ ansible_distribution_version }}
          アーキテクチャ: {{ ansible_architecture }}
          CPUコア数: {{ ansible_processor_cores }}
          総メモリ: {{ ansible_memtotal_mb }}MB
          IPアドレス: {{ ansible_default_ipv4.address }}
          
    - name: カスタムファクトの登録
      set_fact:
        app_full_version: "{{ app_name }}-{{ app_version }}-{{ ansible_date_time.iso8601 }}"
        
    - name: カスタムファクトの表示
      debug:
        var: app_full_version

第7章: ロールの活用

ロールは、Playbookの再利用可能なコンポーネントです。タスク、ハンドラー、変数などを体系的に整理し、再利用可能な形式にまとめたものです。

ロールの基本構造

標準的なロールは以下のようなディレクトリ構造を持ちます:

roles/
  webserver/                  # ロール名
    tasks/
      main.yml               # メインタスクファイル
      install.yml            # インストール関連タスク
      configure.yml          # 設定関連タスク
    handlers/
      main.yml              # ハンドラー定義
    templates/              # テンプレートファイル
      nginx.conf.j2
      vhost.conf.j2
    files/                  # 静的ファイル
      index.html
      robots.txt
    vars/
      main.yml             # ロール変数
    defaults/
      main.yml            # デフォルト変数
    meta/
      main.yml           # メタ情報(依存関係等)

ロールの作成例

1. メタ情報の定義

roles/webserver/meta/main.yml
---
galaxy_info:
  author: Your Name
  description: Nginx Webserver Role
  company: Your Company
  license: MIT
  min_ansible_version: 2.9
  platforms:
    - name: Ubuntu
      versions:
        - focal
        - jammy
    - name: Debian
      versions:
        - bullseye

dependencies:
  - role: common
    vars:
      some_parameter: some_value

2. デフォルト変数の設定

roles/webserver/defaults/main.yml
---
nginx_port: 80
nginx_user: www-data
nginx_worker_processes: auto
nginx_worker_connections: 1024
nginx_keepalive_timeout: 65
nginx_remove_default_vhost: true

# SSL設定
nginx_ssl_enabled: false
nginx_ssl_protocols: "TLSv1.2 TLSv1.3"
nginx_ssl_ciphers: "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256"

# バーチャルホスト設定
nginx_vhosts: []

3. タスクの実装

roles/webserver/tasks/main.yml
---
- name: Include OS-specific variables
  include_vars: "{{ ansible_os_family }}.yml"

- name: Include installation tasks
  include_tasks: install.yml

- name: Include configuration tasks
  include_tasks: configure.yml

- name: Include vhost configuration
  include_tasks: vhosts.yml
roles/webserver/tasks/install.yml
---
- name: Update apt cache
  apt:
    update_cache: yes
    cache_valid_time: 3600
  when: ansible_os_family == 'Debian'

- name: Install nginx package
  package:
    name: nginx
    state: present

- name: Create nginx configuration directories
  file:
    path: "{{ item }}"
    state: directory
    owner: root
    group: root
    mode: '0755'
  with_items:
    - /etc/nginx/conf.d
    - /etc/nginx/sites-available
    - /etc/nginx/sites-enabled

4. ハンドラーの定義

roles/webserver/handlers/main.yml
---
- name: restart nginx
  service:
    name: nginx
    state: restarted

- name: reload nginx
  service:
    name: nginx
    state: reloaded

- name: validate nginx configuration
  command: nginx -t
  changed_when: false
  notify: restart nginx

ロールの使用方法

作成したロールは以下のような方法で使用できます:

playbooks/site.yml
---
- name: Webサーバーのセットアップ
  hosts: webservers
  become: yes
  
  roles:
    # 基本的な使用方法
    - common
    - webserver
    
    # 変数を指定して使用
    - role: webserver
      vars:
        nginx_port: 8080
        nginx_ssl_enabled: true
    
    # 条件付きで使用
    - role: monitoring
      when: enable_monitoring | default(true)
    
    # タグ付きで使用
    - role: webserver
      tags: ['web', 'nginx']

ロール依存関係の管理

ロールの依存関係は meta/main.yml で定義します:

roles/webserver/meta/main.yml
---
dependencies:
  - role: common
    vars:
      some_parameter: some_value
  
  - role: php-fpm
    vars:
      php_version: "8.1"
    when: install_php | default(true)

ロールのベストプラクティス