├── requirements.yml ├── .gitignore ├── ansible └── main.yml ├── .vagrantplugins ├── jsonenv ├── scripts ├── cleanup.sh └── ansible.sh ├── Vagrantfile ├── http └── ks.cfg ├── rhel7.json └── README.md /requirements.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - src: geerlingguy.packer-rhel 3 | - src: geerlingguy.nfs 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | packer_cache/* 3 | *.box 4 | iso/* 5 | output-virtualbox-iso/* 6 | output-vmware-iso/* 7 | .vagrant/* 8 | secret.json 9 | -------------------------------------------------------------------------------- /ansible/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: all 3 | become: yes 4 | gather_facts: yes 5 | 6 | roles: 7 | - geerlingguy.nfs 8 | - geerlingguy.packer-rhel 9 | -------------------------------------------------------------------------------- /.vagrantplugins: -------------------------------------------------------------------------------- 1 | required_plugins = %w( 2 | vagrant-vbguest 3 | vagrant-registration 4 | ) 5 | 6 | needs_restart = false 7 | required_plugins.each do |plugin| 8 | unless Vagrant.has_plugin? plugin 9 | system "vagrant plugin install #{plugin}" 10 | needs_restart = true 11 | end 12 | end 13 | 14 | if needs_restart 15 | exec "vagrant #{ARGV.join' '}" 16 | end 17 | -------------------------------------------------------------------------------- /jsonenv: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # jsonenv reads a json object as input and produces 4 | # escaped shell commands for setting environment vars 5 | # source : https://gist.github.com/kr/6161118 6 | 7 | import json 8 | import pipes 9 | import sys 10 | 11 | for k, v in json.load(sys.stdin).items(): 12 | k = pipes.quote(k) 13 | v = pipes.quote(v) 14 | print "%s=%s export %s;" % (k, v, k) 15 | -------------------------------------------------------------------------------- /scripts/cleanup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -eux 2 | 3 | # Remove Ansible and its dependencies. 4 | yum -y history undo $(cat /tmp/YUM_ID) 5 | 6 | # Unregister template from RHSM 7 | subscription-manager unsubscribe --all 8 | subscription-manager unregister 9 | subscription-manager clean 10 | 11 | # Make some cleaning 12 | rm -rf /var/log/rhsm/* 13 | rm -rf /tmp/* 14 | rm -rf /var/cache/yum/* 15 | rm -rf /etc/ssh/ssh_host_* 16 | 17 | # Zero out the rest of the free space using dd, then delete the written file. 18 | dd if=/dev/zero of=/EMPTY bs=1M 19 | rm -f /EMPTY 20 | 21 | # Add double `sync` so Packer doesn't quit too early, before the large file is deleted. 22 | sync && sync 23 | -------------------------------------------------------------------------------- /scripts/ansible.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -eux 2 | 3 | # Configure repos 4 | subscription-manager register --username=${RHSM_USERNAME} --password=${RHSM_PASSWORD} --name=packer-rhel7-$(date +%Y%m%d)-${RANDOM} 5 | subscription-manager attach --pool=${RHSM_POOL} 6 | subscription-manager repos --disable=* 7 | subscription-manager repos --enable=${ANSIBLE_REPOS} --enable=rhel-7-server-rpms 8 | 9 | # Update to last patches 10 | yum -y update --setopt tsflags=nodocs 11 | 12 | # Install Ansible. 13 | yum -y install --setopt tsflags=nodocs ansible 14 | yum history package ansible|awk '/Install/ {print $1}' > /tmp/YUM_ID 15 | 16 | # Configure /tmp on tmpfs 17 | systemctl enable tmp.mount 18 | -------------------------------------------------------------------------------- /Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby : 3 | 4 | Vagrant.configure("2") do |config| 5 | config.ssh.insert_key = false 6 | config.vm.synced_folder '.', '/vagrant', type: 'nfs' 7 | 8 | # VMware Fusion. 9 | # `vagrant up vmware --provider=vmware_fusion` 10 | config.vm.define "vmware" do |vmware| 11 | vmware.vm.hostname = "rhel7-vmware" 12 | vmware.vm.box = "file://builds/vmware-rhel7.box" 13 | vmware.vm.network :private_network, ip: "192.168.3.2" 14 | 15 | config.vm.provider :vmware_fusion do |v, override| 16 | v.gui = false 17 | v.vmx["memsize"] = 1024 18 | v.vmx["numvcpus"] = 1 19 | end 20 | 21 | config.vm.provision "shell", inline: "echo Hello, World" 22 | end 23 | 24 | # VirtualBox. 25 | # `vagrant up virtualbox --provider=virtualbox` 26 | config.vm.define "virtualbox" do |virtualbox| 27 | virtualbox.vm.hostname = "virtualbox-rhel7" 28 | virtualbox.vm.box = "file://builds/virtualbox-rhel7.box" 29 | virtualbox.vm.network :private_network, ip: "172.16.3.2" 30 | 31 | config.vm.provider :virtualbox do |v| 32 | v.gui = false 33 | v.memory = 1024 34 | v.cpus = 1 35 | v.customize ["modifyvm", :id, "--natdnshostresolver1", "on"] 36 | v.customize ["modifyvm", :id, "--ioapic", "on"] 37 | end 38 | 39 | if Vagrant.has_plugin?('vagrant-registration') 40 | config.registration.manager = 'subscription_manager' 41 | config.registration.name = virtualbox.vm.hostname 42 | config.registration.username = ENV['rhsm_username'] 43 | config.registration.password = ENV['rhsm_password'] 44 | config.registration.pools = ENV['rhsm_pool'] 45 | end 46 | 47 | config.vm.provision "shell", inline: "echo Hello, World" 48 | end 49 | 50 | end 51 | -------------------------------------------------------------------------------- /http/ks.cfg: -------------------------------------------------------------------------------- 1 | install 2 | cdrom 3 | lang en_US.UTF-8 4 | keyboard us 5 | unsupported_hardware 6 | network --bootproto=dhcp 7 | rootpw vagrant 8 | firewall --enabled --ssh 9 | selinux --enforcing 10 | timezone UTC 11 | unsupported_hardware 12 | bootloader --location=mbr 13 | text 14 | skipx 15 | zerombr 16 | clearpart --all --initlabel 17 | autopart 18 | auth --enableshadow --passalgo=sha512 --kickstart 19 | firstboot --disabled 20 | eula --agreed 21 | services --enabled=NetworkManager,sshd 22 | reboot 23 | user --name=vagrant --plaintext --password vagrant --groups=vagrant,wheel 24 | 25 | %packages --ignoremissing --excludedocs 26 | @Base 27 | @Core 28 | @Development Tools 29 | openssh-clients 30 | sudo 31 | openssl-devel 32 | readline-devel 33 | zlib-devel 34 | kernel-headers 35 | kernel-devel 36 | net-tools 37 | vim 38 | wget 39 | curl 40 | rsync 41 | 42 | # unnecessary firmware 43 | -aic94xx-firmware 44 | -atmel-firmware 45 | -b43-openfwwf 46 | -bfa-firmware 47 | -ipw2100-firmware 48 | -ipw2200-firmware 49 | -ivtv-firmware 50 | -iwl100-firmware 51 | -iwl1000-firmware 52 | -iwl3945-firmware 53 | -iwl4965-firmware 54 | -iwl5000-firmware 55 | -iwl5150-firmware 56 | -iwl6000-firmware 57 | -iwl6000g2a-firmware 58 | -iwl6050-firmware 59 | -libertas-usb8388-firmware 60 | -ql2100-firmware 61 | -ql2200-firmware 62 | -ql23xx-firmware 63 | -ql2400-firmware 64 | -ql2500-firmware 65 | -rt61pci-firmware 66 | -rt73usb-firmware 67 | -xorg-x11-drv-ati-firmware 68 | -zd1211-firmware 69 | %end 70 | 71 | %post 72 | yum update -y 73 | 74 | # update root certs 75 | wget -O/etc/pki/tls/certs/ca-bundle.crt http://curl.haxx.se/ca/cacert.pem 76 | 77 | # sudo 78 | yum install -y sudo 79 | echo "vagrant ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers.d/vagrant 80 | sed -i "s/^.*requiretty/#Defaults requiretty/" /etc/sudoers 81 | 82 | yum clean all 83 | %end 84 | -------------------------------------------------------------------------------- /rhel7.json: -------------------------------------------------------------------------------- 1 | { 2 | "builders": [ 3 | { 4 | "boot_command": [ 5 | " text ks=http://{{ .HTTPIP }}:{{ .HTTPPort }}/ks.cfg" 6 | ], 7 | "boot_wait": "10s", 8 | "disk_size": 81920, 9 | "guest_additions_path": "VBoxGuestAdditions_{{.Version}}.iso", 10 | "guest_os_type": "RedHat_64", 11 | "headless": true, 12 | "http_directory": "http", 13 | "iso_checksum": "120acbca7b3d55465eb9f8ef53ad7365f2997d42d4f83d7cc285bf5c71e1131f", 14 | "iso_checksum_type": "sha256", 15 | "iso_urls": [ 16 | "iso/rhel-server-7.6-x86_64-dvd.iso" 17 | ], 18 | "shutdown_command": "echo 'vagrant'|sudo -S /sbin/halt -h -p", 19 | "ssh_password": "vagrant", 20 | "ssh_port": 22, 21 | "ssh_username": "vagrant", 22 | "ssh_wait_timeout": "10000s", 23 | "type": "virtualbox-iso", 24 | "vboxmanage": [ 25 | [ 26 | "modifyvm", 27 | "{{.Name}}", 28 | "--memory", 29 | "512" 30 | ], 31 | [ 32 | "modifyvm", 33 | "{{.Name}}", 34 | "--cpus", 35 | "2" 36 | ] 37 | ], 38 | "virtualbox_version_file": ".vbox_version", 39 | "vm_name": "packer-rhel-7-x86_64" 40 | }, 41 | { 42 | "boot_command": [ 43 | " text ks=http://{{ .HTTPIP }}:{{ .HTTPPort }}/ks.cfg" 44 | ], 45 | "boot_wait": "10s", 46 | "disk_size": 81920, 47 | "guest_os_type": "rhel7-64", 48 | "headless": true, 49 | "http_directory": "http", 50 | "iso_checksum": "60a0be5aeed1f08f2bb7599a578c89ec134b4016cd62a8604b29f15d543a469c", 51 | "iso_checksum_type": "sha256", 52 | "iso_urls": [ 53 | "iso/rhel-server-7.3-x86_64-dvd.iso" 54 | ], 55 | "shutdown_command": "echo 'vagrant'|sudo -S /sbin/halt -h -p", 56 | "ssh_password": "vagrant", 57 | "ssh_port": 22, 58 | "ssh_username": "vagrant", 59 | "ssh_wait_timeout": "10000s", 60 | "tools_upload_flavor": "linux", 61 | "type": "vmware-iso", 62 | "vm_name": "packer-rhel-7-x86_64", 63 | "vmx_data": { 64 | "cpuid.coresPerSocket": "1", 65 | "memsize": "512", 66 | "numvcpus": "2" 67 | } 68 | } 69 | ], 70 | "post-processors": [ 71 | { 72 | "output": "builds/{{.Provider}}-rhel7.box", 73 | "type": "vagrant" 74 | } 75 | ], 76 | "provisioners": [ 77 | { 78 | "environment_vars": [ 79 | "RHSM_USERNAME={{user `rhsm_username`}}", 80 | "RHSM_PASSWORD={{user `rhsm_password`}}", 81 | "RHSM_POOL={{user `rhsm_pool`}}", 82 | "ANSIBLE_REPOS={{user `ansible_repos`}}" 83 | ], 84 | "execute_command": "echo 'vagrant' | {{.Vars}} sudo -S -E bash '{{.Path}}'", 85 | "script": "scripts/ansible.sh", 86 | "type": "shell" 87 | }, 88 | { 89 | "galaxy_file": "requirements.yml", 90 | "playbook_file": "ansible/main.yml", 91 | "type": "ansible-local" 92 | }, 93 | { 94 | "execute_command": "echo 'vagrant' | {{.Vars}} sudo -S -E bash '{{.Path}}'", 95 | "script": "scripts/cleanup.sh", 96 | "type": "shell" 97 | } 98 | ] 99 | } 100 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Packer Example - Red Hat Enterprise Linux 7 Vagrant Box using Ansible provisioner 2 | 3 | This example build configuration installs and configures RHEL 7 x86_64 using Ansible, and then generates two Vagrant box files, for: 4 | 5 | - VirtualBox 6 | - VMware 7 | 8 | The example can be modified to use more Ansible roles, plays, and included playbooks to fully configure (or partially) configure a box file suitable for deployment for development environments. 9 | 10 | ## Paternity 11 | 12 | This repo is a shamelessly fork from [Jeff Geerling](https://github.com/geerlingguy/packer-centos-7), modified to create a Red Hat Enterprise Linux Vagrant Box. 13 | So all gratitude should go to him, and all criticism to myself. 14 | 15 | ## Requirements 16 | 17 | The following software must be installed/present on your local machine before you can use Packer to build the Vagrant box file: 18 | 19 | - [Packer](http://www.packer.io/) 20 | - [Vagrant](http://vagrantup.com/) 21 | - [VirtualBox](https://www.virtualbox.org/) (if you want to build the VirtualBox box) 22 | - [VMware Fusion](http://www.vmware.com/products/fusion/) (or Workstation - if you want to build the VMware box) 23 | - [Ansible](http://docs.ansible.com/intro_installation.html) 24 | 25 | You must have a Red Hat Subscription to download the Red Hat Enterprise Linux 7 iso. If you don't, [create an account](https://developers.redhat.com) and accept the terms and conditions of the Red Hat Developer Program, which provides no-cost subscriptions for development use only. 26 | 27 | ## Usage 28 | 29 | - Make sure all the required software (listed above) is installed. 30 | - cd to the directory containing this README.md file, 31 | - Create `iso/` directory and move inside your Red Hat Enterprise Linux iso. 32 | - Edit rhel7.json file, check if `iso_urls` and `iso_checksum` match your RHEL iso. 33 | - Create file secret.json, with your RHSM informations (where ansible_repos, is the repository where you can find ansible core), 34 | ``` 35 | { 36 | "rhsm_username": "XXXXXXXX", 37 | "rhsm_password" : "XXXXXXXX", 38 | "rhsm_pool" : "XXXXXXXX", 39 | "ansible_repos" : "XXXXXXXX-rpms" 40 | } 41 | ``` 42 | - Finally run: 43 | ``` 44 | $ packer build --var-file=secret.json rhel7.json 45 | ``` 46 | After a few minutes, Packer should tell you the box was generated successfully. 47 | 48 | If you want to only build a box for one of the supported virtualization platforms (e.g. only build the VMware box), add `--only=vmware-iso` to the `packer build` command: 49 | ``` 50 | $ packer build --only=vmware-iso --var-file=secret.json rhel7.json 51 | 52 | $ packer build --only=virtualbox-iso --var-file=secret.json rhel7.json 53 | ``` 54 | ## Testing built boxes 55 | 56 | ### Prerequisite 57 | 58 | The following vagrant plugins should be installed: 59 | 60 | - [vagrant-vbguest](https://github.com/dotless-de/vagrant-vbguest) 61 | - [vagrant-registration](https://github.com/projectatomic/adb-vagrant-registration) 62 | 63 | During the build of the RHEL7 box, a 'yum update' is launched. The VirtualBox Guest Additions installed are probably not the one for the newly installed kernel. So when the VM will start using this box, it will need to re-compile de VirtualBox Guest Additions. This is done using the vagrant plugins vagrant-vbguest.d 64 | 65 | Also we want to register the VM to RHSM, so we do that with vagrant-registration plugin. 66 | 67 | File .vagrantplugins make sure those vagrant plugins are installed. 68 | 69 | ### Let's roll !!! 70 | 71 | There's an included Vagrantfile that allows quick testing of the built Vagrant boxes. From this same directory, run one of the following commands after building the boxes: 72 | ``` 73 | # For VMware Fusion: 74 | $ eval $(./jsonenv < secret.json) vagrant up vmware --provider=vmware_fusion 75 | 76 | # For VirtualBox: 77 | $ eval $(./jsonenv < secret.json) vagrant up virtualbox --provider=virtualbox 78 | ``` 79 | [jsonenv](jsonenv) is a small python script stolen from [Keith Rarick](https://gist.github.com/kr/6161118) which convert a json dictionary into environment variables. 80 | 81 | ## TODO 82 | - Add registration to Satellite. 83 | 84 | ## License 85 | 86 | MIT license. 87 | 88 | ## Author Information 89 | 90 | Created in 2014 by [Jeff Geerling](http://jeffgeerling.com/), author of [Ansible for DevOps](http://ansiblefordevops.com/). 91 | Modified in 2017 by [Tinsjourney](https://www.gnali.org/) 92 | --------------------------------------------------------------------------------