You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何利用GCP标签在Ansible Play中动态设置ansible_fqdn?

解决Ansible动态构建GCP实例FQDN的问题

问题背景

将GCP作为Ansible inventory源时,GCP默认不会暴露虚拟机实例的FQDN,ansible_host被设置为实例的IP地址。为了通过域名管理实例,给GCP实例添加了domainmembership标签(值为域名前缀),固定域名后缀为.somedomain,希望动态构建ansible_fqdn并将ansible_host替换为对应的FQDN,但执行Playbook时出现hostvars['domain1']未定义的错误。

原Playbook代码

---
- name: Patching - pre checks
  hosts: "{{ target_hosts | default('all') }}"
  gather_facts: false

  pre_tasks:
    - name: Include environment variables for GCP Windows Domain Members
      include_vars:
        dir: group_vars/gcp
      when:
         - labels.domainmembership is defined
         - '"windows" in labels.operatingsystem'

    - name: Set facts for identified GCP Domain Members
      ansible.builtin.set_fact:
        domainlabel_secondpart: '{{ ".somedomain" }}'
        ansible_fqdn: "{{ hostvars[labels.domainmembership] + domainlabel_secondpart }}"
        ansible_host: "{{ ansible_hostname_full }}"
        cacheable: yes
      when:
         - labels.domainmembership is defined
         - '"windows" in labels.operatingsystem'  

错误信息

TASK [Set facts for identified GCP Domain Members] *****************************
fatal: [server1]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: \"hostvars['domain1']\" is undefined. \"hostvars['domain1']\" is undefined

The error appears to be in '/runner/project/pre-checks-test.yml': line 36, column 7, but may
be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:


    - name: Set facts for identified GCP Domain Members
      ^ here
"}

GCP实例Inventory信息示例

{
  "ansible_host": "10.0.0.2",
  "canIpForward": false,
  "cpuPlatform": "Intel Cascade Lake",
  "creationTimestamp": "2023-04-26T23:55:38.932-07:00",
  "deletionProtection": false,
  "name": "server1",
  "project": "someproject",
  "startRestricted": false,
  "status": "RUNNING",
  "labels": {
    "domainmembership": "domain1",
    "operatingsystem": "windows"
  }
}

错误原因

错误出在ansible_fqdn的赋值逻辑:hostvars[labels.domainmembership]试图调用名为domain1的主机对应的变量,但domain1只是GCP实例的标签值,并非Ansible inventory中的主机名,因此该变量不存在。

修正方案

直接使用GCP实例的domainmembership标签值与固定后缀拼接,生成FQDN,同时将ansible_host设置为这个FQDN即可。修正后的set_fact任务如下:

- name: Set facts for identified GCP Domain Members
  ansible.builtin.set_fact:
    ansible_fqdn: "{{ labels.domainmembership }}.somedomain"
    ansible_host: "{{ ansible_fqdn }}"
    cacheable: yes
  when:
     - labels.domainmembership is defined
     - '"windows" in labels.operatingsystem'

说明

  1. 直接拼接labels.domainmembership和.somedomain得到完整FQDN,无需借助hostvars
  2. 将ansible_host直接设置为刚生成的ansible_fqdn,替代原来的IP地址
  3. 保留cacheable: yes确保该事实可以在后续Play或任务中复用

验证

修正后执行Playbook,目标实例的ansible_fqdn会被设置为domain1.somedomain,ansible_host也会更新为该FQDN,后续任务将通过域名而非IP连接实例。

内容的提问来源于stack exchange,提问作者J1raya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 22:42:49