This repository has been archived by the owner on Oct 18, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 4
/
Vagrantfile
269 lines (230 loc) · 11.3 KB
/
Vagrantfile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
# -*- mode: ruby -*-
# vi: set ft=ruby :
# Some features used in this configuration file require specific version of
# Vagrant.
Vagrant.require_version ">= 2.2.6"
# Vagrant API version.
VAGRANTFILE_API_VERSION = "2"
# Set base path.
VM_BASE_PATH = File.dirname(__FILE__)
# Draft package base path.
DRAFT_BASE_PATH = File.dirname(__FILE__)
# Project base path.
PROJECT_BASE_PATH = DRAFT_BASE_PATH unless defined? PROJECT_BASE_PATH
# Include configuration.
require "#{VM_BASE_PATH}/provisioning/src/configuration"
# Initialize configuration.
#
# Configuration settings are being loaded from YAML file(s).
#
# Default configuration is being stored in vm-settings.yml.
# Local overrides should be placed in vm-settings.local.yml.
#
# Settings are being merged recursively. Values from local settings file
# overwrites ones from the default settings; missing values are not being touch;
# new values will be added to the resulting settings hash.
configuration = Configuration.new(PROJECT_BASE_PATH, DRAFT_BASE_PATH)
# Before we start: auto-install recommended plugins. Code borrowed here:
# https://github.com/hashicorp/vagrant/issues/8055#issuecomment-403171757
required_plugins = configuration.get("vagrant.plugins")
# Remove Vagrant WinNFSd on non-Windows hosts.
require "rbconfig"
if (RbConfig::CONFIG["host_os"] !~ /cygwin|mswin|mingw|bccwin|wince|emx/)
required_plugins.delete_if { |name| name == 'vagrant-winnfsd' }
end
return if !Vagrant.plugins_enabled?
plugins_to_install = required_plugins.select { |plugin| !Vagrant.has_plugin? plugin }
unless plugins_to_install.empty?
puts "Installing plugins: #{plugins_to_install.join(' ')}"
if system "vagrant plugin install #{plugins_to_install.join(' ')}"
exit system "vagrant #{ARGV.join(' ')}"
else
abort "Installation of one or more plugins has failed. Aborting."
end
end
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
# Boxes
#
# Box is a package format for Vagrant environments. See more at
# http://docs.vagrantup.com/v2/boxes.html
#
# HashiCorp provides publicly available list of Vagrant boxes at
# https://app.vagrantup.com/boxes/search
# Set box and box version.
config.vm.box = configuration.get("vagrant.box")
config.vm.box_version = configuration.get("vagrant.box_version")
config.vm.box_check_update = configuration.get("vagrant.box_check_update")
# Networking
#
# By default Vagrant doesn't require explicit network setup. However, in
# various situations this action is mandatory.
#
# See https://docs.vagrantup.com/v2/networking/index.html
# Set machine's hostname.
config.vm.hostname = configuration.get("vagrant.hostname")
# Set VM name.
config.vm.define configuration.get("virtualbox.name")
# Hosts records
#
# Configure entries in a hosts file. All users are encouraged to install
# vagrant-hostmanager plugin by running:
#
# vagrant plugin install vagrant-hostmanager
# Record HOSTNAME.test will be created.
if Vagrant.has_plugin?("vagrant-hostmanager")
config.hostmanager.enabled = true
config.hostmanager.manage_host = true
unless configuration.get("vagrant.host_aliases").empty?
config.hostmanager.aliases = configuration.get("vagrant.host_aliases")
end
end
# Network File System (NFS) requires private network to be specified when
# VirtualBox is used (due to a limitation of VirtualBox's built-in networking)
#
# See http://docs.vagrantup.com/v2/synced-folders/nfs.html
config.vm.network "private_network", ip: configuration.get("vagrant.ip_address")
# SSH settings
#
# See https://docs.vagrantup.com/v2/vagrantfile/ssh_settings.html
# Enable SSH agent forwarding
config.ssh.forward_agent = true
# Fix annoying "stdin: is not a tty" error.
#
# See https://github.com/mitchellh/vagrant/issues/1673#issuecomment-40278692
config.ssh.shell = "bash -c 'BASH_ENV=/etc/profile exec bash'"
# VirtualBox configuration
#
# VirtualBox allows for some additional virtual machine tuning. List of
# available options can be found here: http://www.virtualbox.org/manual/ch08.html
#
# See https://docs.vagrantup.com/v2/virtualbox/configuration.html
# Tune VirtualBox powered machine.
config.vm.provider :virtualbox do |v|
# Use linked clones instead of importing the base box every time.
#
# See https://www.vagrantup.com/docs/virtualbox/configuration.html#linked-clones
v.linked_clone = true
# Set VM name.
v.name = configuration.get("virtualbox.name")
# Set CPUs count.
v.cpus = configuration.get("virtualbox.cpus")
# Set memory limit (in MB).
v.memory = configuration.get("virtualbox.memory")
# Set CPU execution cap (in %).
v.customize ["modifyvm", :id, "--cpuexecutioncap", configuration.get("virtualbox.cpuexecutioncap")]
# Set VirtualBox disk size (defaults to 40Gb)
config.disksize.size = configuration.get("virtualbox.disk_size")
# Set checking for Guest Additions
v.check_guest_additions = configuration.get("virtualbox.check_guest_additions")
# Use host's resolver mechanisms to handle DNS requests.
v.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
# Allow creation of symlinks in VirtualBox shared folders (works with both
# VirtualBox shared folders and NFS).
v.customize ["setextradata", :id, "VBoxInternal2/SharedFoldersEnableSymlinksCreate/" + configuration.get("vagrant.destination_directory"), "1"]
# Enable multiple cores in Vagrant/VirtualBox.
v.customize ['modifyvm', :id, '--ioapic', 'on']
# Disable Audio.
v.customize ['modifyvm', :id, '--audio', 'none']
# Set recommended Graphics Controller.
v.customize ['modifyvm', :id, '--graphicscontroller', 'vmsvga']
# The VM is configured with console=ttyS0 as one of the kernel parameters
# (/etc/default/grub -> GRUB_CMDLINE_LINUX_DEFAULT) which causes a
# dependency with the serial port. If the serial port is enabled but not
# connected (the default state) then the boot is slow. Disabling the serial
# port makes the boot fast until something needs to be written to the port
# and that's when things get stuck. Workaround is to redirect output to the
# NULL file.
#
# See:
# - https://forums.virtualbox.org/viewtopic.php?f=6&t=92832#p448121
# - https://bugs.launchpad.net/cloud-images/+bug/1829625
v.customize ["modifyvm", :id, "--uartmode1", "file", File::NULL]
# Tune the guest additions time synchronization parameters.
# See https://www.virtualbox.org/manual/ch09.html#changetimesync
#
# Sync time every 10 seconds.
v.customize ["guestproperty", "set", :id, "/VirtualBox/GuestAdd/VBoxService/--timesync-interval", 10000]
# Adjustments if drift > 100 ms.
v.customize ["guestproperty", "set", :id, "/VirtualBox/GuestAdd/VBoxService/--timesync-min-adjust", 100]
# Sync time on restore.
v.customize ["guestproperty", "set", :id, "/VirtualBox/GuestAdd/VBoxService/--timesync-set-on-restore", 1]
# Sync time on start.
v.customize ["guestproperty", "set", :id, "/VirtualBox/GuestAdd/VBoxService/--timesync-set-start", 1]
# At 1 second drift, the time will be set and not "smoothly" adjusted.
v.customize ["guestproperty", "set", :id, "/VirtualBox/GuestAdd/VBoxService/--timesync-set-threshold", 1000]
end
# Synced Folders
#
# See https://docs.vagrantup.com/v2/synced-folders/index.html
# NFS sync method is much faster than others. It's not supported on Windows
# hosts by Vagrant itself, but there is a Vagrant plugin entitled "Vagrant
# WinNFSd" aimed to resolve this issue.
#
# Windows users are encouraged to install vagrant-winnfsd plugin by running:
#
# vagrant plugin install vagrant-winnfsd
#
# See https://docs.vagrantup.com/v2/synced-folders/nfs.html
# Configure synched folders.
config.vm.synced_folder configuration.get("vagrant.source_directory"), configuration.get("vagrant.destination_directory"), configuration.get("vagrant.synced_folder_options")
# Provisioning
#
# See https://docs.vagrantup.com/v2/provisioning/index.html
# Copy generated SSL certificate and private key to the VM.
unless configuration.get("mkcert").nil?
config.vm.provision "file", source: configuration.get("mkcert.directory") + "/.", destination: "/tmp/mkcert"
end
# Get correct path to the Ansible playbook within the machine (avoiding the
# invalid NFS exports file at the same time).
require 'pathname'
source_pathname = (Pathname.new configuration.get("vagrant.source_directory")).realpath
vm_pathname = (Pathname.new VM_BASE_PATH).realpath
# If draft environment is within the synced folder, construct correct path
# to the provisioning directory within the destination directory.
if File.fnmatch(source_pathname.to_path + "/*", vm_pathname.to_path)
ansible_provisioning_path = File.join(configuration.get("vagrant.destination_directory"), vm_pathname.relative_path_from(source_pathname), "provisioning")
# Else draft environment is not within the synced folder. In this case create
# another NFS synced folder containing the required files.
else
config.vm.synced_folder VM_BASE_PATH, "/vagrant", id: "vagrant", type: "nfs", create: true, nfs_udp: false
ansible_provisioning_path = "/vagrant/provisioning"
end
# Run Ansible provisioner from within the virtual machine using Ansible Local
# provisioner.
config.vm.provision "ansible_local" do |ansible|
ansible.become = true
ansible.playbook = "playbook.yml"
ansible.provisioning_path = ansible_provisioning_path
ansible.extra_vars = configuration.getConfiguration()
ansible.galaxy_role_file = "requirements.yml"
ansible.galaxy_roles_path = "/etc/ansible/roles"
ansible.galaxy_command = "sudo ansible-galaxy install --role-file=%{role_file} --roles-path=%{roles_path} --force"
ansible.compatibility_mode = "2.0"
ansible.install_mode = "pip_args_only"
ansible.pip_install_cmd = <<-SHELL
# Ensure that required Python packages are present.
sudo apt install python3-apt python3-distutils -y
# Install PiP.
curl https://bootstrap.pypa.io/get-pip.py | sudo python3
SHELL
# The following will not work properly since the split of Ansible into ansible-base (soon ansible-core)
# and the Ansible collections and modules both together resembling Ansible.
# `ansible --version` will yield the ansible-base version and this command is used by ansible_local.
# It is not suitable to figure out which Ansible distribution/bundle was installed.
# To workaround the wrongful mismatch result when installing Ansible through Vagrant,
# we have to leave ansible.version empty/unset and use ansible.pip_args to provide the desired version.
#
# See also:
# - https://www.ansible.com/blog/ansible-3.0.0-qa
# - https://github.com/hashicorp/vagrant/issues/12204
# - https://git.jotbe.io/jotbe/ansible-devops-vm/commit/972e6c0d87d09cca4397fc8eba0885de04046673
# ansible.version = configuration.get("ansible.version")
ansible.pip_args = "ansible==" + configuration.get("ansible.version")
end
# Display an informational message to the user.
available_hosts = [configuration.get("vagrant.ip_address"), configuration.get("vagrant.hostname")]
unless configuration.get("vagrant.host_aliases").empty?
available_hosts.concat(configuration.get("vagrant.host_aliases"))
end
config.vm.post_up_message = "The app is accessible at any of these addresses:\n - https://" + available_hosts.join("/\n - https://") + "/"
end