User Tools

Site Tools


devops:vagrant

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
devops:vagrant [2023/11/01 07:15] – removed - external edit (Unknown date) 127.0.0.1devops:vagrant [2024/06/22 16:41] (current) – [Error: Authentication failure. Retrying...] skipidar
Line 1: Line 1:
 +====== Vagrant======
 +By Hashicorp.
 +
 +== Workflow ==
 +
 +{{http://czerasz.com/assets/1441437275524/img/posts/vagrant-workflows-phases.png}}
 +
 +
 +==Overview commands==
 +
 +<code>
 +box - manage "boxes"
 +destroy - shut down the VM then delete its stored image?
 +gem
 +halt - shut down the VM
 +init - prepare a directory with a new Vagrantfile
 +package - shut down the VM, then convert it to a 'package' which can be turned into a box? (Or something)
 +provision - run just the provisioning (eg, Chef, Puppet...) stage
 +reload - modify the VM configuration (eg, reapply Vagrantfile), reboot the VM, reprovision the modified parts of the vagrantfile
 +resume - un-suspend (ie, unhibernate)
 +ssh - open an SSH shell connection to the VM
 +ssh-config
 +status
 +suspend - hibernate the VM
 +up - some or all of: copy a VM image to create a new VM, apply configuration to it, boot it
 +</code>
 +
 +
 +
 +
 +===== Vagrantfile =====
 +
 +The variable from outside the provisioning block can be accessed as 
 +<code>
 +"#{PATH_VAGRANT}"
 +</code>
 +
 +The ENvironment Varialbe from the host can be accessed as. This is the way to pass infos to the vagrantfile from the host system. Into the provisioner it then may be passed in as a vagrant variable
 +<code>
 +  GIT_USERNAME=ENV['GIT_USERNAME']
 +
 +  # Use shell script to provision
 +  config.vm.provision "shell", inline: <<-SHELL
 +  
 +    echo "#{PATH_VAGRANT}"
 +  SHELL
 +</code>
 +
 +Getting the path to the folder of the vagrantfile e.g. in order to copy files from the relative location to the vm.
 +
 +<code>
 +  PATH_VAGRANT=File.dirname(__FILE__)
 +
 +  # Use shell script to provision
 +  config.vm.provision "shell", inline: <<-SHELL
 +
 +    # echo the full path
 +    echo -e "Source:     #{PATH_VAGRANT}\.aws\config"
 +  SHELL
 +</code>
 +
 +
 +Copying files is done with an own provisioner
 +
 +<code>
 +PATH_VAGRANT=File.dirname(__FILE__)
 +
 +
 +# upload the AWS configs
 +config.vm.provision "file", source: "#{PATH_VAGRANT}\\.aws\\config", destination: "~/.aws/config"
 +config.vm.provision "file", source: "#{PATH_VAGRANT}\\.aws\\credentials", destination: "~/.aws/credentials"
 +config.vm.provision "file", source: "#{PATH_VAGRANT}\\.aws\\answerfile", destination: "~/.aws/answerfile"
 +
 +</code>
 +
 +
 +
 +=== Escaping ===
 +
 +The escapes, e.g. echo of quotes - must be escaped double times : <code>\\"</code>
 +
 +
 +<code>
 +docker exec tomcat8 bash -c "echo -e '<role rolename=\\"manager-gui\\"/>' >> /usr/local/tomcat/conf/tomcat-users.xml"
 +</code>
 +
 +
 +
 +===== Box =====
 +
 +Howto create a new box
 +
 +<code>
 +# list vms
 +vboxmanage list vms
 +
 +# make sure its the correct one
 +vboxmanage showvminfo vagrant_default_1566982938109_10062
 +
 +# create a new box
 +vagrant package --base vagrant_default_1566982938109_10062  --output devenv.v190819.box
 +
 +# add box to the known boxes
 +vagrant box add devenv.v190819 devenv.v190819.box
 +
 +# list boxes and see the new box added to vagrant
 +vagrant box list
 +</code>
 +
 +Now you can reference the new box
 +<code>
 +# reference the new box
 +...
 +Vagrant.configure("2") do |config|
 + config.vm.box = "myjenkins"
 +...
 +
 +</code>
 +
 +
 +===== Deleting VMs ======
 +
 +<code>
 +vboxmanage list vms
 +</code>
 +
 +<code>
 +"<inaccessible>" {5642f0cb-6042-486f-8ea6-7443cb5815b7}
 +"Jenkins-Vagrant_default_1507401281630_21314" {8e3fd4ba-cda9-4539-9781-bbf7ad4fe423}
 +</code>
 +
 +<code>
 +vvboxmanage unregistervm Jenkins-Vagrant_default_1507401281630_21314 --delete
 +vboxmanage unregistervm Jenkins-Vagrant_default_1507401281630_21314 --delete
 +</code>
 +
 +
 +===== Commands ======
 +
 +<code>
 +# clear the global-status cache, if a machine shows up, which is not running
 +global-status --prune
 +
 +</code>
 +
 +
 +===== Plugins ======
 +The complete list: https://github.com/hashicorp/vagrant/wiki/Available-Vagrant-Plugins
 +
 +===VBox additions===
 +
 +VBox additions installation. To enable folder mounting on any OS.
 +<code>
 +vagrant plugin install vagrant-vbguest
 +vagrant vbguest
 +</code>
 +
 +Winnfsd - helps handling NFS mounting problems on WIndows.
 +<code>
 +vagrant plugin install vagrant-winnfsd
 +</code>
 +
 +
 +===VBox SCP ===
 +To copy files from the host to the guest.
 +
 +<code>
 +vagrant plugin install vagrant-scp
 +</code>
 +
 +
 +===== Shell Provisioner ======
 +
 +Echo multiple lines
 +<code>
 +mkdir -p /home/vagrant/.docker/
 +echo -e "
 +{
 + \"proxies\":
 + {
 +   \"default\":
 +   {
 + \"httpProxy\": \"http://localhost:8500\",
 +   }
 + }
 +}
 +" > /home/vagrant/.docker/config.json
 +
 +</code>
 +
 +
 +===== Connect via putty  ======
 +Those scripts will use the vagrant configuration output,
 +to connect to the vagrant machine via putty.
 +
 +The normal way would be to install the special plugin, made for that :)
 +<code>
 +vagrant install plugin vagrant-multi-putty 
 +vagrant putty
 +</code>
 +
 +
 +If you want to go the long way, you can write an own script to do so
 +
 +The putty client supports the full color palette and so has a better UX, than the CMD.
 +
 +Put those files to that folder on the path, e.g. near the "vagrant.exe"
 +
 +
 +**vagrantssh.ps1** \\
 +A script to start the putty client and connect to the vagrant machine
 +<code>
 +$puttypath="D:\Programme\Putty\putty.exe"
 +$vagrantProjectConfigs = & vagrant.exe ssh-config
 +
 +# parse the vagrant configs
 +$port = ( $vagrantProjectConfigs | Select-String -Pattern "Port" -SimpleMatch  ) -replace '^[ ]*Port[ ]+(.+)[ ]*', '$1'
 +$identityfile = ( $vagrantProjectConfigs | Select-String -Pattern "IdentityFile" -SimpleMatch  ) -replace '^[ ]*IdentityFile[ ]+(.+)[ ]*', '$1'
 +$hostName = ( $vagrantProjectConfigs | Select-String -Pattern "HostName" -SimpleMatch  ) -replace '^[ ]*HostName[ ]+(.+)[ ]*', '$1'
 +
 +& $puttypath vagrant@$hostName -pw vagrant -P $port -i "$identityfile"
 +</code>
 +
 +
 +**vagrantssh.bat** \\
 +A helper, to call the powershell script above.
 +<code>
 +PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& '%~dp0/vagrantssh.ps1'"
 +</code>
 +
 +
 +===== Useful plugins  ======
 +Listed here https://github.com/hashicorp/vagrant/wiki/Available-Vagrant-Plugins
 +<code>
 +vagrant install plugin vagrant-multi-putty 
 +vagrant install plugin vagrant-scp
 +vagrant install plugin vagrant-proxy
 +</code>
 +
 +
 +
 +===== SSH Tunneling from Vagrant to host  ======
 +
 +
 +you can create a tunnel exposing it on the host machine 
 +
 +First forward the ports on Vagrant to Host.
 +This makes the guest-port of vm 4440
 +available on host port 4440
 +<code>
 +
 +    # forwarding ports
 +    config.vm.network "forwarded_port", guest: 4441, host: 4441 # rundeck
 +
 +</code>
 +
 +
 +Then establish a tunnel.
 +Establishing a tunnel from port 4440 on guest vm 
 +to remote machine i-012412412ASF2.
 +
 +<color #ed1c24>The important part here - is NOT to omit the ip, setting it to 0.0.0.0, 
 +so that the ssh tunnel gets exposed on all network adapters, not only localhost
 +and so can be reached from host</color>
 +
 +<code>
 +ssh ec2-user@i-012412412ASF2 -i ~/.ssh/ec2key.priv.openssh.ppk -fNTC -L 0.0.0.0:4441:localhost:4440
 +</code>
 +
 +
 +
 +
 +{{https://s3.eu-central-1.amazonaws.com/alf-digital-wiki-pics/sharex/MV2akxXqdD.png}}
 +
 +Now you can reach your rundeck application on host under: 
 +**localhost:4441**
 +
 +which redirects to guest-vm port:
 +**localhost:4441**
 +
 +which redirects, via the ssh-tunnel to remote server i-012412412ASF2:
 +**i-012412412ASF2:4440**
 +
 +
 +
 +In this example the session-manager is involved to create the tunnel, this part is optional
 +see https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-getting-started-enable-ssh-connections.html
 +
 +
 +
 +===== Setting up Rsync folder-synch on Windows =====
 +
 +=== Why ===
 +When **developing code** in an **IDE on Windows-Host** \\
 +I would like to have the possibility 
 +of running code in the Guest-VM. In an environment as close to the deployment as possible: \\
 +e.g. on Kubernetes, integrated with other containers.
 +
 +**File-system watcher:**
 +
 +Requirement:
 +
 +On the Guest - the changes of "file-system" of code-project must be recognized\\
 +and the code-project rebuilt. \\
 +
 +Also changes in the **IDE on Windows-Host** \\ 
 +must trigger changes on the file-system in "Guest-VM". \\
 +
 +Problem:
 +
 +When sharing a code-project via **Oracle-Virtualbox shared-folders** \\
 +and files where changed on **IDE on Windows-Host** \\
 +unfortunately, **NO changes where triggered** on **Guest** file-system-watcher.
 +
 +When sharing a code-project via **Rsync**  - the requirement was fulfilled.
 +
 +
 +=== How ===
 +An example of setting up the environment
 +
 +  *   On Guest. Install Cygwin, to get Rsync on Windows
 +  *   On Guest. Add the "code-project-folder" to the same folder, where "Vagrantfile" is located
 +  *   Configure Vagrantfile to sync "code-project-folder"
 +  *   On Guest. Run automatic sync command in one cmd-shell
 +  *   Ssh into Vagrant. Run continuos build in one shell
 +  *   Configure the Spring Boot application to hot-deploy changes
 +  *   Ssh into Vagrant. Run application like Spring Boot application
 +
 +
 +== On Guest. Install Cygwin, to get Rsync on Windows ==
 +
 +<code>
 +winget install -e --id Cygwin.Cygwin
 +</code>
 +
 +
 +==On Guest. Add the "code-project-folder" to the same folder, where "Vagrantfile" is located==
 +
 +<code>
 +cd "VagrantProjectFolder"
 +mkdir "spring-boot-code-project-folder"
 +</code>
 +
 +
 +==Configure Vagrantfile to sync "code-project-folder"==
 +Sync folder `spring-boot-code-project-folder`.
 +Based on `checksum`, not timestamp.
 +
 +Vagrantfile
 +<sxh ruby>
 +...
 + config.vm.synced_folder "./spring-boot-code-project-folder", "//mnt/spring-boot-code-project-folder/", 
 + type: "rsync", 
 + rsync__auto: true,
 + rsync__args: ["--verbose", "--ignore-times", "--checksum", "--rsync-path='rsync'", "--archive", "--delete", "-z"],
 + id: "spring"
 +
 +..
 +</sxh>
 +
 +
 +==On Guest. Run automatic sync command in one cmd-shell==
 +
 +Open a new [[https://apps.microsoft.com/store/detail/windows-terminal/9N0DX20HK701?hl=de-ch&gl=ch| Windows-Terminal ]] Tab and run the continuous sync in there:
 +<sxh shell>
 +vagrant rsync-auto
 +</sxh>
 +
 +{{https://s3.eu-central-1.amazonaws.com/alf-digital-wiki-pics/sharex/kSQKOKRZ1C.png}}
 +
 +
 +==Ssh into Vagrant. Run continuos build in one shell==
 +
 +See https://docs.gradle.org/current/userguide/command_line_interface.html#sec:continuous_build
 +
 +Skip the tests.\\
 +Dont use the daemon.
 +
 +<sxh shell>
 +vagrant ssh
 +cd "/mnt/spring-boot-code-project-folder"
 +./gradlew build -xtest --no-daemon --continuous
 +</sxh>
 +
 +
 +== Configure the Spring Boot application to hot-deploy changes ==
 +
 +The Spring boot applications needs to be advised, \\
 +to take up any rebuilt app and hot-deploy it.
 +
 +Add dependency to "devtools".
 +
 +build.gradle
 +<sxh>
 +dependencies {
 +
 + // makes Spring boot hot swap rebuilt jar to tomcat
 + developmentOnly 'org.springframework.boot:spring-boot-devtools'
 +}
 +</sxh>
 +
 +
 +==Ssh into Vagrant. Run application like Spring Boot application==
 +
 +
 +<sxh shell>
 +vagrant ssh
 +cd "/mnt/spring-boot-code-project-folder"
 +./gradlew bootRun --args='--server.port=8888'
 +</sxh>
 +
 +{{https://s3.eu-central-1.amazonaws.com/alf-digital-wiki-pics/sharex/YuluwvPA2V.png}}
 +
 +
 +===== Error: Authentication failure. Retrying... =====
 +
 +Thats also the reason for disk /mnt/d not being mounted correctly
 +
 +<sxh shell>
 +
 + # give the home permissions back to vagrant 
 + # without that -  /home/vagrant is owned by root. 
 + # and also /home/vagrant/.ssh/authorized_keys
 + # so that no ssh connection works and 
 + # vagrant ssh - failes with "Error: Authentication failure. Retrying..."
 + sudo chown -R vagrant:vagrant "/home/vagrant"
 +</sxh>