Vagrant provision multiple playbooks with multiple ssh users - ssh

I'm trying to provision a vm using vagrant's ansible provisioner. But I have two playbooks and both need to use different ssh users. My use case is this, I have a pre-provisioning script that runs under the vagrant ssh user that is set up by default. My pre-provision script then adds a different ssh user provisioner that is set up to ssh onto the VM with its own key. The actual provision script has a task that deletes the insecure vagrant user on the system so it has to run as a different ssh user, provsioner, the user that the pre-provisioner creates.
I can not figure out how to change the ssh user in the Vagrantfile. Example below is how far I've gotten. Despite changing the config.ssh.username vagrant always sets the ssh user to the last value, in this case provisioner and that doesn't authenticate when running the pre-provision script because it hasn't been created yet.
Can I override the ssh user somehow? Maybe with an ansible variable itself inside the do |ansible| block (below)?
Is what I'm trying to achieve possible? It seems so straightforward I'm shocked I'm having this much trouble with it.
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.box = "base_box"
config.vm.box_url = "s3://bucket/base-box/base.box"
config.vm.network "private_network", ip: "10.0.3.10"
config.ssh.keep_alive = true
config.vm.define "vagrant_image"
config.vm.provision "ansible" do |ansible_pre|
config.ssh.username = "vagrant"
ansible_pre.playbook = "provisioning/pre_provisioning.yml"
ansible_pre.host_vars = {
"vagrant_image" => {
"ansible_host" => "127.0.0.1",
}
}
ansible_pre.vault_password_file = ENV['ANSIBLE_VAULT_PASSWORD_FILE']
end
config.vm.provision "ansible" do |ansible|
config.ssh.username = "provisioner"
ansible.playbook = "provisioning/provisioning.yml"
ansible.host_vars = {
"vagrant_image" => {
"ansible_host" => "127.0.0.1",
}
}
ansible.vault_password_file = ENV['ANSIBLE_VAULT_PASSWORD_FILE']
end
end
(In case you were wondering the s3 box url only works because I've installed the vagrant-s3auth (1.3.2) plugin)

You can set it in several places. Vagrantfile (but not config, it will be overridden), through Ansible extravars:
config.vm.provision "ansible" do |ansible_pre|
ansible_pre.playbook = "provisioning/pre_provisioning.yml"
ansible_pre.host_vars = {
"vagrant_image" => {
"ansible_host" => "127.0.0.1",
}
}
ansible_pre.extra_vars = {
ansible_user: "vagrant"
}
ansible_pre.vault_password_file = ENV['ANSIBLE_VAULT_PASSWORD_FILE']
end
config.vm.provision "ansible" do |ansible|
ansible.playbook = "provisioning/provisioning.yml"
ansible.host_vars = {
"vagrant_image" => {
"ansible_host" => "127.0.0.1",
}
ansible.extra_vars = {
ansible_user: "provisioner"
}
ansible.raw_ssh_args = "-i /path/to/private/key/id_rsa"
ansible.vault_password_file = ENV['ANSIBLE_VAULT_PASSWORD_FILE']
end
But you can also write a single playbook and switch users inside. See ansible_user and meta: reset_connection.

Related

Terraform - Failed to set up SSH tunneling for host

Hell, I am trying to deploy rke k8s with terraform, but I am not able to connect to the desired host via ssh:
time="2022-02-28T11:17:38+01:00" level=warning msg="Failed to set up SSH tunneling for host [poc-k8s.my-domain.com]: Can't retrieve Docker Info: error during connect: Get \"http://%2Fvar%2Frun%2Fdocker.sock/v1.24/info\": Unable to access node with address [poc-k8s.my-domain.com:22] using SSH. Please check if you are able to SSH to the node using the specified SSH Private Key and if you have configured the correct SSH username. Error: ssh: handshake failed: ssh: unable to authenticate, attempted methods [none publickey], no supported methods remain"
and this is the .tf file I am using:
terraform {
required_providers {
rke = {
source = "rancher/rke"
version = "1.3.0"
}
}
}
provider "rke" {
log_file = "rke_debug.log"
}
resource "rke_cluster" "cluster" {
nodes {
address = "poc-k8s.my-domain.com"
user = "root"
role = ["controlplane", "worker", "etcd"]
ssh_key = file("~/.ssh/root_key")
}
nodes {
address = "poc-k8s.my-domain.com"
user = "root"
role = ["worker", "etcd"]
ssh_key = file("~/.ssh/root_key")
}
addons_include = [
"https://raw.githubusercontent.com/kubernetes/dashboard/v1.10.1/src/deploy/recommended/kubernetes-dashboard.yaml",
"https://gist.githubusercontent.com/superseb/499f2caa2637c404af41cfb7e5f4a938/raw/930841ac00653fdff8beca61dab9a20bb8983782/k8s-dashboard-user.yml",
]
}
resource "local_file" "kube_cluster_yaml" {
filename = "~/.kube/kube_config_cluster.yml"
sensitive_content = "rke_cluster.cluster.kube_config_yaml"
}
The key if of course correct and I am able to connect to the desired host:
ssh -i ~/.ssh/root_key root#poc-k8s.my-domain.com
what am I missing here?
[Update]
Cluster resource has delay_on_creation property that can be used
resource "rke_cluster" "cluster" {
delay_on_creation = 180
(...)
}
I'm facing a similar issue. On the second run of terrafor apply it works correctly. In my case the issue is that docker is not up fast enough for RKE provider.
I've found following workaround from citynetwork /
citycloud-examples:
resource "rke_cluster" "cluster" {
(...)
depends_on = [null_resource.wait-for-docker]
}
resource "null_resource" "wait-for-docker" {
provisioner "local-exec" {
command = "sleep 180"
}
depends_on = [
# list of servers docker being installed on
(...)
]
}
It waits for 180s which is not ideal, though.

Gitlab-ci problems pushing to the private registry with HTTPS

I'm trying to push an image to my registry with the gitlab ci. I can login without any problems (the before script). However I get the following error on the push command. error parsing HTTP 400 response body: invalid character '<' looking for beginning of value: "<html>\r\n<head><title>400 The plain HTTP request was sent to HTTPS port</title></head>\r\n<body>\r\n<center><h1>400 Bad Request</h1></center>\r\n<center>The plain HTTP request was sent to HTTPS port</center>\r\n<hr><center>nginx</center>\r\n</body>\r\n</html>\r\n"
This in the config.toml from the used gitlab-runner
[[runners]]
name = "e736f9d48a40"
url = "https://gitlab.domain.com/"
token = "token"
executor = "docker"
[runners.custom_build_dir]
[runners.cache]
[runners.cache.s3]
[runners.cache.gcs]
[runners.cache.azure]
[runners.docker]
tls_verify = false
image = "docker"
privileged = true
disable_entrypoint_overwrite = false
oom_kill_disable = false
disable_cache = false
volumes = ["/cache"]
shm_size = 0
This is the relevant part of the gitlab-ci
image: docker
services:
- docker:dind
variables:
BACKEND_PROJECT: "test"
DOCKER_DRIVER: overlay2
DOCKER_TLS_CERTDIR: ""
containerize:
stage: containerize
before_script:
- "docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY"
only:
- master
script:
- "cd backend/"
- "docker build -t $CI_REGISTRY_IMAGE/api:latest ."
- "docker push $CI_REGISTRY_IMAGE/api:latest"
The GitLab omnibus registry configuration
registry_external_url 'https://gitlab.domain.com:5050'
registry_nginx['enable'] = true
registry_nginx['ssl_certificate_key'] = "/etc/letsencrypt/live/gitlab.domain.com/privkey.pem"
registry_nginx['ssl_certificate'] = "/etc/letsencrypt/live/gitlab.domain.com/fullchain.pem"
registry_nginx['port'] = 443
registry_nginx['redirect_http_to_https'] = true
### Settings used by Registry application
registry['enable'] = true
registry_nginx['proxy_set_headers'] = {
"Host" => "$http_host",
"X-Real-IP" => "$remote_addr",
"X-Forwarded-For" => "$proxy_add_x_forwarded_for",
"X-Forwarded-Proto" => "http",
"X-Forwarded-Ssl" => "on"
}
Can someone help me with this problem?
Okay, the solution was quite simple. I only had to change the
"X-Forwarded-Proto" => "http",
to
"X-Forwarded-Proto" => "https",

Vagrantfile setup to allow Ansible to SSH in

I have a vagrantfile from a book about Ansible for Devops. The issue I have is that I can SSH into the servers but Ansible cannot. Here is my vagrantfile;
# -*- mode: ruby -*-
# vi: set ft=ruby
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
# General Vagrant VM configuration
config.vm.box = "geerlingguy/centos7"
config.ssh.insert_key = false
config.vm.synced_folder ".", "/vagrant", disabled: true
config.vm.provider :virtualbox do |v|
v.memory = 256
v.linked_clone = true
end
# Application server 1
config.vm.define "app1" do |app|
app.vm.hostname = "orc-app1.dev"
app.vm.network :private_network, ip: "192.168.60.4"
end
# Application server 2
config.vm.define "app2" do |app|
app.vm.hostname = "orc-app2.dev"
app.vm.network :private_network, ip: "192.168.60.5"
end
# Database server
config.vm.define "db" do |db|
db.vm.hostname = "orc-db.dev"
db.vm.network :private_network, ip: "192.168.60.6"
end
end
And my Ansible hosts file;
# Application servers
[app]
192.168.60.4
192.168.60.5
# Database servers
[db]
192.168.60.6
# Group 'multi' with all servers
[multi:children]
app
db
# Variables that will be appliedto all servers
[multi:vars]
ansible_ssh_user=vagrant
ansible_ssh_private_key_file=~/.vagrant.d/insecure_private_key
I know I can explicitly add ansible_ssh_port=2200 etc but I'd rather have it setup in the vagrantfile
You could try several things
Set the full ssh key path, in ansible config.
Try connect by your self, using ssh.
Check that 22th port opened, using telnet. If it’s closed you can try to disable firewall in VM. CentOS has it enabled by default.

vagrant up command times out after "SSH auth method: private key" line

I have installed Ubuntu 16.04 on in VirtualBox on Windows 8.1 operating system.
I boot my Virtual box with Ubuntu 16.04 and inside it, when I am trying to run vagrant up, it freezes at default: ssh auth method: private key line and finally times out after 600 seconds (which I set into Vagrantfile).
Timed out while waiting for the machine to boot. This means that
Vagrant was unable to communicate with the guest machine within
the configured ("config.vm.boot_timeout" value) time period. If you look above, you should be able to see the error(s) that Vagrant had when attempting to connect to the machine. These errors are usually good hints as to what may be wrong. If you're using a custom box, make sure that networking is properly working and you're able to connect to the machine. It is a common problem that networking isn't setup properly in these boxes. Verify that authentication configurations are also setup properly,
as well. If the box appears to be booting properly, you may want to increase the timeout ("config.vm.boot_timeout") value.
I am running vagrant up command from its location.
$ /var/www/yrc-2017$ vagrant up
My Vagrantfile looks like this:
if Gem::Version.new(Vagrant::VERSION) < Gem::Version.new("1.5.0")
puts "ERROR: Outdated version of Vagrant"
puts " Chassis requires Vagrant 1.5.0+ "
puts
exit 1
end
if not File.exist?(File.join(File.dirname(__FILE__), "puppet", "modules", "apt", ".git"))
puts "NOTICE: Submodules not found, updating for you"
if not system("git submodule update --init", :chdir => File.dirname(__FILE__))
puts "WARNING: Submodules may be missing, and could not automatically\ndownload them for you."
end
# Extra new line, please!
puts
end
require_relative "puppet/chassis.rb"
CONF = Chassis.config
Chassis.install_extensions(CONF)
base_path = Pathname.new( File.dirname( __FILE__ ) )
module_paths = [ base_path.to_s + "/puppet/modules" ]
module_paths.concat Dir.glob( base_path.to_s + "/extensions/*/modules" )
module_paths.map! do |path|
pathname = Pathname.new(path)
pathname.relative_path_from(base_path).to_s
end
Vagrant.configure("2") do |config|
# Set up potential providers.
config.vm.provider "virtualbox" do |vb|
# Use linked clones to preserve disk space.
vb.linked_clone = true if Vagrant::VERSION =~ /^1.8/
end
config.vm.box = "bento/ubuntu-16.04"
# Adding boot timeout
config.vm.boot_timeout = 600
# Enable SSH forwarding
config.ssh.forward_agent = true
# Disable updating of Virtual Box Guest Additions for faster provisioning.
if Vagrant.has_plugin?("vagrant-vbguest")
config.vbguest.auto_update = false
end
# Having access would be nice.
if CONF['ip'] == "dhcp"
config.vm.network :private_network, type: "dhcp", hostsupdater: "skip"
else
config.vm.network :private_network, ip: CONF['ip'], hostsupdater: "skip"
end
config.vm.hostname = CONF['hosts'][0]
config.vm.network "forwarded_port", guest: 22, host: 2222, host_ip: "127.0.0.1", id: 'ssh'
preprovision_args = [
CONF['apt_mirror'].to_s,
CONF['database']['has_custom_prefix'] ? "" : "check_prefix"
]
config.vm.provision :shell, :path => "puppet/preprovision.sh", :args => preprovision_args
config.vm.provision :puppet do |puppet|
puppet.manifests_path = "puppet/manifests"
puppet.manifest_file = "development.pp"
module_paths.map! { |rel_path| "/vagrant/" + rel_path }
puppet.options = "--modulepath " + module_paths.join( ':' ).inspect
puppet.options += " --hiera_config /dev/null"
puppet.options += " --disable_warnings=deprecations"
end
config.vm.provision :shell do |shell|
shell.path = "puppet/postprovision.sh"
shell.args = [
# 0 = hostname
CONF['hosts'][0],
# 1 = username
CONF['admin']['user'],
# 2 = password
CONF['admin']['password']
]
end
synced_folders = CONF["synced_folders"].clone
synced_folders["."] = "/vagrant"
mount_opts = CONF['nfs'] ? [] : ["dmode=777","fmode=777"]
synced_folders.each do |from, to|
config.vm.synced_folder from, to, :mount_options => mount_opts, :nfs => CONF['nfs']
if CONF['nfs'] && Vagrant.has_plugin?("vagrant-bindfs")
config.bindfs.bind_folder to, to
end
end
# Success?
end
I only added the following two lines in above file:
config.vm.boot_timeout = 600
Reference
and
config.vm.network "forwarded_port", guest: 22, host: 2222, host_ip: "127.0.0.1", id: 'ssh'
Reference
What should I do?
UPDATE
I have the following settings in VirtualBox > System on Windows 8.1
Paravitualization Interface: Default
Hardware Virtualization:
- Enable VT-x/AMD-V
- Enable Nested Paging
And all the options above are disabled, means I cannot change anything.
Screenshot:
Try and write "Vagrant ssh" after vagrant up, and if it asks for credentials it is "vagrant", if the issue is not fixed with a vagrant up --provision or a vagrant reload (halt and up), then delete your box and rebuild it from the box you started out with.
it have happen to me some times, when i try to upgrade the boxes i have, then i just have to re-setup the box and everything works.
it happens that the system does not gets the system propperly started.

Terraform cannot connect Chef provisioner with ssh

I cannot get terraform's ssh to connect via private aws keypair for chef provisioning - the error looks to just be a timeout:
aws_instance.app (chef): Connecting to remote host via SSH...
aws_instance.app (chef): Host: 96.175.120.236:32:
aws_instance.app (chef): User: ubuntu
aws_instance.app (chef): Password: false
aws_instance.app (chef): Private key: true
aws_instance.app (chef): SSH Agent: true
aws_instance.app: Still creating... (5m30s elapsed)
Error applying plan:
1 error(s) occurred:
* dial tcp 96.175.120.236:32: i/o timeout
Terraform does not automatically rollback in the face of errors.
Instead, your Terraform state file has been partially updated with
any resources that successfully completed. Please address the error
above and apply again to incrementally change your infrastructure.
Here is my terraform plan - note the ssh settings.. the key_name setting is set to my AWS keypair name and the ssh_for_chef.pem is the private key
variable "AWS_ACCESS_KEY" {}
variable "AWS_SECRET_KEY" {}
provider "aws" {
region = "us-east-1"
access_key = "${var.AWS_ACCESS_KEY}"
secret_key = "${var.AWS_SECRET_KEY}"
}
resource "aws_instance" "app" {
ami = "ami-88aa1ce0"
count = "1"
instance_type = "t1.micro"
key_name = "ssh_for_chef"
security_groups = ["sg-c43490e1"]
subnet_id = "subnet-75dd96e2"
associate_public_ip_address = true
provisioner "chef" {
server_url = "https://api.chef.io/organizations/xxxxxxx"
validation_client_name = "xxxxxxx-validator"
validation_key = "/home/user01/Documents/Devel/chef-repo/.chef/xxxxxxxx-validator.pem"
node_name = "dubba_u_7"
run_list = [ "motd_rhel" ]
user_name = "user01"
user_key = "/home/user01/Documents/Devel/chef-repo/.chef/user01.pem"
ssl_verify_mode = "false"
}
connection {
type = "ssh"
user = "ubuntu"
private_key = "${file("/home/user01/Documents/Devel/ssh_for_chef.pem")}"
}
}
Any ideas?
I'm not sure if we had the same problem, since you didn't specify if you were able to ssh to the instance.
In my case, I was running terraform from within the VPC, and the connection was allowed with a security groups, which can't be used with a public IP.
the solution is simple (but you will have to use the new conditional interpolations of terraform v.0.8.0) -
Define this variable - variable use_public_ip { default = true }
Then, inside the connection section of the chef provisioner, add the following line -
host = "${var.use_public_ip ? aws_instance.instance.public_ip : aws_instance.instance.private_ip}"
If you wish to use the public IP, set the variable as true, otherwise, set it to false.
I use this for aws -
connection {
user = "ubuntu"
host = "${var.use_public_ip ? aws_instance.instance.public_ip : aws_instance.instance.private_ip}","
}