Ansible入門|YAMLで始めるインフラ自動化

インフラ自動化の第一歩を踏み出すなら、Ansibleを選ぶべきです。YAML形式のシンプルな構文で、サーバーの設定管理からデプロイメントまで、一貫した自動化を実現できます。本記事では、Ansibleの基本概念から具体的な使い方まで、実務で即戦力となる知識を網羅的に解説します。初心者でも理解できるように、具体的なコマンドや設定例を交えながら丁寧に説明しますので、ぜひ最後までお読みください。


目次


Ansibleの概要と特徴

Ansibleは、Red Hat社によって開発されたオープンソースの構成管理ツールです。2015年にRed Hatに買収されて以来、企業のITインフラ自動化において広く採用されています。Ansibleの最大の特徴は、エージェントレスで動作する点です。これは、管理対象の各サーバーに特別なソフトウェアをインストールする必要がないことを意味します。SSHを通じてリモートでコマンドを実行するだけで、サーバーの設定管理が可能です。

Ansibleの主な特徴は以下の通りです:

  • エージェントレス:管理対象サーバーにエージェントをインストールする必要がない
  • シンプルな構文:YAML形式で記述できるため、学習コストが低い
  • 冪等性(Idempotency):同じ設定を何度実行しても、常に同じ結果を得られる
  • 豊富なモジュール:2,000以上の公式モジュールが提供されている
  • 拡張性:独自のモジュールやプラグインを開発できる

Ansibleが他の構成管理ツール(Chef、Puppet、SaltStackなど)と比較して優れている点は、そのシンプルさと学習の容易さです。特に、YAML形式のプレイブックは、人間が読みやすく、書きやすい構造になっています。また、冪等性を保証する設計により、運用時のミスを最小限に抑えることができます。

Ansibleの公式サイトによると、2023年現在でAnsibleは世界中の10,000社以上で利用されており、その成長率は他の構成管理ツールを上回っています(出典: Ansible公式サイト)。


Ansibleの環境構築手順

Ansibleを利用するためには、まず環境を構築する必要があります。AnsibleはPythonで書かれているため、Pythonがインストールされている環境であれば動作します。ここでは、主要なOS(Linux、macOS、Windows)におけるAnsibleのインストール方法と基本設定について解説します。

Ansibleのインストール方法

Ansibleのインストール方法は、使用するOSによって異なります。以下に、主要なOSごとのインストール手順を示します。

Linux(Ubuntu/Debian)

UbuntuやDebian系のLinuxでは、aptパッケージマネージャーを使用してAnsibleをインストールできます。

# 更新
sudo apt update

必要なパッケージのインストール

sudo apt install -y software-properties-common

AnsibleのPPAリポジトリを追加

sudo add-apt-repository --yes --update ppa:ansible/ansible

Ansibleのインストール

sudo apt install -y ansible

インストールが完了したら、バージョンを確認します。

ansible --version

Linux(CentOS/RHEL)

CentOSやRHEL系のLinuxでは、yumパッケージマネージャーを使用してAnsibleをインストールできます。

# EPELリポジトリの有効化
sudo yum install -y epel-release

Ansibleのインストール

sudo yum install -y ansible

macOS

macOSでは、Homebrewを使用してAnsibleをインストールできます。

# Homebrewの更新
brew update

Ansibleのインストール

brew install ansible

Windows

Windowsでは、公式のAnsibleはサポートされていませんが、Windows Subsystem for Linux(WSL)を使用してLinux環境を構築し、そこでAnsibleを実行することができます。以下の手順でWSLを設定します。

  1. Windows PowerShellを開き、以下のコマンドを実行してWSLを有効化します。
  2. wsl --install
    
  3. UbuntuなどのLinuxディストリビューションをインストールします。
  4. WSL内でLinuxのターミナルを開き、上記のLinux(Ubuntu/Debian)の手順に従ってAnsibleをインストールします。

設定ファイル(ansible.cfg)の基本設定

Ansibleの動作は、設定ファイル(ansible.cfg)によって制御されます。デフォルトでは、Ansibleはカレントディレクトリやホームディレクトリ内のansible.cfgファイルを探します。設定ファイルを作成することで、Ansibleの動作をカスタマイズできます。

以下は、基本的なansible.cfgの例です。

[defaults]
inventory = ./inventory
remote_user = ansible
private_key_file = ~/.ssh/id_rsa
host_key_checking = False
retry_files_enabled = False

主な設定項目の説明:

  • inventory:インベントリファイルのパスを指定します。デフォルトは./inventoryです。
  • remote_user:リモートサーバーに接続する際のユーザー名を指定します。
  • private_key_file:SSH接続に使用する秘密鍵ファイルのパスを指定します。
  • host_key_checking:SSH接続時にホストキーの検証を行うかどうかを指定します。Falseに設定すると、初回接続時のホストキー確認がスキップされます。
  • retry_files_enabled:失敗したタスクの再試行ファイルを作成するかどうかを指定します。Falseに設定すると、再試行ファイルが作成されません。

設定ファイルを作成したら、以下のコマンドでAnsibleの動作を確認します。

ansible --version

Ansibleの基本概念と用語

Ansibleを効果的に活用するためには、その基本概念と用語を理解することが重要です。ここでは、Ansibleの主要な概念である「インベントリ」「プレイブック」「モジュール」について詳しく解説します。

インベントリファイルの作成

インベントリファイルは、Ansibleが管理するサーバー(ホスト)の情報を定義するファイルです。通常、YAML形式またはINI形式で記述されます。インベントリファイルを使用することで、複数のサーバーをグループ化したり、変数を定義したりすることができます。

以下は、INI形式のインベントリファイルの例です。

[webservers]
web1.example.com
web2.example.com

[dbservers]
db1.example.com
db2.example.com

[all:vars]
ansible_user=ansible
ansible_ssh_private_key_file=~/.ssh/id_rsa

この例では、2つのグループ(webserversとdbservers)を定義しています。また、all:varsセクションで、全てのホストに共通の変数を定義しています。

YAML形式のインベントリファイルも使用できます。以下は、YAML形式の例です。

all:
  hosts:
    web1.example.com:
      ansible_user: ansible
      ansible_ssh_private_key_file: ~/.ssh/id_rsa
    web2.example.com:
      ansible_user: ansible
  children:
    webservers:
      hosts:
        web1.example.com:
        web2.example.com:
    dbservers:
      hosts:
        db1.example.com:
        db2.example.com:

インベントリファイルを作成したら、以下のコマンドでホストの接続をテストします。

ansible all -m ping

このコマンドは、全てのホストに対してpingモジュールを実行し、接続を確認します。接続が成功すると、以下のような出力が得られます。

web1.example.com | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
web2.example.com | SUCCESS => {
    "changed": false,
    "ping": "pong"
}

プレイブックの基本構造

プレイブックは、Ansibleのタスクを定義するYAMLファイルです。プレイブックを実行することで、複数のタスクを順番に実行し、サーバーの設定を自動化できます。プレイブックは、以下のような基本的な構造で構成されます。

---
- name: タスクの説明
  hosts: 管理対象のホストグループ
  become: yes  # root権限で実行する場合
  tasks:
    - name: タスク1の説明
      module名:
        パラメータ1: 値1
        パラメータ2: 値2
    - name: タスク2の説明
      module名:
        パラメータ1: 値1

以下は、具体的なプレイブックの例です。このプレイブックは、Apache HTTP Serverをインストールし、起動するタスクを定義しています。

---
- name: Apache HTTP Serverのインストールと起動
  hosts: webservers
  become: yes
  tasks:
    - name: Apache HTTP Serverのインストール
      apt:
        name: apache2
        state: present
      when: ansible_os_family == 'Debian'

    - name: Apache HTTP Serverのインストール(RHEL系)
      yum:
        name: httpd
        state: present
      when: ansible_os_family == 'RedHat'

    - name: Apache HTTP Serverの起動
      service:
        name: apache2
        state: started
        enabled: yes
      when: ansible_os_family == 'Debian'

    - name: Apache HTTP Serverの起動(RHEL系)
      service:
        name: httpd
        state: started
        enabled: yes
      when: ansible_os_family == 'RedHat'

プレイブックを実行するには、以下のコマンドを使用します。

ansible-playbook playbook.yml

主要モジュールの使い方

Ansibleには、2,000以上の公式モジュールが提供されています。モジュールは、特定のタスクを実行するための機能を提供します。ここでは、代表的なモジュールの使い方について解説します。

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

aptモジュールとyumモジュールは、それぞれDebian系およびRHEL系のLinuxでパッケージを管理するためのモジュールです。

# Debian系(Ubuntu/Debian)でのパッケージインストール
- name: nginxのインストール
  apt:
    name: nginx
    state: present
    update_cache: yes

RHEL系(CentOS/RHEL)でのパッケージインストール

- name: nginxのインストール yum: name: nginx state: present

copyモジュール(ファイルのコピー)

copyモジュールは、ローカルのファイルをリモートサーバーにコピーするためのモジュールです。

- name: 設定ファイルをコピー
  copy:
    src: /path/to/local/file.conf
    dest: /etc/nginx/conf.d/file.conf
    owner: root
    group: root
    mode: '0644'

templateモジュール(テンプレートファイルの展開)

templateモジュールは、Jinja2テンプレートを使用して動的な設定ファイルを展開するためのモジュールです。

- name: nginx設定ファイルを展開
  template:
    src: templates/nginx.conf.j2
    dest: /etc/nginx/nginx.conf
    owner: root
    group: root
    mode: '0644'

serviceモジュール(サービス管理)

serviceモジュールは、サービスの起動、停止、再起動を行うためのモジュールです。

- name: nginxサービスを起動
  service:
    name: nginx
    state: started
    enabled: yes

command/shellモジュール(コマンド実行)

commandモジュールとshellモジュールは、任意のコマンドを実行するためのモジュールです。commandモジュールは単純なコマンド実行に使用され、shellモジュールはシェルの機能(パイプ、リダイレクトなど)を使用するコマンド実行に使用されます。

- name: シンプルなコマンド実行
  command: /usr/bin/ls /tmp

- name: シェル機能を使用したコマンド実行
  shell: cat /tmp/file.txt | grep "pattern"

実践的なAnsible活用方法

Ansibleの基本的な使い方を理解したら、次は実践的な活用方法について学びましょう。ここでは、具体的なユースケースとして、パッケージ管理、ユーザー管理、サービス管理の自動化について解説します。

パッケージ管理の自動化

パッケージ管理は、サーバーの設定管理において非常に重要なタスクです。Ansibleを使用することで、複数のサーバーに対して一括でパッケージのインストール、更新、アンインストールを行うことができます。

以下は、複数のパッケージをインストールするプレイブックの例です。

---
- name: 複数のパッケージをインストール
  hosts: all
  become: yes
  tasks:
    - name: 必要なパッケージをインストール
      apt:
        name:
          - nginx
          - mysql-server
          - php
          - php-mysql
        state: present
        update_cache: yes
      when: ansible_os_family == 'Debian'

    - name: 必要なパッケージをインストール(RHEL系)
      yum:
        name:
          - nginx
          - mysql-server
          - php
          - php-mysql
        state: present
      when: ansible_os_family == 'RedHat'

このプレイブックを実行すると、全ての管理対象サーバーに対して、指定したパッケージがインストールされます。また、when条件を使用することで、OSの種類に応じて異なるパッケージ管理コマンドを実行しています。

ユーザー管理の自動化

ユーザー管理も、Ansibleを使用して自動化することができます。例えば、新しいユーザーの作成、既存ユーザーの削除、パスワードの変更などを一括で行うことができます。

以下は、新しいユーザーを作成し、SSHキーを設定するプレイブックの例です。

---
- name: ユーザーの作成とSSHキーの設定
  hosts: all
  become: yes
  vars:
    new_user: deploy
    ssh_public_key: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQ..."

  tasks:
    - name: ユーザーを作成
      user:
        name: "{{ new_user }}"
        groups: sudo
        shell: /bin/bash
        password: "{{ 'password' | password_hash('sha512') }}"
        state: present

    - name: SSHディレクトリを作成
      file:
        path: "/home/{{ new_user }}/.ssh"
        state: directory
        owner: "{{ new_user }}"
        group: "{{ new_user }}"
        mode: '0700'

    - name: SSH公開鍵を配置
      copy:
        content: "{{ ssh_public_key }}"
        dest: "/home/{{ new_user }}/.ssh/authorized_keys"
        owner: "{{ new_user }}"
        group: "{{ new_user }}"
        mode: '0600'

このプレイブックを実行すると、全ての管理対象サーバーに対して、指定したユーザーが作成され、SSHキーが設定されます。varsセクションで定義された変数を使用することで、柔軟な設定が可能です。

サービス管理の自動化

サービス管理も、Ansibleを使用して自動化することができます。例えば、サービスの起動、停止、再起動、有効化/無効化などを一括で行うことができます。

以下は、Nginxサービスを起動し、有効化するプレイブックの例です。

---
- name: Nginxサービスの管理
  hosts: webservers
  become: yes
  tasks:
    - name: Nginxサービスを起動
      service:
        name: nginx
        state: started
        enabled: yes

このプレイブックを実行すると、webserversグループに属する全てのサーバーに対して、Nginxサービスが起動し、システム起動時に自動的に起動するように設定されます。

また、サービスの再起動や停止も同様に行うことができます。

---
- name: Nginxサービスの再起動
  hosts: webservers
  become: yes
  tasks:
    - name: Nginxサービスを再起動
      service:
        name: nginx
        state: restarted

応用的なAnsible技術

基本的なAnsibleの使い方をマスターしたら、次は応用的な技術について学びましょう。ここでは、ロールを使った再利用可能な構成管理、Jinja2テンプレートを活用した動的設定、Ansible Vaultを使った機密情報の暗号化について解説します。

ロールを使った再利用可能な構成管理

ロールは、Ansibleの構成管理を再利用可能な単位に分割するための仕組みです。ロールを使用することで、同じ設定を複数のプロジェクトで共有したり、プロジェクト間で設定を再利用したりすることができます。

ロールの基本的な構造は以下の通りです。

roles/
  └── role_name/
      ├── defaults/
      │   └── main.yml
      ├── tasks/
      │   └── main.yml
      ├── handlers/
      │   └── main.yml
      ├── templates/
      │   └── template.j2
      ├── files/
      │   └── file.conf
      └── vars/
          └── main.yml

以下は、Nginxをインストールし、設定するロールの例です。

roles/
  └── nginx/
      ├── defaults/
      │   └── main.yml
      ├── tasks/
      │   └── main.yml
      ├── handlers/
      │   └── main.yml
      ├── templates/
      │   └── nginx.conf.j2
      └── vars/
          └── main.yml

各ディレクトリの役割は以下の通りです。

  • defaults/main.yml:ロールのデフォルト変数を定義します。
  • tasks/main.yml:ロールのタスクを定義します。
  • handlers/main.yml:ロールのハンドラーを定義します。
  • templates/:Jinja2テンプレートファイルを格納します。
  • files/:静的なファイルを格納します。
  • vars/main.yml:ロールの変数を定義します。

以下は、tasks/main.ymlの例です。

---
- name: Nginxをインストール
  apt:
    name: nginx
    state: present
    update_cache: yes
  when: ansible_os_family == 'Debian'

- name: Nginxをインストール(RHEL系)
  yum:
    name: nginx
    state: present
  when: ansible_os_family == 'RedHat'

- name: Nginx設定ファイルを展開
  template:
    src: nginx.conf.j2
    dest: /etc/nginx/nginx.conf
    owner: root
    group: root
    mode: '0644'
  notify: Nginxを再起動

- name: Nginxサービスを起動
  service:
    name: nginx
    state: started
    enabled: yes

ロールを使用するには、プレイブックからロールを呼び出します。以下は、ロールを使用したプレイブックの例です。

---
- name: Nginxを設定
  hosts: webservers
  become: yes
  roles:
    - nginx

Jinja2テンプレートを活用した動的設定

Jinja2は、Pythonで動作するテンプレートエンジンです。Ansibleでは、Jinja2テンプレートを使用して動的な設定ファイルを生成することができます。これにより、環境ごとに異なる設定を柔軟に管理することができます。

以下は、Nginxの設定ファイル(nginx.conf.j2)の例です。

user {{ nginx_user }};
worker_processes {{ ansible_processor_vcpus }};

error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;

events {
    worker_connections {{ nginx_worker_connections }};
}

http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    sendfile on;
    keepalive_timeout 65;

    server {
        listen {{ nginx_port }};
        server_name {{ nginx_server_name }};

        location / {
            root /var/www/html;
            index index.html index.htm;
        }
    }
}

このテンプレートでは、変数を使用して動的に設定値を埋め込んでいます。テンプレート内で使用される変数は、プレイブックやロールのvarsセクション、インベントリファイルなどで定義されます。

以下は、テンプレートを使用するプレイブックの例です。

---
- name: Nginx設定ファイルを展開
  hosts: webservers
  become: yes
  vars:
    nginx_user: www-data
    nginx_worker_connections: 1024
    nginx_port: 80
    nginx_server_name: example.com

  tasks:
    - name: Nginx設定ファイルを展開
      template:
        src: templates/nginx.conf.j2
        dest: /etc/nginx/nginx.conf
        owner: root
        group: root
        mode: '0644'
      notify: Nginxを再起動

Ansible Vaultを使った機密情報の暗号化

Ansible Vaultは、Ansibleで扱う機密情報(パスワード、APIキー、証明書など)を暗号化するためのツールです。Ansible Vaultを使用することで、機密情報を安全に管理し、バージョン管理システム(Gitなど)で共有することができます。

Ansible Vaultを使用するには、まず暗号化されたファイルを作成します。以下のコマンドで、新しい暗号化ファイルを作成します。

ansible-vault create secrets.yml

このコマンドを実行すると、エディタが開き、暗号化されたファイルの編集が行われます。ファイル内には、以下のようなYAML形式のデータを記述します。

db_password: "supersecretpassword"
api_key: "abc123xyz456"

暗号化されたファイルを編集するには、以下のコマンドを使用します。

ansible-vault edit secrets.yml

暗号化されたファイルを使用するには、プレイブック内でvars_filesディレクティブを使用します。以下は、暗号化されたファイルを使用するプレイブックの例です。

---
- name: 機密情報を使用した設定
  hosts: dbservers
  become: yes
  vars_files:
    - secrets.yml

  tasks:
    - name: MySQLをインストール
      apt:
        name: mysql-server
        state: present
        update_cache: yes

    - name: MySQLのrootパスワードを設定
      command: mysqladmin -u root password "{{ db_password }}"

Ansible Vaultを使用する際の注意点として、暗号化されたファイルを実行する際には、–ask-vault-passオプションを使用してパスワードを入力する必要があります。また、CI/CDパイプラインなどで自動化する場合は、環境変数や外部の秘密管理ツール(HashiCorp Vaultなど)と連携することを検討してください。

ansible-playbook playbook.yml --ask-vault-pass

トラブルシューティングとベストプラクティス

Ansibleを使用する際には、さまざまなトラブルに遭遇することがあります。ここでは、一般的なトラブルとその解決方法、およびAnsibleを効果的に活用するためのベストプラクティスについて解説します。

一般的なトラブルと解決方法

Ansibleを使用する際に遭遇する可能性のある一般的なトラブルとその解決方法を以下に示します。

トラブル原因解決方法
SSH接続エラーSSH鍵の設定ミス、ホストキーの不一致、ファイアウォールの制限SSH接続をテストし、必要に応じて鍵を再設定する。host_key_checkingをFalseに設定する。
モジュールが見つからないAnsibleのバージョンが古い、モジュールがインストールされていないAnsibleを最新バージョンにアップデートする。必要なモジュールをpipでインストールする。
タスクが失敗するタスクの条件が正しくない、権限が不足しているタスクの条件を見直す。become: yesを使用してroot権限で実行する。
変数が正しく展開されない変数名のタイプミス、変数のスコープが正しくない変数名を確認する。varsセクションやインベントリファイルで変数を正しく定義する。
プレイブックの実行が遅い同時実行数が多すぎる、SSH接続のタイムアウトforksパラメータを調整する。SSH接続のタイムアウトを延長する。

ベストプラクティス

Ansibleを効果的に活用するためのベストプラクティスを以下に示します。

  • プレイブックのモジュール化:ロールを使用して、再利用可能な構成管理を行う。
  • 変数の管理:vars_filesやgroup_vars、host_varsを使用して、変数を適切に管理する。
  • 冪等性の確保:全てのタスクが冪等性を保持するように設計する。
  • エラーハンドリング
    【編集・制作ポリシー】
    本記事はRoute Bloom編集部が各ベンダー公式ドキュメント・エンジニア監修をもとに作成しています。インフラ・クラウド構築は環境により異なります。本番環境への適用前に必ずテストを実施してください。情報の正確性には万全を期していますが、最新情報は各公式ドキュメントをご確認ください。
    ABOUT ME
    たから
    サラリーマンをしながら開業して経営やってます。 今年、本業で独立・別事業を起業予定です。 ◆経験:IT講師/インフラエンジニア/PM/マネジメント/採用/運用・保守・構築・設計 ◆取得資格:CCNA/CCNP/LPIC-1/AZ-900/FE/サーティファイC言語 ◆サイドビジネス:アパレル事業/複数のWEBメディアを運営