AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / server / 问题 / 962040
Accepted
Synchro
Synchro
Asked: 2019-04-09 06:51:33 +0800 CST2019-04-09 06:51:33 +0800 CST 2019-04-09 06:51:33 +0800 CST

在播放之间共享 ansible 变量

  • 772

这是对这个问题的跟进。

我有一个配置一堆 EC2 实例的游戏。必要时,该hosts值是localhost(因为当它运行时没有主机),并且该播放组装了一个名为的新主机列表ec2hosts,并生成主机 ip 到主机名映射,因为这是第一次也是唯一一次提供该信息,并且使用set_fact. 这个主机列表是后续游戏的主题。问题是我需要hostname_map在第二次播放中使用在配置播放期间创建的字典,而我看不到如何执行此操作。

这是第一部戏:

- hosts: localhost
  connection: local
  gather_facts: False

  tasks:
    - name: Provision a set of instances
      ec2:
        key_name: marcus
        instance_type: t2.micro
        image: "{{ ami_id }}"
        wait: true
        exact_count: "{{ server_count }}"
        count_tag:
          Tutorial: "{{ tutorial_name }}"
        instance_tags:
          Tutorial: "{{ tutorial_name }}"
        groups: ['SSH', 'Web']
      register: ec2

    - name: Add all instance public IPs to host group
      add_host:
        hostname: "{{ item.public_ip }}"
        groups: ec2hosts
      loop: "{{ ec2.instances }}"

    - name: Build an IP to hostname map
      set_fact:
        hostname_map: "{{ hostname_map | combine({item.0.public_ip: (item.1 + '.' + tutorial_domain)}) }}"
      loop: "{{ ec2.instances|zip(hostnames)|list }}"

    - name: Debug hostname_map
      debug:
        msg: "{{ hostname_map }}"

最后,hostname_map包含如下地图:

{
    "18.184.109.70": "host1.example.com", 
    "18.196.135.59": "host2.example.com"
}

通过阅读关于变量范围的 ansible 文档,它说在剧本中定义的变量在该剧本之外不可用,除非它被应用于同一组主机。在这种情况下这是不可能的,所以我需要使用具有全局范围的 var,从我读过的内容set_fact来看,这是执行此操作的适当方法。所以我在 中创建了一个空变量/group_vars/all,以便所有播放都可以访问该变量:

hostname_map: {}

下一个播放连接到每个新创建的实例(使用我们动态创建的主机列表)并从内部设置其主机名:

- hosts: ec2hosts
  gather_facts: yes
  tasks:
    - name: Debug hostname_map
      debug:
        msg: "{{ hostname_map }}"
    - name: Set hostnames
      hostname:
        name: "{{ hostname_map[ansible_host] }}"

但是,这失败了,因为hostname_map它是空的

TASK [Debug hostname_map]
ok: [18.184.109.70] => {
    "msg": {}
}
ok: [18.196.135.59] => {
    "msg": {}
}

所以我得到这个错误:

致命:[18.184.109.70]:失败!=> {“msg”:“任务包含一个带有未定义变量的选项。错误是:'dict object'没有属性u'18.184.109.70'

奇怪的是,即使我没有全局定义变量,我也会得到相同的调试输出和错误。

我读过的其他文章都建议应该在 中明确枚举值vars,但我不能这样做,因为数据是动态的,直到运行时才知道。同样,出于同样的原因,我无法extra_vars在命令行上使用它。

如何在第二次播放中使此变量可用?我想避免笨拙的解决方案,例如将本地文件写出然后再将其读回!

我也愿意接受以完全不同的方式执行此操作的建议,其中“this”是:创建任意数量的 EC2 实例并为它们分配从静态列表中获取的主机名。

amazon-ec2
  • 3 3 个回答
  • 18142 Views

3 个回答

  • Voted
  1. Best Answer
    Zoredache
    2019-04-09T09:33:35+08:002019-04-09T09:33:35+08:00

    您设置的值set_fact将在不同的播放之间可用。请记住, set_fact 是为特定主机设置的。您的第一个游戏是针对localhost运行的,因此事实是 localhosts 变量的一部分。因此,在接下来的游戏中,您应该能够通过这样的任务访问它。

    - debug:
        var: hostvars['localhost']['hostmap']
    
    • 16
  2. Most Wanted
    2020-09-29T03:32:14+08:002020-09-29T03:32:14+08:00

    您可以使用虚拟主机,它将在add_host的帮助下存储您想要共享的所有变量。然后只需使用hostvars访问您的变量

    - hosts: "18.184.109.70"
      user: ubuntu
      tasks:
        - name: set a variable
          set_fact:
            shared_variable: "Some value"
        - name: add variables to dummy host
          add_host:
            name: "variable_holder"
            shared_variable:  "{{ shared_variable }}"
    
    - hosts: "18.196.135.59"
      user: ubuntu
      vars:
        shared_variable: "{{ hostvars['variable_holder']['shared_variable'] }}"
      tasks:
        - debug:
            msg: "{{ shared_variable }}"
    
    • 2
  3. Delisa Simonovic
    2020-04-25T02:50:01+08:002020-04-25T02:50:01+08:00

    取决于你如何定义游戏。如果您在一次 ansible 运行中进行多次播放,则它可以工作。但是不适用于多个连续播放。我的意思是当你运行 ansible-playbook playbook1.yml 时它不起作用,然后运行 ​​ansible-playbook playbook2.yml

    • 0

相关问题

  • 权限被拒绝(公钥)。从本地 Ubuntu 到 Amazon EC2 服务器的 SSH

  • 管理员如何管理他们的 EC2 EBS 和快照?

  • 云有多大?[关闭]

  • EC2 映像启动

  • 如何将安全组添加到正在运行的 EC2 实例?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    新安装后 postgres 的默认超级用户用户名/密码是什么?

    • 5 个回答
  • Marko Smith

    SFTP 使用什么端口?

    • 6 个回答
  • Marko Smith

    命令行列出 Windows Active Directory 组中的用户?

    • 9 个回答
  • Marko Smith

    什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同?

    • 3 个回答
  • Marko Smith

    如何确定bash变量是否为空?

    • 15 个回答
  • Martin Hope
    Tom Feiner 如何按大小对 du -h 输出进行排序 2009-02-26 05:42:42 +0800 CST
  • Martin Hope
    Noah Goodrich 什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同? 2009-05-19 18:24:42 +0800 CST
  • Martin Hope
    Brent 如何确定bash变量是否为空? 2009-05-13 09:54:48 +0800 CST
  • Martin Hope
    cletus 您如何找到在 Windows 中打开文件的进程? 2009-05-01 16:47:16 +0800 CST

热门标签

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve