Issues with cloud-config on CentOS 7

May 9, 2018 1.4k views
Configuration Management CentOS

I'm trying to use a cloud-config.yml file to automatically configure a few basic tasks when I provision a new droplet, currently though only some steps work, others partly work, and others fail completely and looking at /var/log/clioud-init.log and /var/log/cloud-init-output.log I'm not really sure why it's failing.

#cloud-config
packages:
  - zsh
  - vim-enhanced
users:
  - name: jsmith
    groups: wheel
    shell: /usr/bin/zsh
    sudo: ['ALL=(ALL) NOPASSWD:ALL']
    ssh_authorized_keys:
      - (my ssh key)
chpasswd:
  list: |
    jsmith:(password sanitized)
  expire: False
write_files:
  - path: /home/jsmith/.my.cnf
    owner: "jsmith:jsmith"
    permissions: 0400
    content: |
      [client]
      user=root
      password=''
runcmd:
  - [ sed, -i, -e, 's/#PermitRootLogin yes/PermitRootLogin no/g', /etc/ssh/sshd_config ]
  - systemctl restart sshd

For the above script only the users section runs fully, so I have a user account created trying to use a shell that failed to get installed for it login shell, I can not tell if the chpasswd failed or not as I can't login due to ZSH failing to get installed by cloud-init. The write_files command partly works, the only thing that fails is it fails to correctly chown the file after creation (probably due to how it's quoted?). The runcmd hook the sed command does fail, but I'm not sure if the systemcl call failed (I could have checked it's logs to see if it was restarted but kind of lower priority to the other things).

Anyone with more experience with working with cloud-config know what I'm doing wrong or what's going on?

1 Answer

Hi! I attempted to replicate the issues you are seeing by creating a brand new CentOS 7 droplet using your cloud-init configuration (adding my own ssh-key and password but otherwise changing nothing).

Immediately after creation I was able to log in using the root account ssh key that I provided via the UI to watch cloud-init.log as the rest of the process completed with no errors.

I was then able to log in as the user jsmith using the key I provided.

The only thing that I can think of as a potential cause of the problem you encountered is if your ssh-key included any linebreaks that could cause the config to be parsed incorrectly.

  • Sorry you missed a very crucial step of my cloud init, I can get to that same point as well, but that is not the end result that I want. In the cloud init script that provided it should disable root login via SSH, add SSH key to the user that it created and I should be able ssh as that unprivileged user not root. This is not the case as those steps are failing to be ran by cloud init.

    Also my SSH key is correctly parsed by cloud init and added to the authorized_key file for the created user, but because cloud init fails to install the desired login shell (ZSH) that user account is effectively useless without manually sshing into the box as root and manually preforming the tasks that cloud init should have done.

    • That is very odd. You were correct about my testing as I failed to check a few steps. I've just run this test again with the following:

      • Changed password='' to reflect a password to use for the jsmith user
      • Added my ssh public key in place of - (my ssh key)
      • Created the droplet with no defined root ssh key

      It took a couple minutes for the cloud-init process to complete but I was then able to log in with my ssh key as jsmith and tested that sudo permissions were set properly.

      I then checked /etc/ssh/sshd_config and found that PermitRootLogin was properly set to "no"

      Attempting to log in as root presented a password prompt but did not allow login using the emailed password. Confirmed that the emailed password was correct by running su root from the jsmith account (which prompted the first login password change prompt for root).

      Unfortunately you've got me stumped as this cloud-init configuration appears to function properly in my testing.

      • One thing I forgot to note. zsh was properly installed in my test and set as the default shell for the jsmith user account.

      • I think I narrowed down my issue to the version of the cloud-init package that comes on the CentOS 7.4 image I used.

        If I add package_upgrade: true to the top of my cloud config yaml (implying it should run first from my understanding) and try again I don't see any change, but if I SSH into the droplet do a yum update (which includes an update to the cloud-init package) and reboot, when the VM comes back up, SSH as root is disallowed, zsh in installed which means I'm able to login as the unprivileged user with my SSH key.

        • Rather than use sed to modify files I find it easier to just swap in the file I want.

          In Ruby like sudo code:

          def user_data
            cfgfile_path = '/path/to/where/you want/the/file/to/go'
            <<~MYFILE
            runcmd:
              - mv #{cfgfile_path} #{cfgfile_path}.original
            write_files:
              - path: #{cfgfile_path}
                content: |
                    # my cfgfile content 
            runcmd:
              - systemctl restart my_service
            MYFILE
          end
          

          This works with the cloud-init version provided with the DO CentOS 7.4 image.

          Doing it this way has the advantage of making the new configuration explicit when reading the code.

Have another answer? Share your knowledge.