I am trying to use ansible
to add two lines to a configuration file for an LXC container on a Proxmox server.
I have used both blockinfile
and lineinfile
to achieve this, and it works, but subsequent runs result in the duplication of lines despite that not being the (to my understanding) expected behavior.
When using blockinfile
, the markers and block also appear in different locations in the file.
blockinfile
With this I am using a unique marker, with no newlines as per the documentation.
---
- name: Configure LXC Container
ansible.builtin.blockinfile:
path: "/etc/pve/lxc/{{ tailscale_lxc_vmid }}.conf"
marker: "# {mark} ANSIBLE MANAGED BLOCK FOR CONTAINER {{ tailscale_lxc_vmid }}"
block: |
lxc.cgroup2.devices.allow = c 10:200 rwm
lxc.mount.entry = /dev/net/tun dev/net/tun none bind,create=file
owner: root
group: www-data
mode: "0640"
insertafter: EOF
register: lxc_config_result
Running the above results in the following configuration file.
# BEGIN ANSIBLE MANAGED BLOCK FOR CONTAINER 105
# END ANSIBLE MANAGED BLOCK FOR CONTAINER 105
arch: amd64
cmode: tty
console: 1
cores: 1
cpulimit: 0
cpuunits: 1024
hostname: test
memory: 512
net0: name=eth0,bridge=vmbr0,gw=192.168.0.1,hwaddr=XX:XX:XX:XX:XX:XX,ip=192.168.0.10/24,type=veth
onboot: 1
ostype: ubuntu
protection: 0
rootfs: local-lvm:vm-105-disk-0,size=8G
swap: 512
tty: 2
unprivileged: 1
lxc.cgroup2.devices.allow: c 10:200 rwm
lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file
This seems to be bugged in some way because the marker lines are at the top of the file, and the block contents are at the end. I have tried removing insertafter
, and also setting insertafter
to unprivileged: 1
to force it to be placed in a specific location, but all three of these result in the above output.
In addition, running ansible
again duplicated the block at the end of the file.
lineinfile
Because of the above issues, I tried switching to lineinfile
.
- name: Ensure TUN device permissions
ansible.builtin.lineinfile:
path: "/etc/pve/lxc/{{ tailscale_lxc_vmid }}.conf"
line: "lxc.cgroup2.devices.allow = c 10:200 rwm"
state: present
register: group_allow_result
- name: Ensure TUN device is mounted
ansible.builtin.lineinfile:
path: "/etc/pve/lxc/{{ tailscale_lxc_vmid }}.conf"
line: "lxc.mount.entry = /dev/net/tun dev/net/tun none bind,create=file"
state: present
register: mount_result
This worked as expected, placing the two lines at the end of the file. But again, on subsequent runs, the lines are duplicated instead of being registered as already existing. I tried using the regexp
option to specify how to search for the line, in-case of whitespace issues, but got the same result.
What am I doing wrong here?
I am thinking I am going to have to result to shell commands to grep for the line and then echo it in if it’s not present. Which will work, but I would like to know what the issue is with blockinfile
and lineinfile
because I am using them elsewhere with no issue.
2
Answers
This turned out to be a Proxmox issue, not an Ansible one.
Proxmox LXC configuration files accept both
<key>: <value
and =. However, it automatically converts the latter into the former. This is why
lineinfile` was not working.I am still slightly unsure as to why
blockinfile
was producing marker lines at the top of the file and placing the block at the bottom, butlineinfile
is working as expected using the<key>: <value>
format.Based on your comment
and the documentation Anatomy of LXC Container Config File, Manual: pct.conf …
For a configuration file
105.conf
a minimal example playbook
will result into an output of
and a config file content
cat 105.conf
at the first runand for second run into
This will be the case for both syntax options, means also for INI-style
Q: "Why
blockinfile
was producing marker lines at the top of the file and placing the block at the bottom"A: This isn’t reproducible for me.