Ansibleインベントリの作業

Ansibleでは、インベントリ・リストと呼ばれるリストを単純なファイル(hostfileとも呼ばれる)として保持し、構成リソースを追跡します。これらのインベントリ・リストは静的にすることも動的にすることもできます。動的なリストは、インベントリ・リソースが追加、削除または移動されると自動的に更新されます。

多くのOracle Cloud Infrastructure (OCI)リソースが時間の経過とともに追加されたり削除されたりするため、静的インベントリ・リストの情報は簡単に古くなることがあります。TerraformやOCI SDKなどのツールもリソースに影響する可能性があります。

Oracle Cloud Infrastructureには、正確なAnsibleインベントリを維持するために動的インベントリ・プラグインが用意されています。

Ansibleインベントリ・ファイルの詳細は、インベントリの作業および動的インベントリの作業を参照してください。

インベントリ・プラグインの有効化

既存のansible.cfgファイルがあり、その構成でenable_pluginsを使用してプラグインがすでに有効にになっている場合は、OCIインベントリ・プラグインも追加して有効にする必要があります。例:

[inventory]
enable_plugins = oracle.oci.oci

enable_pluginsが指定されているansible.cfgファイルがまだない場合は、構成にOCIインベントリ・プラグインを追加する必要はありません。

インベントリ・プラグインの構成

有効にした後でOCIインベントリ・プラグインを使用するために必要な操作は、解析する権限を持っているインベントリ・ソースを指定することのみです。インベントリ・ソースは、YAML構成ファイルで定義されます。詳細は、ユーザーの権限を参照してください。

YAML構成ソースでインベントリ・プラグインの使用を開始するには、次のいずれかの許容されるファイル名を持つファイルを作成します:

  • <filename>.oci.yml
  • <filename>.oci.yaml

plugin: oracle.oci.ociをYAML構成ファイルに追加します。

OCIインベントリ・プラグインの実行に必要な最小限のインベントリ・ソース・ファイルの例を次に示します:

# demo.oci.yml
plugin: oracle.oci.oci
 
# Optional fields to specify oci connection config:
config_file: ~/.oci/config
config_profile: DEFAULT

この例では、config_fileおよびconfig_profileパラメータを使用して、SDKおよびCLIの構成ファイルに説明されている認証情報をプラグインが使用できるようにしています。一部のパラメータは、環境変数としても指定できます。

プラグインでサポートされるパラメータおよび環境変数の完全なリストは、OCIインベントリ・プラグインを参照してください。インベントリのシナリオでは、使用可能なパラメータを多数紹介しています。

重要

デフォルトでは、OCIインベントリ・プラグインは、パブリックIPアドレスを持つコンピューティング・インスタンスのみを検出してリストします。詳細は、「ホスト名形式のプリファレンス」を参照してください。

優先順位

オプションが複数の場所で指定されている場合、インベントリ・プラグインは次の優先順位を使用します:

  1. YAMLファイルの設定。
  2. 環境変数。
  3. OCI構成ファイルで選択したprofileの構成設定。

データベース・ホストのフェッチ

デフォルトでは、OCIインベントリ・プラグインは、コンピュート・インスタンスのみが検出されて、リストされます。データベース・ノードは、データベース・ソフトウェアを実行しているサーバーです。データベース・ノードは、オプションfetch_db_hoststrueに設定するとフェッチされます。例:

# demo.oci.yml

# DB Hosts
plugin: oracle.oci.oci
fetch_db_hosts: true

インベントリ・プラグインの使用

Ansibleインベントリ・プラグインを使用してデータ・ソースを定義できます。Ansibleはこれを使用して、タスクのターゲット指定に使用するホストのインベントリをコンパイルします。これらのデータ・ソースには、-i /path/to/fileまたは-i 'host1, host2'コマンドライン・パラメータを使用してアクセスします。または、他の構成ソースからアクセスします。

たとえば、次のコマンドを使用してインベントリを実行できます:

ansible-inventory -i <filename>.oci.yml --graph

これによって、次のような出力が生成されます:

@all:
  |--@oci:
  |  |--compute_instance1
  |  |--compute_instance2
  |–@ungrouped:
重要

デフォルトでは、インベントリはテナンシのすべてのコンパートメントについて生成されます。このスクリプトがすべてのコンパートメントにアクセスできるようにするには、ルート・コンパートメントに対するCOMPARTMENT_INSPECT権限が必要です。ただし、compartment_ocidが指定されると、インベントリは特定のコンパートメントのみについて生成されるため、指定されたコンパートメントのみのCOMPARTMENT_INSPECT権限が必要になります。詳細は、ポリシーの仕組みを参照してください。

すべてのインスタンスの詳細をフェッチするには、インスタンスおよびVNICをリストして読み取る権限と、VCNおよびサブネットを読み取る権限も必要です。詳細は、ユーザーの権限を参照してください。

インベントリ・プラグインをプラグイン・パスに追加し、デフォルトのインベントリ・パスを設定して、コマンドを簡略化できます。デフォルトのインベントリ・パスをansible.cfgファイルの[defaults]セクションに追加するか、インベントリ・ソースを示すANSIBLE_INVENTORY環境変数を使用します。次のコマンドを実行すると、YAML構成ソースを直接渡すときと同じ出力が生成されます:

ansible-inventory --graph

通常、インベントリ・プラグインが実行されるのは、実行が開始されて、プレイブック、プレイおよびロールがロードされる前のみです。meta: refresh_inventoryタスクを使用するとプラグインを「再実行」できます。こうとすると、既存のインベントリが消去されて再作成されます。

インベントリの出力

インベントリ・プラグインで生成されるインベントリ・リストは、次の属性を使用してグループ化されます:

  • コンピュート・インスタンスが存在するリージョン
  • コンピュート・インスタンスが属するコンパートメントの名前
  • コンピュート・インスタンスが存在する可用性ドメイン
  • コンピュート・インスタンスが存在するVCNのvcn_id
  • コンピュート・インスタンスが存在するサブネットのsubnet_id
  • コンピュート・インスタンスが存在するサブネットのsecurity_list_ids
  • コンピュート・インスタンスの起動に使用されるイメージのimage_id
  • コンピュート・インスタンスのシェイプ
  • コンピュート・インスタンスのフリーフォーム・タグ(グループ名がtag_<tag_name>=<tag_value>に設定されている)
  • コンピュート・インスタンスの定義済タグ(グループ名が<tag_namespace>#<tag_name>=<tag_value>に設定されている)
  • OCIコンピューティング・インスタンスのメタデータ(キー/値ペア)(グループ名が<metadata-key>=<metadata-value>に設定されている)
  • OCIコンピューティング・インスタンスの拡張メタデータ(キー/値ペア)(グループ名が<metadata-key>=<metadata-value>に設定されている)

ホスト名形式のプリファレンス

OCIインベントリ・プラグインによって生成されるインベントリには、デフォルトでパブリックIPアドレスがあるインスタンスのみが含まれます。これが役立つのは、Ansibleコントローラ・ノードがVCNの外部にあり、パブリックIPアドレスがあるインスタンスにしかAnsibleがアクセスできない場合です。

inventory_hostnameprivate_ipまたはカスタム・ホスト名に構成するには、hostname_format_preferencesオプションにリストとしてJinja2式を渡します。hostname_format_preferencesオプションでは、Jinja2式のリストが優先順位に従って取得され、inventory_hostnameが構成されます。結果が空の文字列の場合や値がNoneの場合、インベントリ・プラグインでは式が無視されます。hostname_format_preferences式のいずれも空でない値になる場合、インスタンスは無視されます。

次の例では、inventory_hostname"display_name+'.oci.com'""private_ip"または"public_ip"のいずれかに設定されます。

hostname_format_preferences:
  - "display_name+'.oci.com'"
  - "private_ip"
  - "public_ip"

式は、すべてのインスタンスのhost_varsで評価されます。評価では、構成での優先順位を考慮してinventory_hostnameが構成されます。前述の例では、"display_name+'.oci.com'"は、"private_ip"および"public_ip"の前に評価されます。

ホストのフィルタリング

OCIインベントリ・プラグインには、プラグインによって返されたホストをフィルタするための様々なフィルタリング・オプションが付属しています。

インベントリからのホストの除外

Jinja2条件式のリストをexclude_host_filtersパラメータに渡すことができます。リスト内の各式は、ホストごとに評価されます。式がtrueの場合、ホストはインベントリから除外されます。exclude_host_filtersパラメータは、include_host_filtersおよびfiltersオプションより優先されます。

次の例では、リージョンiadに存在しないホストがインベントリから除外されます:

exclude_host_filters:
  - "region not in ['iad']"

フリーフォーム・タグを使用したホストの除外

フリーフォーム・タグを使用してインベントリからホストを除外するには、次の構文を使用できます:

exclude_host_filters:
  # filter the hosts with freeform tag with key <tag_key> which has value <tag_value>
  - "'<tag_value>' == freeform_tags.<tag_key>"
  # filter the hosts which has <tag_key> freeform tag
  - "'<tag_key>' in freefrom_tags"

例:

exclude_host_filters:
  - "'operating_system' in freeform_tags"
  - "'linux' == freeform_tags.operating_system"

定義済タグを使用したホストの除外

定義済タグを使用してインベントリからホストを除外するには、次の構文を使用できます:

exclude_host_filters:
  #filter the hosts with defined tag in <namespace> with <tag_key> and <tag_value>
  - "'<tag_value>' == defined_tags.<namespace>.<tag_key>"
  # filter the hosts with <tag_key> in the <namespace> in defined tags
  - "'<tag_key>' in defined_tags.<namespace>"

例:

exclude_host_filters:
  - "'ansible' == defined_tags.ansible_collections_tag_namespace.managed_by"
  - "'managed_by' in defined_tags.ansible_collections_tag_namespace"

インベントリへのホストの追加

Jinja2条件式のリストをinclude_host_filtersパラメータに渡すことができます。リスト内の各式は、ホストごとに評価されます。式がtrueの場合、ホストはインベントリに追加されます。

次の例では、display_nameが'.oci.com'で終わるホストのみがインベントリに追加されます:

include_host_filters:
  - "display_name is match('.*.oci.com')"
ノート

include_host_filtersオプションとfiltersオプションを同時に使用することはできません。

フリーフォーム・タグを使用したホストの追加

フリーフォーム・タグを使用してインベントリにホストを追加するには、次の構文を使用できます:

include_host_filters:
  # filter the hosts with freeform tag with key <tag_key> which has value <tag_value>
  - "'<tag_value>' == freeform_tags.<tag_key>"
  # filter the hosts which has <tag_key> freeform tag
  - "'<tag_key>' in freefrom_tags"

例:

include_host_filters:
  - "'operating_system' in freeform_tags"
  - "'linux' == freeform_tags.operating_system"

定義済タグを使用したホストの追加

定義済タグを使用してインベントリにホストを追加するには、次の構文を使用できます:

include_host_filters:
  #filter the hosts with defined tag in <namespace> with <tag_key> and <tag_value>
  - "'<tag_value>' == defined_tags.<namespace>.<tag_key>"
  # filter the hosts with <tag_key> in the <namespace> in defined tags
  - "'<tag_key>' in defined_tags.<namespace>"

例:

include_host_filters:
  -  "'ansible' == defined_tags.ansible_collections_tag_namespace.managed_by"
  -  "'managed_by' in defined_tags.ansible_collections_tag_namespace"

キャッシングの有効化

キャッシングを有効にすると、検索を高速化できます。個々のYAML構成ソース、または環境変数やAnsible構成ファイルを使用する複数のインベントリ・ソースにキャッシング・オプションを設定できます。インベントリ固有のキャッシング・オプションを指定せずにインベントリ・プラグインのキャッシングを有効にすると、インベントリ・プラグインはファクト・キャッシング・オプションを使用します。

個々のYAML構成ファイルのキャッシングを有効にする例を次に示します:

# demo.oci.yml
plugin: oracle.oci.oci
cache: yes
cache_plugin: jsonfile
cache_timeout: 7200
cache_connection: /tmp/oci_inventory
cache_prefix: oci

動的グループの使用

作成されたkeyed_groupsオプションとホスト変数を使用して動的グループを作成できます。オプションgroupsは、グループの作成や、ホスト変数の作成および変更にも使用できます。キー・グループおよびタグを使用するグループの構文は次のとおりです:

keyed_groups
- key: freeform_tags.<tag key>
  prefix: <my_prefix>
- key: defined_tags.<namespace>.<tag key>
  prefix: <my_prefix>
groups:
  <group_name>: "'<tag_value>' == freeform_tags.<tag_key>"
  <group_name>: "'<tag_value>' == defined_tags.<namespace>.<tag_key>"
  <group_name>: "'<tag_key>' in defined_tags.<namespace>"

例:

# demo.oci.yml
plugin: oracle.oci.oci
regions:
  - us-phoenix-1
  - us-ashburn-1
keyed_groups:
  # add hosts to tag_Name_value groups for each oci host's tags.Name variable
  - key: tags.Name
    prefix: tag_Name_
groups:
  # add hosts to the group development if any of the dictionary's keys or values is the word 'devel'
  development: "'devel' in (tags|list)"
  # add hosts with freefrom_tags that has 'operating_system' key and 'linux' value to 'linux' group
  linux: "'linux' == freeform_tags.operating_system"
  # add hosts with freefrom tags that has 'operating_system' key to os group
  os: "'operating_system' in freeform_tags"
  # add hosts with defined tags in the namespace 'ansible_collections_tag_namespace' with tag 'managed_by' and value 'ansible'
  ansible_managed: "'ansible' == defined_tags.ansible_collections_tag_namespace.managed_by"
  # add hosts with defined tags in the namespace 'ansible_collections_tag_namespace' with tag 'managed_by'
  cm_managed_hosts: "'managed_by' in defined_tags.ansible_collections_tag_namespace"

この例では、次のような出力が生成されます。

@all:
  |--@development:
  |  |--compute_instance1
  |  |--compute_instance2
  |--@linux:
  |  |--compute_instance1
  |--@os:
  |  |--compute_instance1
  |  |--compute_instance2
  |--@ansible_managed:
  |  |--compute_instance1
  |--@cm_managed_hosts:
  |  |--compute_instance2
  |--@ungrouped

ホストの構成に変数が指定されていない場合、ホストは、インベントリ・プラグインで作成されたグループ以外には追加されず、ansible_hostホスト変数は変更されません。

インベントリのシナリオ

後続の項では、一般的なインベントリのシナリオを対象とした構成の例を説明します。

すべてのコンピュート・ホストのフェッチ

すべてのホストをフェッチする場合、構成は次の例のようにシンプルなものになります:

plugin: oracle.oci.oci

DBホストのみのフェッチ

コンピュート・ホストを除き、データベース・ソフトウェアをホストしているすべてのノードをフェッチする場合、構成は次の例のようになります:

plugin: oracle.oci.oci

# fetch databse hosts
fetch_db_hosts: true
# don't fetch Compute hosts
fetch_compute_hosts: False

特定リージョンのホストのフェッチ

指定したリージョンでのみホストをフェッチする場合、構成は次の例のようになります:

plugin: oracle.oci.oci

# Fetch only the hosts in the regions us-ashburn-1, us-phoenix-1
regions:
  - us-ashburn-1
  - us-phoenix-1

インベントリのホスト名の設定

インベントリで使用されるインベントリのホスト名の形式を設定するには、次の例のようなセクションを構成に加えます:

plugin: oracle.oci.oci

# Sets the inventory_hostname to either "display_name+'.oci.com'", "public_ip", "private_ip", or "id" 
# "display_name+'.oci.com'" has more preference than "public_ip", "private_ip", "id".
hostname_format_preferences:
  - "display_name+'.oci.com'"
  - "public_ip"
  - "private_ip"
  - "id"

詳細は、「ホスト名形式のプリファレンス」を参照してください。

インベントリからのホストの除外

Jinja2条件式を使用してインベントリからホストを除外するには、構成に次の例のようなセクションを加えます:

plugin: oracle.oci.oci

# Excludes hosts that are not in the region 'iad' from the inventory
exclude_host_filters:
  - "region not in ['iad']"

詳細は、「ホストのフィルタリング」を参照してください。

インベントリへのホストの追加

Jinja2条件式を使用してインベントリにホストを追加するには、構成に次の例のようなセクションを加えます:

plugin: oracle.oci.oci

# Includes only the hosts that have a display_name ending with '.oci.com' in the inventory
include_host_filters:
  - "display_name is match('.*.oci.com')"

詳細は、「ホストのフィルタリング」を参照してください。

ノート

include_host_filtersオプションとfiltersオプションを同時に使用することはできません。

特定コンパートメントのホストのフェッチ

次の例では、指定されたコンパートメントからすべてのホストをフェッチする方法を示しています:

# Fetch all hosts
plugin: oracle.oci.oci

# Select compartment by OCID or name
compartments:
  - compartment_ocid: <ocid1.compartment.oc1..exampleuniqueID>
    fetch_hosts_from_subcompartments: false

  - compartment_name: "<compartment_name>"
    parent_compartment_ocid: <ocid1.tenancy.oc1..exampleuniqueID>

その他のオプション

次の構成の例では、前述のシナリオにさらに構成オプションを加えています:

# Fetch all hosts
plugin: oracle.oci.oci

# Optional fields:
config_file: ~/.oci/config
config_profile: DEFAULT

# Example select regions
regions:
  - us-ashburn-1
  - us-phoenix-1

# Enable threads to speedup lookup
enable_parallel_processing: yes

# Select compartment by ocid or name
compartments:
  - compartment_ocid: <ocid1.compartment.oc1..exampleuniqueID>
    fetch_hosts_from_subcompartments: false

  - compartment_name: "<compartment_name>"
    parent_compartment_ocid: <ocid1.tenancy.oc1..exampleuniqueID>

# Sets the inventory_hostname. Each item is a Jinja2 expression and it gets evaluated on host_vars.
hostname_format_preferences:
  - "display_name+'.oci.com'"
  - "private_ip"
  - "public_ip"

# Excludes a host from the inventory when any of the Jinja2 expression evaluates to true.
exclude_host_filters:
  - "region not in ['iad']"
  - "'<tag_key>' in freeform_tags"
  - "'<tag_value>' == freeform_tags.<tag_key>"
  - "'<tag_value>' == defined_tags.<namespace>.<tag_key>"
  - "'<tag_key>' in defined_tags.<namespace>"

# Includes a host in the inventory when any of the Jinja2 expression evaluates to true.
include_host_filters:
  - "display_name is match('.*.oci.com')"
  - "'<tag_key>' in freeform_tags"
  - "'<tag_value>' == freeform_tags.<tag_key>"
  - "'<tag_value>' == defined_tags.<namespace>.<tag_key>"
  - "'<tag_key>' in defined_tags.<namespace>"

# Example group results by key
keyed_groups
- key: freeform_tags.<tag key>
  prefix: <my_prefix>
- key: defined_tags.<namespace>.<tag key>
  prefix: <my_prefix>

groups:
  <group_name>: "'<tag_value>' == freeform_tags.<tag_key>"
  <group_name>: "'<tag_value>' == defined_tags.<namespace>.<tag_key>"
  <group_name>: "'<tag_key>' in defined_tags.<namespace>"

# Example to create and modify a host variable
compose:
  ansible_host: display_name+'.oracle.com'

# Example flag to turn on debug mode
debug: true

# Enable Cache
cache: yes
cache_plugin: jsonfile
cache_timeout: 7200
cache_connection: /tmp/oci-cache
cache_prefix: oci_

# DB Hosts
fetch_db_hosts: True

# Compute Hosts (bool type)
fetch_compute_hosts: True

# Process only the primary vnic of a compute instance
primary_vnic_only: True

インベントリ・プラグインのトラブルシューティング

OCIインベントリ・プラグインによって生成されたインベントリ・リストに、テナンシのすべてのコンピューティング・インスタンスが含まれていない場合は、次の情報を確認してください。

ユーザーの権限

ユーザーに次のポリシー権限があることを確認します。ユーザーOCIDは、OCI_USER環境変数を使用するか、SDKおよびCLI構成ファイルのprofileセクションを使用して指定します。

API操作のための権限のリストを表示するには、コア・サービスの詳細を参照してください。

インベントリ・プラグインでは、次の操作のAPIコールが実行されます:

  • ListCompartments
  • GetCompartment
  • ListVNICAttachments
  • GetVNIC
  • GetSubnet
  • GetVLAN
  • GetVCN
  • ListInstances
  • GetInstance
  • ListDBNodes
  • ListDBSystems
  • ListRegionSubscriptions

詳細情報

OCIインベントリ・プラグインの使用の詳細は、docs.oracle.comおよびreadthedocs.ioを参照してください。

次のコマンドを使用して、プラグインのドキュメントを表示することもできます:

ansible-doc -t inventory oracle.oci.oci

インベントリ・プラグインの詳細は、公式なAnsibleドキュメントを参照してください。