キーワードで検索

今日を知り、明日を変えるシステム運用メディア

Ansibleの変数の使い方とテンプレート活用を徹底解説

Ansibleの変数の使い方とテンプレート活用を徹底解説 | 変数の優先順位とスコープを理解して効率化を実現

Red Hatが開発したオープンソースのIT自動化ツール「Ansible(アンシブル)」は、インフラ構築、構成管理、アプリケーションのデプロイ、オーケストレーションなど、様々なITプロセスを自動化するために使用されます。

そんなAnsibleを使いこなす上で「変数」の理解は欠かせません。変数を適切に活用すれば、Playbookの柔軟性と再利用性が向上し、効率的な管理が実現します。

本記事では、変数の定義方法やスコープ、優先順位を解説するとともに、動的変数やテンプレート活用、環境別管理の方法について詳しく解説します。

variable costs

Ansibleにおける変数とは?

Ansibleにおいて「変数」は、設定値やパラメータを動的に扱うための仕組みです。変数を使用することで、同じPlaybookやタスクを異なる環境や条件に適応させることができ、コードの再利用性や効率性を大幅に向上させます。

たとえば、サーバー名やIPアドレス、ポート番号など、環境ごとに異なる値を動的に切り替えることが可能です。

Playbook内でvars:を使用して変数を定義する方法


– name: Deploy Application
  hosts: all
  vars:
    server_name: “app-server”
    app_version: “1.0.0”
  tasks:
    – name: Print server name and version
      debug:
        msg: “Deploying on {{ server_name }} with version {{ app_version }}”

インベントリファイルでの定義

インベントリファイルを使うことで、各ホストやグループごとに特定の変数を割り当てることができます。この方法は、複数のホストやグループを対象にPlaybookを適用する際に非常に有用です。


[web_servers]
web1 ansible_host=192.168.1.101 app_env=production
web2 ansible_host=192.168.1.102 app_env=staging

[db_servers]
db1 ansible_host=192.168.1.201 db_user=admin db_password=secure_password

外部ファイルでの定義

変数を外部のYAMLファイルに定義し、Playbook内で読み込む方法です。この方法は、環境別の設定や複雑な変数構造を扱う場合に適しています。

外部ファイル(vars/main.yml)の例


app_name: “my_application”
app_port: 8080

デフォルト変数の定義

Ansible Rolesを使用する場合、defaults/main.ymlファイルにデフォルトの変数を定義できます。この方法は、Roles内で変数を柔軟に管理したい場合に便利です。

defaults/main.yml


# デフォルトのアプリケーション設定
app_name: “default_app”
app_port: 8080
app_env: “development”

# デフォルトのデータベース設定
db_host: “localhost”
db_name: “default_db”
db_user: “root”
db_password: “password”

defaults/main.ymlに定義した変数は、そのRoleを使用するPlaybook内で自動的に読み込まれます。

変数のスコープ

Ansibleにおける変数は、適用範囲(スコープ)によって以下の3つに分類されます。スコープを理解することで、どの変数がどの範囲に影響を与えるのかを把握し、効率的にPlaybookや構成を管理できます。

グローバル変数

グローバル変数は、Playbook全体にわたって使用可能な変数です。すべてのタスクやロールに適用されるため、汎用的な設定値を指定するのに適しています。global_varというグローバル変数を定義し、実際に使用する時のコードを解説します。


– name: Example Playbook with Global Variables
  hosts: all
  vars:
    global_var: “This is a global variable”
  tasks:
    – name: Print global variable
      debug:
        msg: “Global variable value: {{ global_var }}”
  • どのホストやタスクからでもアクセス可能
  • varsセクションに定義されることが一般的
  • 簡易的な設定値やデフォルト値に使用されます

ホスト変数

Ansibleでは、管理対象のサーバーやPCのことを「ホスト」と呼びます。ホスト変数は、特定のホストに対して適用される変数です。こちらを用いることで、ホストごとに異なる設定を定義することができます。インベントリファイルやホスト変数ファイルで定義されることが一般的です。

例:インベントリファイルに直接定義

[web]
192.168.1.10 ansible_user=admin app_name=my-web-app

例:ホスト変数ファイルに定義 ディレクトリ構造

inventory/
├── host_vars/
│   ├── 192.168.1.10.yml

host_vars/192.168.1.10.yml


app_name: my-web-app
db_name: web_db

定義したそれぞれの変数は以下のように使用します。


– name: Example Playbook with Host Variables
  hosts: web
  tasks:
    – name: Print host-specific variables
      debug:
        msg: “App Name: {{ app_name }}, DB Name: {{ db_name }}”
  • 各ホストに固有の値を持たせることが可能
  • ホスト固有の設定(IPアドレス、アプリケーション名など)に最適
  • host_varsディレクトリ内に定義することで管理が容易になります

グループ変数

グループ変数は、特定のホストグループに対して適用される変数です。インベントリファイル内で定義したホストグループごとに設定できます。複数のホストに共通する設定値を管理する際に役立ちます。

例:インベントリファイルに直接定義

[web]
192.168.1.10
192.168.1.11

[web:vars]
app_env=production

例:グループ変数ファイルに定義 ディレクトリ構造

inventory/
├── group_vars/
│   ├── web.yml

group_vars/web.yml


app_env: production
db_user: admin

使用例


– name: Example Playbook with Group Variables
  hosts: web
  tasks:
    – name: Print group-specific variables
      debug:
        msg: “Environment: {{ app_env }}, DB User: {{ db_user }}”
  • 同じグループに属するホストに対して一括設定が可能
  • グループごとの設定(環境設定、共通アカウント情報など)に最適
  • group_varsディレクトリ内に定義することで管理が簡単になる

Ansibleにおける変数には明確な優先順位があり、どの変数が最終的に適用されるかが定義されています。

変数の優先順位

ここからは、変数の優先順位を解説します。上から高い順に列挙していきます。

  1. –extra-vars(コマンドラインで指定する変数)
    →常にすべての変数より優先される
  2. タスク変数(task vars)
    → タスクレベルで定義された変数
  3. ブロック変数(block vars)
    → block 内で定義された変数。
  4. ロール変数(role vars)
    → ロール内の vars/main.yml で定義された変数
  5. Playbookレベルの変数
    → Playbook内の vars セクションや vars_files による変数
  6. インベントリのホスト変数やグループ変数
    → host_vars や group_vars で定義された変数
  7. デフォルト変数(role defaults)
    → ロール内の defaults/main.yml に定義された変数

適切なスコープで変数を定義し、衝突や予期しない動作を回避しましょう。詳細については、公式ドキュメントをご確認ください。

変数の優先順位の具体例

同じ名前の変数(app_port)が異なる場所で定義されています。どの値が最終的に適用されるかを確認してみましょう。

Playbook(example.yml)


– name: Demonstrate variable precedence
  hosts: localhost
  vars:
    app_port: 8080  # Playbook内で定義された変数
  tasks:
    – name: Override variable at task level
      vars:
        app_port: 9090  # タスク内で定義された変数
      debug:
        msg: “The app is running on port {{ app_port }}”

インベントリファイル(inventory.ini)

[all]
localhost ansible_connection=local

[all:vars]
app_port=7070  # インベントリファイルで定義された変数

この例を実行すると、app_portには最も優先順位が高いタスク内で定義された値(9090)が適用されます。

$ ansible-playbook example.yml

TASK [Override variable at task level] ****************************************************************
ok: [localhost] => {
    “msg”: “The app is running on port 9090”
}

動的変数と静的変数

Ansibleで効率的な構成管理を行うには、「動的変数」と「静的変数」を適切に使い分けることが重要です。

動的変数

動的変数とは、実行時の条件やテンプレートを基に値が生成される変数を指します。Jinja2テンプレートや条件分岐を活用することで、柔軟かつ自動的に値を決定することが可能です。

  • 条件やループに応じて動的に値が変化。
  • 再利用性が高く、複数の環境に対応可能。
  • シンプルなPlaybookでは難しい複雑なロジックを表現できる。

静的変数

静的変数は、あらかじめ設定された固定値を持つ変数です。変数の値は実行時に変化しません。

  • 値が固定されているため、動作が予測しやすい。
  • 主に環境設定や基本的な構成で使用される。
  • 他のタスクや条件に依存しないシンプルな設定に最適。

ループでの動的変数

Ansibleでは、Jinja2テンプレートを使用して動的に値を生成することが可能です。ループを活用して、複数のリソースを動的に生成する例を見てみましょう。


– name: Launch multiple EC2 instances with dynamic variables
  hosts: localhost
  connection: local
  vars:     # 動的にインスタンスを作成するための変数リストを定義
    ec2_instances:
      – { name: “web-server-1”, instance_type: “t2.micro” }
      – { name: “web-server-2”, instance_type: “t2.micro” }
  tasks:
    – name: Create EC2 instances dynamically
      amazon.aws.ec2_instance:
        name: “{{ item.name }}”  # インスタンスの名前を動的に設定
        instance_type: “{{ item.instance_type }}”
        image_id: “ami-0abcdef1234567890”
        key_name: “my-key”
        state: present
      loop: “{{ ec2_instances }}”  # ループ処理を使い、ec2_instancesリストの各要素を使用
      register: ec2_results

    – name: Display created instances
      debug:
        msg: “Created instance {{ item.instances[0].id }} with name {{ item.instances[0].tags.Name }}”
      loop: “{{ ec2_results.results }}”
  • varsで動的変数を定義
    ec2_instancesに各インスタンスの情報(名前とインスタンスタイプ)をリスト形式で定義しています。
  • loopで動的にリソースを生成
    loopを使用し、リスト内の各項目(item.nameやitem.instance_type)を参照してインスタンスを作成します。
  • 登録結果を利用して表示

registerで保存した結果を利用して、生成されたインスタンスのIDや名前を表示しています。

TASK [Create EC2 instances dynamically] ************************************************
changed: [localhost] => (item={‘name’: ‘web-server-1’, ‘instance_type’: ‘t2.micro’})
changed: [localhost] => (item={‘name’: ‘web-server-2’, ‘instance_type’: ‘t2.micro’})

TASK [Display created instances] *******************************************************
ok: [localhost] => (item={‘instances’: [{‘id’: ‘i-0a1b2c3d4e5f6g7h8’, ‘tags’: {‘Name’: ‘web-server-1’}}]}) => {
    “msg”: “Created instance i-0a1b2c3d4e5f6g7h8 with name web-server-1”
}
ok: [localhost] => (item={‘instances’: [{‘id’: ‘i-1a2b3c4d5e6f7g8h9’, ‘tags’: {‘Name’: ‘web-server-2’}}]}) => {
    “msg”: “Created instance i-1a2b3c4d5e6f7g8h9 with name web-server-2”
}

条件分岐での動的変数


– name: Apply dynamic variables based on conditions
  hosts: localhost
  connection: local
  vars:
    environment: “production”  # 環境を指定(”production” または “development”)

  tasks:
    # 条件に基づいて動的にデータベースのホストとユーザーを設定
    – name: Set database configuration dynamically
      set_fact:
        db_host: >-
          {% if environment == ‘production’ %}
          db.prod.example.com  # 本番環境用のデータベースホスト
          {% else %}
          db.dev.example.com  # 開発環境用のデータベースホスト
          {% endif %}
        db_user: >-
          {% if environment == ‘production’ %}
          prod_user  # 本番環境用のデータベースユーザー
          {% else %}
          dev_user  # 開発環境用のデータベースユーザー
          {% endif %}

    # 動的に設定されたデータベースホストとユーザー情報を表示
    – name: Display database configuration
      debug:
        msg:
          – “Database host: {{ db_host }}”  # 設定されたdb_host変数を表示
          – “Database user: {{ db_user }}”  # 設定されたdb_user変数を表示
  • 環境変数に基づく条件分岐
    environmentがproductionの場合は本番用のデータベース設定、それ以外の場合は開発用の設定を使用します。
  • set_factで動的に変数を生成
    条件分岐(if-else構文)を用いて、environmentの値に応じたデータベースホスト(db_host)とユーザー(db_user)を動的に設定します。
  • 結果の表示
    動的に生成された変数(db_hostとdb_user)の値を確認しています。

変数を取り扱う上で気をつけること

デフォルト変数をdefaults/main.ymlに定義する

Ansibleでは、Rolesを使用する際にデフォルトの変数をdefaults/main.ymlに定義することが推奨されています。デフォルト変数を定義しておくと、必要な値を一元管理でき、複数のタスクやPlaybookで簡単に再利用できます。

また、優先順位は優先順位が低いため、必要に応じて他の場所(例えばPlaybookやインベントリファイル)で簡単に上書きが可能です。その際は、デフォルト変数を定義しないことによる二度手間や修正が発生しないよう注意しましょう。

適切なスコープに分散する

Ansibleの変数にはさまざまなスコープが存在します。変数を適切なスコープに分散させることで、管理性が向上し、予期しない動作を防ぐことができます。

グローバル変数・グループ変数・ホスト変数の影響範囲を正しく理解し、不要な上書きや設定ミスを防止するよう変数管理しましょう。

命名規則を明確にする

PlaybookやRolesで使用する変数名の命名規則を統一することで、チーム内でのコード共有や保守性が向上します。役割や用途が一目でわかるように、すべての変数名で一貫性を保つことを心がけましょう。

まとめ

Ansibleで変数を適切に活用することで、Playbookの柔軟性や再利用性を大幅に向上させることができます。本記事では、変数の定義方法やスコープ、優先順位を解説し、動的変数の活用方法や注意点についても具体的なコード例を交えて紹介しました。特に、変数を適切なスコープに分散し、命名規則を統一することが重要です。

次の記事では、Ansible Vaultで暗号化ファイルをPlaybookで活用する方法について紹介します。興味のある方は、ぜひご覧ください。

現在クラウドエンジニアとして勤務。AWS(SAP、DOP)とAzure(AZ-305)の資格を保有しており、ネットワークやセキュリティに関する業務を主に行っています。

最新情報をお届けします!

最新のITトレンドやセキュリティ対策の情報を、メルマガでいち早く受け取りませんか?ぜひご登録ください

メルマガ登録

最新情報をお届けします!

最新のITトレンドやセキュリティ対策の情報を、メルマガでいち早く受け取りませんか?ぜひご登録ください

メルマガ登録