Vagrant Operations

From NovaOrdis Knowledge Base
Jump to navigation Jump to search

External

Internal

Plugin Operations

Plugin Operations

Environment Operations

Environment Operations

Box Operations

List

vagrant box list

Instance Operations

up

https://www.vagrantup.com/docs/cli/up.html

This is the essential Vagrant command. It starts and provision the vagrant environment:

vagrant up

The backing Vagrantfile can be written in such a way that bringing the machine up creates a ~/.ssh/dev/vagranthostname configuration that can be used by ssh to connect directly. This is an example of how to achieve this: Describe the VM in a Vagrantfile.

init

https://www.vagrantup.com/docs/cli/init.html
vagrant init

ssh

Connect to machine via SSH:

vagrant ssh

How does it know to connect to the instance it was started? More about jump box.


global-status

Global status of the VM:

vagrant global-status

status

vagrant status [name|id]

destroy

Stops and deletes all traces of the vagrant machine:

vagrant destroy
vagrant destroy [name|id]

If the corresponding VM runs in AWS EC2, this terminates the instance.

Managing a VM in an AWS Environment

https://github.com/mitchellh/vagrant-aws

Describe the VM in a Vagrantfile

This is an example. More details about Vagrantfile syntax in:

Vagrantfile
# frozen_string_literal: true

#
# Configuration
#

#
# It is assumed that the environment was already configured with AWS authentication (.aws/credentials or AWS
# environment variables). The VM will be created in the configured account/region.
#

ENVIRONMENT_NAME = "infra-playground"
BASTION_HOST = '1.2.3.4'
AWS_KEYPAIR = 'infra-playground'
SSH_PRIVATE_KEY = "~/.ssh/#{AWS_KEYPAIR}.pem"
SSH_CONFIG_FILE = "#{ENV['HOME']}/.ssh/dev/infra-worker"

#
# This is required by AWS CLI as part of instance provisioning call. It must the ID of the private subnet
# the instance will be attached to. If using environments, this subnet should be the default private subnet
# of the environment.
#
SUBNET_ID = 'subnet-000000000000000'

#
# This is required by AWS CLI as part of instance provisioning call. It must the ID of the security
# group that will protect the access to the instance. Access must be configuring depending on the instance
# requirements. At minimum, it should allow inbound ssh access.
#
SECURITY_GROUP_ID = 'sg-000000000000000'

#
# The AMI of the infra-worker image created by Packer
#
AMI_ID = ENV['AMI_ID'] || 'ami-0000000000000000'

INSTANCE_TYPE = 'm5.4xlarge'
VOLUME_SIZE_GB = 50

#
# Install vagrant plugin
#
# @param: plugin type: Array[String] desc: The desired plugin to install
def ensure_plugins(plugins)
  logger = Vagrant::UI::Colored.new
  result = false
  plugins.each do |p|
    pm = Vagrant::Plugin::Manager.new(
      Vagrant::Plugin::Manager.user_plugins_file
    )
    plugin_hash = pm.installed_plugins
    next if plugin_hash.key?(p)

    result = true
    logger.warn("Installing plugin #{p}")
    pm.install_plugin(p)
  end
  if result
    logger.warn('Re-run vagrant up now that plugins are installed')
    exit
  end
end

def aws_config(name)
  value = `aws configure get #{name}`.strip
  raise ArgumentError, "aws #{name} config must be set; use 'aws configure set #{name} <value>'" if value.empty?
  value
end

def username
  ENV['USER'] || 'anonymous'
end

def hostname
  "infra-worker-#{username}"
end

#
# Create and configure the AWS instance(s)
#
Vagrant.configure('2') do |config|

  ensure_plugins(%w[vagrant-aws])

  config.vm.define :infra_worker do |t|
  end

  config.vm.hostname = hostname
  #
  # Use dummy AWS box
  #
  config.vm.box = 'dummy'
  config.vm.synced_folder '.', '/vagrant', disabled: true

  #
  # Specify AWS provider configuration
  #
  config.vm.provider 'aws' do |aws, override|
    #
    # Specify SSH keypair to use, which should match SSH_PRIVATE_KEY
    #
    aws.keypair_name = AWS_KEYPAIR
    aws.instance_type = INSTANCE_TYPE
    aws.associate_public_ip = false
    aws.elastic_ip = false

    #
    # Launch configuration
    #
    aws.ami = AMI_ID
    aws.subnet_id = SUBNET_ID
    aws.security_groups = [SECURITY_GROUP_ID]
    aws.block_device_mapping = [{ 'DeviceName' => '/dev/xvda', 'Ebs.VolumeSize' => VOLUME_SIZE_GB }]
    aws.tags = {
      'Name' => hostname,
      'Created by' => username,
      'Environment' => ENVIRONMENT_NAME
    }

    #
    # Specify username and private key path
    # 
    config.ssh.forward_agent = true
    override.ssh.username = 'ec2-user'
    override.ssh.private_key_path = SSH_PRIVATE_KEY
    override.ssh.proxy_command = "ssh -o ExitOnForwardFailure=yes -W %h:%p -i #{override.ssh.private_key_path} %r@#{BASTION_HOST}"
  end

  config.trigger.after [:up] do |t|
    t.info = "Writing ssh config to #{SSH_CONFIG_FILE}"
    t.run = { path: '../_common_tools_and_config/bin/configure-ssh-access', args: [SSH_CONFIG_FILE.to_s] }
  end
end

Companion ssh configuration script configure-ssh-access'


#!/usr/bin/env bash

function usage() {

cat << EOF

Write the output of "vagrant ssh-config" to the configuration file specified as first argument.
This script is invoked as part of the "vagrant up" sequence. Various Vagrantfiles that mention
it have the path to it hardcoded.
EOF

}
function main() {

    local ssh_config_file=$1

    [[ -z ${ssh_config_file} ]] && { echo "a ssh configuration file must be specified" 1>&2; exit 1; }

    mkdir -p $(dirname ${ssh_config_file})

    #
    # Ruby won't allow for "-" in host name so we convert it here. "Host a_b" will be converted to "Host a-b".
    #
    vagrant ssh-config | sed -e 's/^\(Host.*\)_\(.*\)/\1-\2/' > ${ssh_config_file}
}

main "$@"