在 Ansible 中调用变量

Call variable in Ansible

很抱歉这个简单的问题,但我尝试了各种方法都没有成功。

这是我的 vars 文件

---
preprod:
  name: nginx
prod:
  name: apache

我正在尝试根据用户提供的环境名称(preprod、prod 等)传递 name 的值。 这是我的模板

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: {{ env.name }} 
  name: {{ env.name }}
  namespace: default
spec:
  selector:
    matchLabels:
      app: {{ env.name }}
  template:
    metadata:
      labels:
        app: {{ env.name }}
    spec:
      containers:
      - image: {{ env.name }}
        imagePullPolicy: Always
        name: {{ env.name }}
        resources: {}

但是,当我尝试使用以下命令时:

ansible-playbook playbook.yaml -e env=preprod

我收到以下错误。

fatal: [localhost]: FAILED! => {"changed": false, "msg": "AnsibleUndefinedVariable: 'str object' has no attribute 'name'"}

我的期望是 {{ env.name }} 应该被替换为 preprod.name 的值,如本例中的 nginx

我希望用户在命令行上通过 -eenv 提供值,看来如果我直接在模板上喜欢 preprod.name,似乎可以工作,但我不想那样。

我希望这能澄清我正在尝试做的事情,但它没有用。 我可以知道我错过了什么吗?

此错误消息表明作为 -e 在命令行上传递的额外 var 是一个字符串,而不是我们从 vars 文件加载的字典的键(我们期望的)。

我正在制作一个示例剧本,因为您没有展示如何加载您的 vars 文件。我正在使用 include_vars 因为我们可以命名要将 dict 加载到的变量。

    # include vars with a name, so that we can access testvars[env]
    - include_vars:
        file: testvars.yml
        name: testvars
    - template:
        src: test/deployment.yaml.j2
        dest: /tmp/deployment.yaml
      vars:
        _name: "{{ testvars[env]['name'] }}"

通过这种方法,prodpreprod 键将在 testvars 下可用,并且可以使用 env.[=19 等变量进行引用=]

那么模板应该使用_name变量,比如:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: {{ _name }} 

给定变量在剧本可以找到的地方,例如group_vars/all。可选择添加 default_env

shell> cat group_vars/all
preprod:
  name: nginx
prod:
  name: apache
default_env:
  name: lighttpd

使用 vars lookup plugin"Retrieve the value of an Ansible variable".

shell> ansible-doc -t lookup vars

例如剧本

shell> cat playbook.yml
- hosts: test_11
  vars:
    env: "{{ lookup('vars', my_env|default('default_env')) }}"
    app: "{{ env.name }}"
  tasks:
    - debug:
        var: app

默认显示

shell> ansible-playbook playbook.yml
...
  app: lighttpd

现在您可以通过声明变量 my_env 来 select 环境,.e.g

shell> ansible-playbook playbook.yml -e my_env=prod
...
  app: apache

shell> ansible-playbook playbook.yml -e my_env=preprod
...
  app: nginx