在 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
。
我希望用户在命令行上通过 -e
为 env
提供值,看来如果我直接在模板上喜欢 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'] }}"
通过这种方法,prod
和 preprod
键将在 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
很抱歉这个简单的问题,但我尝试了各种方法都没有成功。
这是我的 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
。
我希望用户在命令行上通过 -e
为 env
提供值,看来如果我直接在模板上喜欢 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'] }}"
通过这种方法,prod
和 preprod
键将在 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