9

I'm trying to get a cloud config script working properly with my DigitalOcean droplet, but I'm testing on local lxc containers in the interim.

One consistent problem I have is that I can never get the write_files directive working properly for more than one file. It seems to behave in weird ways that I cannot understand.

For example, this configuration is incorrect, and only outputs a single file (.tarsnaprc) in /tmp:

#cloud-config
users:
  - name: julian
    shell: /bin/bash
    ssh_authorized_keys:
      - ssh-rsa myrsakeygoeshere julian@hostname
write_files:
  - path: /tmp/.tarsnaprc
    permissions: "0644"
    content: |
      cachedir /home/julian/tarsnap-cache
      keyfile /home/julian/tarsnap.key
      nodump
      print-stats
      checkpoint-bytes 1G
    owner: julian:julian
  - path: /tmp/lxc
    content: |
      lxc.id_map = u 0 100000 65536
      lxc.id_map = g 0 100000 65536
      lxc.network.type = veth
      lxc.network.link = lxcbr0
    permissions: "0644"

However, if I swap the two items in the write_files array, it magically works, and creates both files, .tarsnaprc and lxc. What am I doing wrong, do I have a syntax error?

Julian H. Lam
  • 25,501
  • 13
  • 46
  • 73

3 Answers3

11

It may be too late, as it was posted 1 year ago. The problem is setting the owner in /tmp/.tarsnaprc as the user does not exist when the file is created. Check cloud-init: What is the execution order of cloud-config directives? answer that clearly explains the order of cloud-config directives.

Community
  • 1
  • 1
rvelaz
  • 553
  • 7
  • 14
  • I might have missed it, but I didn't find a error in the logs about this, but as you said removing owner solved the issue I had. – Peter Feb 23 '23 at 15:58
5

Do not write files under /tmp during boot because of a race with systemd-tmpfiles-clean that can cause temp files to get cleaned during the early boot process. Use /run/somedir instead to avoid race LP:1707222.

ref: https://cloudinit.readthedocs.io/en/latest/topics/modules.html#write-files

Christian
  • 27,509
  • 17
  • 111
  • 155
2

Came here because of using canonicals multipass. Nowadays the answers of @rvelaz and @Christian still hint to the right direction. The corrected example whould look like this:

#cloud-config
users:
  - name: julian
    shell: /bin/bash
    ssh_authorized_keys:
      - ssh-rsa myrsakeygoeshere julian@hostname
write_files:
  # not writing to /tmp
  - path: /data/.tarsnaprc
    permissions: "0644"
    content: |
      cachedir /home/julian/tarsnap-cache
      keyfile /home/julian/tarsnap.key
      nodump
      print-stats
      checkpoint-bytes 1G
  # at execution time, this owner does not yet exist (see runcmd)
  #   owner: julian:julian
  - path: /data/lxc
    content: |
      lxc.id_map = u 0 100000 65536
      lxc.id_map = g 0 100000 65536
      lxc.network.type = veth
      lxc.network.link = lxcbr0
    permissions: "0644"
runcmd:
  - "chown julian:julian /data/lxc /data/.tarsnaprc"
mbwmd
  • 56
  • 4