My First Cloud-Init Scripts

By Paul Heinlein | Mar 4, 2016 (updated Jul 20, 2016 )

I’ve been playing with OpenStack at work, getting ready for a pilot project that, if approved, will launch in a couple weeks. I hope to have more entries on OpenStack installation, configuration, and usage later. Today, however, I began experimenting with cloud-init scripting and customizing a stock OpenStack VM image.

I found that preconfiguring user accounts is always useful and sometimes necessary, depending on who produced the base cloud image.

Whitespace

The cloud-init interpreter reads YAML, a text-based data format. It’s worth noting that YAML treats leading whitespace as significant. The indentations in the examples below aren’t just visual hygiene; they’necessary for parsing.

If you’re unsure of your formatting, you can use an online parser like YAML Lint to test all or part of your markup.

CentOS

My initial starting point was the official CentOS 7 image. My goals for the customized VM were

In the OpenStack Dashboard GUI, I launched a new instance using the CentOS image. As part of the process, I pointed the launcher at my configuration file:

#cloud-config
users:
  - name: heinlein
    gecos: Paul Heinlein
    sudo: ['ALL=(ALL) NOPASSWD:ALL']
    groups: wheel
    ssh-authorized-keys:
      - ssh-rsa AAAAB3NzaC1...1234 work-key
      - ssh-rsa AAAAB3NzaC1...5678 home-key

# use package mirror at Portland State; it's the fastest one available
write_files:
  - path: /etc/yum.repos.d/CentOS-Base.repo
    owner: root:root
    permissions: '0444'
    content: |
      # installed by cloud-init
      [base]
      name=CentOS-$releasever - Base
      baseurl=http://mirrors.cat.pdx.edu/centos/$releasever/os/$basearch/
      gpgcheck=1
      gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
      #released updates 
      [updates]
      name=CentOS-$releasever - Updates
      baseurl=http://mirrors.cat.pdx.edu/centos/$releasever/updates/$basearch/
      gpgcheck=1
      gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
      #additional packages that may be useful
      [extras]
      name=CentOS-$releasever - Extras
      baseurl=http://mirrors.cat.pdx.edu/centos/$releasever/extras/$basearch/
      gpgcheck=1
      gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7

# update all installed packages
package_upgrade: true

# install Apache and PostgreSQL
packages:
  - httpd
  - php
  - postgresql
  - postgresql-server

# install puppet (and dependencies); make sure apache and postgres
# both start at boot-time
runcmd:
  - [ yum, "-y", install, "http://mirrors.cat.pdx.edu/epel/7/x86_64/e/epel-release-7-5.noarch.rpm" ]
  - [ yum, "-y", install, "https://yum.puppetlabs.com/puppetlabs-release-el-7.noarch.rpm" ]
  - [ yum, "-y", install, puppet ]
  - [ postgresql-setup, initdb ]
  - [ systemctl, enable, httpd.service ]
  - [ systemctl, start, httpd.service ]
  - [ systemctl, enable, postgresql.service ]
  - [ systemctl, start, postgresql.service ]

The VM in question doesn’t have a connection to our local puppet master, so installing puppet was mostly for the sake of testing.

Everything went quite well. I made a snapshot of the newly configured VM and then launched several instances of it to simulate a miniature web and database farm.

Ubuntu

Things were slightly different when using the official Ubuntu cloud images. OpenStack will correctly install your SSH key into the root account, but it will get configured so that you cannot login as root. Setting up a user account with sudo privileges is absolutely necessary to use the Ubuntu image.

My goals for the Ubuntu image were simple:

#cloud-config
users:
  - name: heinlein
    gecos: Paul Heinlein
    sudo: ['ALL=(ALL) NOPASSWD:ALL']
    shell: /bin/bash
    groups: sudo
    ssh-authorized-keys:
      - ssh-rsa AAAAB3NzaC1...1234 work-key
      - ssh-rsa AAAAB3NzaC1...5678 home-key

package_upgrade: true

packages:
  - apache2
  - aptitude