Skip to content

Instantly share code, notes, and snippets.

@wrouesnel
Created January 29, 2016 10:56
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wrouesnel/7718666e5736e0a4cf4d to your computer and use it in GitHub Desktop.
Save wrouesnel/7718666e5736e0a4cf4d to your computer and use it in GitHub Desktop.
Ansible VM base image builder
---
# Provisions a Debian base-image
- hosts: local
connection: local
force_handlers: True
sudo: yes
tasks:
# - name: Check environment set
# fail: msg="Configuration incompletely specified!"
# when: (server_ip is defined|bool and netmask is defined|bool and gateway is defined|ipaddr and
# image_name is defined|bool and image_size_mb is defined|bool)|bool == false
#
- name: Create a disk image
command: dd if=/dev/zero of={{ image_name }}.img bs=1 seek={{ image_size_mb }}M count=0
notify: Remove intermediate image
- set_fact: should_remove_img=True
- set_fact: image_name_img={{ image_name }}.img
- name: Creating partitions
command: /sbin/parted --script {{ image_name_img }} mklabel msdos -- mkpart primary ext4 0% 100% set 1 boot
- name: Mapping partitions
command: kpartx -s -av {{ image_name_img }}
register: mapper_output
notify: Unmap drives
- set_fact: loop_part={{ mapper_output.stdout.split()[2] }} loop_device={{ mapper_output.stdout.split()[7] }}
- name: Make filesystem
command: mkfs.ext4 /dev/mapper/{{ loop_part }}
- name: Make temporary directory
command: mktemp -d
register: tempdir
notify: Clean up temporary directory
- set_fact: mount_dir={{ tempdir.stdout }}
- name: Mount
command: mount /dev/mapper/{{ loop_part }} {{ mount_dir }}
notify: Unmount build directory
- name: Bootstrapping Image
command: debootstrap
--arch=amd64
--include=openssh-server,sudo,python,python-pip,ansible,linux-image-amd64,locales
{{ suite }} {{ mount_dir }} http://ftp.iinet.net.au/debian/debian
environment:
http_proxy: "{{ lookup('env','http_proxy') }}"
- name: Get UUID of root partition
command: blkid -s UUID /dev/mapper/{{ loop_part }}
register: blkid_out
- set_fact: root_uuid={{ blkid_out.stdout.split('"')[1] }} root_fstype=ext4
- name: Configuring fstab
template: src=templates/provisioning/fstab.j2
dest={{ mount_dir }}/etc/fstab
owner=root group=root mode=0644
- name: Configuring networking
template: src=templates/provisioning/interfaces.j2
dest={{ mount_dir }}/etc/network/interfaces
owner=root group=root mode=0644
- name: Configuring nameservers
template: src=templates/provisioning/resolv.conf.j2
dest={{ mount_dir }}/etc/resolv.conf
owner=root group=root mode=0644
- name: Setting hostname
copy: dest={{ mount_dir }}/etc/hostname content={{ hostname }} owner=root group=root node=0644
# This is necessary to admin the server in its default state.
- name: Allowing root login over SSH
lineinfile:
regexp: 'PermitRootLogin .*'
state: present
line: 'PermitRootLogin yes'
dest: '{{ mount_dir }}/etc/ssh/sshd_config'
- name: Setting root password
lineinfile:
regexp: 'root:.*'
state: present
line: 'root:{{ root_password | password_hash("sha512") }}:{{ (ansible_date_time.epoch|int) // 86400 }}:0:99999:7:::'
dest: '{{ mount_dir }}/etc/shadow'
- name: Making device map
copy:
content: "(hd0) /dev/{{ loop_device }}"
dest: "{{ mount_dir }}/device.map"
- name: Installing grub
command: >
grub-install
--no-floppy
--grub-mkdevicemap={{ mount_dir }}/device.map
--root-directory={{ mount_dir }}
--boot-directory={{ mount_dir }}/boot
{{ loop_device }}
- name: Setting grub configuration
template: src=templates/provisioning/grub.cfg.j2
dest={{ mount_dir }}/boot/grub/grub.cfg
owner=root group=root mode=0644
- set_fact: should_remove_img=False
- meta: flush_handlers
- set_fact: should_remove_img=True
handlers:
- name: Unmount build directory
command: umount {{ mount_dir }}
- name: Clean up temporary directory
file: state=absent path={{ mount_dir }}
- name: Unmap drives
command: kpartx -s -dv {{ image_name_img }}
- name: Remove intermediate image
file: state=absent path={{ image_name_img }}
when: should_remove_img
- name: Remove final image
file: state=absent path={{ image_name }}.vmdk
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment