使用 Ansible,如何在不丢失左填充的情况下将私钥写入文本文件?
With Ansible, how do I write a private key to a text file without losing the left padding?
换句话说,我希望将来自 Ansible 变量的内容写入配置文件中的特定“列”,并且我不希望该内容被包装。
任务:
- name: build cloud-init file
local_action:
module: ansible.builtin.template
src: cloud_config.j2
dest: ./cloud_config.yml
mode: 0640
tags: ['containers', 'containers:configuration']
保存在库文件中的变量:
machineuser_key: |
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
...
模板:
write_files:
{# ssh config to allow our deployment user to fetch the Ansible repo #}
{# See https://docs.github.com/en/developers/overview/managing-deploy-keys#machine-users #}
- path: /home/{{ gcp_deploy_user }}/.ssh/{{ gcp_deploy_user}}_github_rsa
permissions: 600
owner: {{ gcp_deploy_user }}
content: |
{{ machineuser_key }}
该模板任务的输出:
write_files:
- path: /home/omegasphinx/.ssh/omegasphinx_github_rsa
permissions: 600
owner: omegasphinx
content: |
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
...
我知道 blockinfile
是一个推荐的模块,当有人想写一个配置文件时,我应该使用 。但是当我做这些事情的时候,它仍然包裹着ssh key的内容。 blockinfile
任务如下所示:
- name: add ssh private key to cloud-init file
local_action:
module: ansible.builtin.blockinfile
path: cloud_config.yml
mode: 0440
insertafter: "# machineuser_ssh_block"
block: |2
- path: /home/{{ gcp_deploy_user }}/.ssh/{{ gcp_deploy_user}}_github_rsa
permissions: 600
owner: {{ gcp_deploy_user }}
content: |
{{ machineuser_key }}
tags: ['containers', 'containers:configuration']
.j2
模板如下所示:
write_files:
# machineuser_ssh_block
输出看起来像这样(完全一样):
write_files:
- path: /home/omegasphinx/.ssh/omegasphinx_github_rsa
permissions: 600
owner: omegasphinx
content: |
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
...
我尝试过的其他事情:
我在我的编辑器中禁用了制表符到空格,然后在 machineuser_key
变量
中的每行 ssh 密钥之前添加了制表符
文档说“您可以通过在块的开头放置加号 (+) 来手动禁用 lstrip_blocks 行为”;所以我添加了一个块,然后在块内缩进了变量:
{%+ if machineuser_key is defined %}
{{ machineuser_key }}
{% endif %}
我对 Jinja2 中空格的理解:
给你一些关于我期待发生的事情的背景。 Jinja 文档的“Whitespace Control”部分指出“如果存在单个尾随换行符,则将被删除”,但“其他空格(空格、制表符、换行符等)将原封不动地返回。”在我的例子中,我有“其他空白”:变量 machineuser_key
每一行左侧的空格。但显然我错过了一些东西。
据我从你的问题中可以看出,干扰你结果的不是 jinja 空格控制,而是 machineuser_key
本身嵌入了换行符;许多 helm 图表都有同样的问题,这使您可以利用相同的解决方法:
- 利用 YAML 是 JSON
的超集这一事实
- 使用
indent
filter 让您和 YAML 块在同一页面上
JSON 作为 YAML 方法
- path: /home/{{ gcp_deploy_user }}/.ssh/{{ gcp_deploy_user}}_github_rsa
permissions: 600
owner: {{ gcp_deploy_user }}
content: {{ machineuser_key | to_json }}
导致
owner: gcpawesomeuser
content: "-----BEGIN OPENSSH PRIVATE KEY-----\nb3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn\nETC ETC ETC\n"
使用缩进过滤器
- path: /home/{{ gcp_deploy_user }}/.ssh/{{ gcp_deploy_user}}_github_rsa
permissions: 600
owner: {{ gcp_deploy_user }}
content: |
{{ machineuser_key | indent(2) }}
# with the (2) matching the number of spaces under "content" where the mustaches start
生产:
owner: gcpawesomeuser
content: |
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
ETC ETC ETC
换句话说,我希望将来自 Ansible 变量的内容写入配置文件中的特定“列”,并且我不希望该内容被包装。
任务:
- name: build cloud-init file
local_action:
module: ansible.builtin.template
src: cloud_config.j2
dest: ./cloud_config.yml
mode: 0640
tags: ['containers', 'containers:configuration']
保存在库文件中的变量:
machineuser_key: |
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
...
模板:
write_files:
{# ssh config to allow our deployment user to fetch the Ansible repo #}
{# See https://docs.github.com/en/developers/overview/managing-deploy-keys#machine-users #}
- path: /home/{{ gcp_deploy_user }}/.ssh/{{ gcp_deploy_user}}_github_rsa
permissions: 600
owner: {{ gcp_deploy_user }}
content: |
{{ machineuser_key }}
该模板任务的输出:
write_files:
- path: /home/omegasphinx/.ssh/omegasphinx_github_rsa
permissions: 600
owner: omegasphinx
content: |
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
...
我知道 blockinfile
是一个推荐的模块,当有人想写一个配置文件时,我应该使用 blockinfile
任务如下所示:
- name: add ssh private key to cloud-init file
local_action:
module: ansible.builtin.blockinfile
path: cloud_config.yml
mode: 0440
insertafter: "# machineuser_ssh_block"
block: |2
- path: /home/{{ gcp_deploy_user }}/.ssh/{{ gcp_deploy_user}}_github_rsa
permissions: 600
owner: {{ gcp_deploy_user }}
content: |
{{ machineuser_key }}
tags: ['containers', 'containers:configuration']
.j2
模板如下所示:
write_files:
# machineuser_ssh_block
输出看起来像这样(完全一样):
write_files:
- path: /home/omegasphinx/.ssh/omegasphinx_github_rsa
permissions: 600
owner: omegasphinx
content: |
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
...
我尝试过的其他事情:
我在我的编辑器中禁用了制表符到空格,然后在
中的每行 ssh 密钥之前添加了制表符machineuser_key
变量文档说“您可以通过在块的开头放置加号 (+) 来手动禁用 lstrip_blocks 行为”;所以我添加了一个块,然后在块内缩进了变量:
{%+ if machineuser_key is defined %}
{{ machineuser_key }}
{% endif %}
我对 Jinja2 中空格的理解:
给你一些关于我期待发生的事情的背景。 Jinja 文档的“Whitespace Control”部分指出“如果存在单个尾随换行符,则将被删除”,但“其他空格(空格、制表符、换行符等)将原封不动地返回。”在我的例子中,我有“其他空白”:变量 machineuser_key
每一行左侧的空格。但显然我错过了一些东西。
据我从你的问题中可以看出,干扰你结果的不是 jinja 空格控制,而是 machineuser_key
本身嵌入了换行符;许多 helm 图表都有同样的问题,这使您可以利用相同的解决方法:
- 利用 YAML 是 JSON 的超集这一事实
- 使用
indent
filter 让您和 YAML 块在同一页面上
JSON 作为 YAML 方法
- path: /home/{{ gcp_deploy_user }}/.ssh/{{ gcp_deploy_user}}_github_rsa
permissions: 600
owner: {{ gcp_deploy_user }}
content: {{ machineuser_key | to_json }}
导致
owner: gcpawesomeuser
content: "-----BEGIN OPENSSH PRIVATE KEY-----\nb3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn\nETC ETC ETC\n"
使用缩进过滤器
- path: /home/{{ gcp_deploy_user }}/.ssh/{{ gcp_deploy_user}}_github_rsa
permissions: 600
owner: {{ gcp_deploy_user }}
content: |
{{ machineuser_key | indent(2) }}
# with the (2) matching the number of spaces under "content" where the mustaches start
生产:
owner: gcpawesomeuser
content: |
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
ETC ETC ETC