Ansible/Jinja: Docker/Podman 中的条件端口发布
Ansible/Jinja: Conditional port publishing in Docker/Podman
我的意图很简单:IF 我在我的 Ansible 剧本中指定了一个 端口,将它暴露在容器中 created/updated.否则,不要暴露任何端口。
我认为通过这种尝试更容易理解我的意图:
- name: Create MySQL Docker Container
containers.podman.podman_container:
name: "mysql"
state: present
image: "mysql:8.0.26"
publish:
- "{{ omit if mysql_access_port is not defined else 'mysql_access_port:3306' }}"
这是 Podman,但语法就像 Docker。因此,端口分配应采用通常的格式 3306:3306
.
我的第一个问题是我无法在 jinja 表达式中连接 mysql_access_port
变量和字符串 :3306。这只是一个语法问题。用谷歌搜索,但无法弄清楚。
现在,假设上面的语法问题已解决,假设我硬编码了以下内容:
publish:
- "{{ omit if mysql_access_port is not defined else '3306:3306' }}"
如果定义了 mysql_access_port
,端口将按预期分配。
如果未定义,我不会跳过端口分配,而是收到以下错误消息:
fatal: [localhost]: FAILED! => {"changed": false, "msg": "Can't create container mysql", "stderr": "Error: error parsing container port: invalid port number: strconv.Atoi: parsing \"__omit_place_holder__0ad9ccf9b7e738c9d218e9d65dd2de8a359ac72c\": invalid syntax\n", "stderr_lines": ["Error: error parsing container port: invalid port number: strconv.Atoi: parsing \"__omit_place_holder__0ad9ccf9b7e738c9d218e9d65dd2de8a359ac72c\": invalid syntax"], "stdout": "", "stdout_lines": []}
似乎有不同的方法来获得我需要的东西(使用省略 + 三元等),但我就是做对了。
您不能省略列表的元素,即使可以,您也会得到一个空的 publish
,这也可能是无效的。
方法是在这样定义的列表中移动列表赋值:
publish: ['foobar']
有了这个,省略将开始作用于 publish
参数,您的行为将是预期的。
所以,在你的情况下:
publish: >-
{{
[mysql_access_port ~ ':3306']
if mysql_access_port is defined else omit
}}
备注
- 关于
mysql_access_port
的语法问题,Jinja 中的连接运算符是 tilde ~
- 一个好的做法是在可能的情况下尝试支持积极的断言而不是消极的断言,即
[mysql_access_port ~ ':3306'] if mysql_access_port is defined
而不是 omit if mysql_access_port is not defined
包含任务的剧本:
- debug:
msg:
publish: >-
{{
[mysql_access_port ~ ':3306']
if mysql_access_port is defined else omit
}}
会产生
TASK [debug] ***********************************************************
ok: [localhost] =>
msg: {}
但是,如果同一剧本是 运行 和 --extra-vars mysql_access_port=3306
,它将产生
TASK [debug] ***********************************************************
ok: [localhost] =>
msg:
publish:
- 3306:3306
我的意图很简单:IF 我在我的 Ansible 剧本中指定了一个 端口,将它暴露在容器中 created/updated.否则,不要暴露任何端口。
我认为通过这种尝试更容易理解我的意图:
- name: Create MySQL Docker Container
containers.podman.podman_container:
name: "mysql"
state: present
image: "mysql:8.0.26"
publish:
- "{{ omit if mysql_access_port is not defined else 'mysql_access_port:3306' }}"
这是 Podman,但语法就像 Docker。因此,端口分配应采用通常的格式 3306:3306
.
我的第一个问题是我无法在 jinja 表达式中连接 mysql_access_port
变量和字符串 :3306。这只是一个语法问题。用谷歌搜索,但无法弄清楚。
现在,假设上面的语法问题已解决,假设我硬编码了以下内容:
publish:
- "{{ omit if mysql_access_port is not defined else '3306:3306' }}"
如果定义了 mysql_access_port
,端口将按预期分配。
如果未定义,我不会跳过端口分配,而是收到以下错误消息:
fatal: [localhost]: FAILED! => {"changed": false, "msg": "Can't create container mysql", "stderr": "Error: error parsing container port: invalid port number: strconv.Atoi: parsing \"__omit_place_holder__0ad9ccf9b7e738c9d218e9d65dd2de8a359ac72c\": invalid syntax\n", "stderr_lines": ["Error: error parsing container port: invalid port number: strconv.Atoi: parsing \"__omit_place_holder__0ad9ccf9b7e738c9d218e9d65dd2de8a359ac72c\": invalid syntax"], "stdout": "", "stdout_lines": []}
似乎有不同的方法来获得我需要的东西(使用省略 + 三元等),但我就是做对了。
您不能省略列表的元素,即使可以,您也会得到一个空的 publish
,这也可能是无效的。
方法是在这样定义的列表中移动列表赋值:
publish: ['foobar']
有了这个,省略将开始作用于 publish
参数,您的行为将是预期的。
所以,在你的情况下:
publish: >-
{{
[mysql_access_port ~ ':3306']
if mysql_access_port is defined else omit
}}
备注
- 关于
mysql_access_port
的语法问题,Jinja 中的连接运算符是 tilde~
- 一个好的做法是在可能的情况下尝试支持积极的断言而不是消极的断言,即
[mysql_access_port ~ ':3306'] if mysql_access_port is defined
而不是omit if mysql_access_port is not defined
包含任务的剧本:
- debug:
msg:
publish: >-
{{
[mysql_access_port ~ ':3306']
if mysql_access_port is defined else omit
}}
会产生
TASK [debug] ***********************************************************
ok: [localhost] =>
msg: {}
但是,如果同一剧本是 运行 和 --extra-vars mysql_access_port=3306
,它将产生
TASK [debug] ***********************************************************
ok: [localhost] =>
msg:
publish:
- 3306:3306