I created a VM using Vagrant and Ansible and when i try to use it after it is booted i note that it is extremely slow. I'm also using a remote DB in the cloud but it seems not to be the cause of the slow response. By slow response i mean about 5secs to load a page most of the time.
Vagrantfile
# -*- mode: ruby -*-
# vi: set ft=ruby :
# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
# Set the box name and URL
config.vm.box = "trusty-server"
config.vm.box = "skeleton"
config.vm.box_url = "https://cloud-images.ubuntu.com/vagrant/trusty/current/trusty-server-cloudimg-amd64-vagrant-disk1.box"
# Hostmanager plugin config
config.hostmanager.enabled = true
config.hostmanager.manage_host = true
config.hostmanager.ignore_private_ip = false
config.hostmanager.include_offline = true
# Fix TTY problem
config.ssh.shell = "bash -c 'BASH_ENV=/etc/profile exec bash'"
# Basic box configuration
config.vm.network "private_network", ip: "192.168.100.102"
config.vm.hostname = "skeleton.ontherocks.dev"
config.hostmanager.aliases = %w(en.skeleton.ontherocks.dev)
config.vm.synced_folder ".", "/vagrant", :mount_options => ['dmode=777', 'fmode=777']
# Provision using Ansible
config.vm.provision "ansible" do |ansible|
ansible.playbook = "provisioning/playbook.yml"
end
config.vm.provision :hostmanager
end
Playbook
- hosts: default
remote_user: vagrant
sudo: true
sudo_user: root
tasks:
##
# Update apt packages
#
- name: General | Update apt packages.
apt: update_cache=yes
##
# Apt package instalation of required software
#
- name: General | Install required packages.
apt: pkg={{ item }} state=present
with_items:
- build-essential
- php5
- apache2
- php5-mysql
- sendmail
- php5-mcrypt
- php5-curl
- php5-gd
##
# Apache2 setup
#
- name: Apache | Enable required modules
action: command a2enmod rewrite vhost_alias
- name: Apache | Configuration file for our site
action: template src=templates/etc-apache2-sites-available-website-conf.j2 dest=/etc/apache2/sites-available/website.conf
- name: Apache | Disable the default site
action: command a2dissite 000-default
- name: Apache | Enable our new site
action: command a2ensite website
notify:
- Restart Apache
- name: PHP | Enable required modules
action: command php5enmod mcrypt
notify:
- Restart Apache
##
# Website setup
#
- name: Website | Set up file and directory permissions
file: path=/vagrant/craft/storage/ mode=0777 recurse=yes state=directory
sudo: yes
##
# Restart services
#
handlers:
- name: Restart Apache
service: name=apache2 state=restarted
Speed up the shared folder with nfs
config.vm.synced_folder ".", "/vagrant", :nfs => { :mount_options => ["dmode=777","fmode=777"] }
Speed up the vm networking
config.vm.provider "virtualbox" do |vb|
vb.customize ["modifyvm", :id, "--nictype1", "virtio"]
end
This had a 10-15x networking increase for me.
Related
I am trying to provision a virtual machine with an Ansible playbook.
Following the documentation, I ended up with this simple Vagrant File:
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/xenial64"
config.vm.network "private_network", ip: "192.168.50.5"
config.vm.provision "ansible" do |ansible|
ansible.verbose = "vvv"
ansible.playbook = "playbook.yml"
end
end
As you can see, I am trying to provision a xenial64 machine (Ubuntu 16.04) from a playbook.yml file.
When I launch vagrant provision, here is what I get:
$ vagrant provision
==> default: Running provisioner: ansible...
default: Running ansible-playbook...
PYTHONUNBUFFERED=1 ANSIBLE_FORCE_COLOR=true ANSIBLE_HOST_KEY_CHECKING=false ANSIBLE_SSH_ARGS='-o UserKnownHostsFile=/dev/null -o IdentitiesOnly=yes -o ControlMaster=auto -o ControlPersist=60s' ansible-playbook --connection=ssh --timeout=30 --limit="default" --inventory-file=/home/mmarteau/Code/ansible-arc/.vagrant/provisioners/ansible/inventory -vvv playbook.yml
Using /etc/ansible/ansible.cfg as config file
statically included: /home/mmarteau/Code/ansible-arc/roles/user/tasks/ho-my-zsh.yml
statically included: /home/mmarteau/Code/ansible-arc/roles/webserver/tasks/nginx.yml
statically included: /home/mmarteau/Code/ansible-arc/roles/webserver/tasks/php.yml
statically included: /etc/ansible/roles/geerlingguy.composer/tasks/global-require.yml
statically included: /etc/ansible/roles/geerlingguy.nodejs/tasks/setup-RedHat.yml
statically included: /etc/ansible/roles/geerlingguy.nodejs/tasks/setup-Debian.yml
PLAYBOOK: playbook.yml *********************************************************
1 plays in playbook.yml
PLAY RECAP *********************************************************************
So my file seems to be read because I get some statically included from roles into my playbook.yml file.
However, the script stops very quickly, and I don't have any information to debug or to see any errors.
How can I debug this process?
EDIT: More info
Here is my playbook.yml file:
---
- name: Installation du serveur
# hosts: web
hosts: test
vars:
user: mmart
apps:
dev:
branch: development
domain: admin.test.dev
master:
branch: master
domain: admin.test.fr
bitbucket_repository: git#bitbucket.org:Test/test.git
composer_home_path: '/home/mmart/.composer'
composer_home_owner: mmart
composer_home_group: mmart
zsh_theme: agnoster
environment_file: arc-parameters.yml
ssh_agent_config: arc-ssh-config
roles:
- apt
- user
- webserver
- geerlingguy.composer
- geerlingguy.nodejs
- deploy
- deployer
...
Here is my host file:
[web]
XX.XX.XXX.XXX ansible_ssh_private_key_file=/somekey.pem ansible_become=true ansible_user=ubuntu
[test]
Here is the generated host file from vagrant in .vagrant/provisioners/ansible/inventory/vagrant_ansible_inventory :
# Generated by Vagrant
default ansible_ssh_host=127.0.0.1 ansible_ssh_port=2222 ansible_ssh_user='ubuntu' ansible_ssh_private_key_file='/home/mmart/Code/ansible-test/.vagrant/machines/default/virtualbox/private_key'
Is this correct? Shouldn't the ansible_ssh_user be set to vagrant ?
In your playbook use the default as hosts, as vagrant by default will only create an inventory element for that particular host:
---
- name: Installation du serveur
hosts: default
(...)
My Vagrantfile looks like:
Vagrant.configure("2") do |config|
config.vm.box = "vag-box"
config.vm.box_url = "boxes/base.box"
config.vm.network :private_network, ip: "192.168.100.100"
config.vm.provision :setup, type: :ansible_local do |ansible|
ansible.playbook = "playbook.yml"
ansible.provisioning_path = "/vagrant"
ansible.inventory_path = "/vagrant/hosts"
end
end
My playbook file looks like:
---
- name: Setup system
hosts: localhost
become: true
become_user: root
roles:
- { role: role1 }
- { role: role2 }
My hosts file looks like:
[localhost]
localhost # 192.168.100.100
During ansible execution I get the following error:
ERROR! Specified --limit does not match any hosts
First: "localhost" is a name that is assigned to the 127.0.0.1 address by convention. This refers to the loopback address of the local machine. I don't think this is what you are trying to use it for, based on the comment in your hosts file.
Second: The Ansible provisioner in Vagrant usually creates a custom inventory file, with the required contents to provision the Vagrant box. For example:
# Generated by Vagrant
myvagrantbox ansible_ssh_host=127.0.0.1 ansible_ssh_port=2222 ansible_ssh_user='vagrant' ansible_ssh_private_key_file='/home/sage/ansible/vagrant/myvagrantbox/.vagrant/machines/myvagrantbox/virtualbox/private_key'
As you are overriding the inventory file, you will need to specify a similar line for the hostname of your vagrant box.
If you omit the ansible.inventory_path = "/vagrant/hosts" line from your config, it should JustWork(tm). You might also wish to specify config.vm.hostname = "myvagrantboxname" in your configuration, so you know what hostname will be used.
See the Using Vagrant and Ansible and the Vagrant -- Ansible Provisioner documentation for more details.
I wrote a playbook which installs Docker.
---
- name: Install dependencies
apt: name={{ item }} state=present update_cache=yes
with_items:
- linux-image-generic-lts-{{ ansible_distribution_release }}
- linux-headers-generic-lts-{{ ansible_distribution_release }}
become: true
- name: Add Docker repository key
apt_key:
id: 58118E89F3A912897C070ADBF76221572C52609D
keyserver: hkp://p80.pool.sks-keyservers.net:80
state: present
register: add_repository_key
become: true
- name: Add Docker repository
apt_repository:
repo: 'deb https://apt.dockerproject.org/repo {{ ansible_distribution_release }} main'
state: present
become: true
- name: Install Docker
apt:
name: docker
state: latest
update_cache: yes
become: true
- name: Verify the service is running
service:
name: docker
enabled: yes
state: started
become: true
I'm up'ing a vagrant machine which is configured to use that playbook.
Vagrantfile:
# -*- mode: ruby -*-
# vi: set ft=ruby :
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.box = "ubuntu/trusty64"
config.ssh.insert_key = false
config.vm.synced_folder "./", "/tmp/project",create: true
config.vm.network :forwarded_port, guest: 80, host: 80 , auto_correct: true
config.vm.provider :virtualbox do |v|
# Name of machine
v.name = "default"
# Machine memory
v.memory = 1024
# Number of cpu's
v.cpus = 2
# This option makes the NAT engine use the host's resolver mechanisms to handle DNS requests
v.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
# Enabling the I/O APIC is required for 64-bit guest operating systems; it is also required if you want to use more than one virtual CPU in a virtual machine.
v.customize ["modifyvm", :id, "--ioapic", "on"]
end
config.vm.provision "ansible" do |ansible|
# Sets the playbook to use when machine is up'ed
ansible.playbook = "deploy/main.yml"
end
end
But for some reason, that's the output I get and docker is not installed on the vagrant machine:
$ vagrant up --provision
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Checking if box 'ubuntu/trusty64' is up to date...
==> default: Running provisioner: ansible...
default: Running ansible-playbook...
PLAY RECAP *********************************************************************
Is this the right way to do that?
Is there a command which lets me play a playbook on a running Vagrant machine?
I wrote a playbook which installs docker.
---
- name: Install dependencies
apt: name={{ item }} state=present update_cache=yes
with_items:
- linux-image-generic-lts-{{ ansible_distribution_release }}
- linux-headers-generic-lts-{{ ansible_distribution_release }}
become: true
No, you have not written a playbook. You have written a YAML file containing a list of Ansible tasks.
Playbooks contain a list of plays, and plays are YAML dictionaries which, for Ansible to work, at minimum must contain hosts key. In a typical play, the list of tasks is defined in tasks key.
So for your file to be a playbook you'd at least need:
- hosts: default
tasks:
- name: Install dependencies
apt: name={{ item }} state=present update_cache=yes
with_items:
- linux-image-generic-lts-{{ ansible_distribution_release }}
- linux-headers-generic-lts-{{ ansible_distribution_release }}
become: true
Note: default here refers to the name of the machine defined in your Vagrantfile (v.name = "default") not anything Ansible-default.
Is there a command which lets me play a playbook on a running Vagrant machine?
You can run the playbook defined in the Vagrant file with:
vagrant provision
To run another one, you'd just use ansible-playbook, but you must point to the Vagrant's inventory file, you must also use vagrant as the remote_user:
ansible-playbook -i .vagrant/provisioners/ansible/inventory/vagrant_ansible_inventory playbook.yml
I have just begun with ansible and I'm finding trouble with playbook syntax trying to provision a vagrant file. Below is my ansible playbook
---
- hosts: all
tasks:
- name: update apt cache
apt: update_cache=yes
become: yes
become_method: sudo
- name: create a directory for projects
file: path=/home/projects
state=directory
- name: create a directory for our project
file: path=/home/projects/myproject
state=directory
- name: install git
apt: name=git
become: yes
become_method: sudo
- name: initiaite git
command: git init
args:
chdir: /home/projects/myproject
- name: pull git
git: repo=https://github.com/path/to/repo.git
dest=/home/projects/myproject
- name: install mysql
apt: name=mysql-server
become: yes
become_method: sudo
- name: create mysql db for project
mysql_db: name=mydb
encoding=utf8
- name: create user and assign privileges
mysql_user: name=foo
password=bar
priv=mydb.*,GRANT
- name: install pip
apt: name=pip
become: yes
become_method: sudo
- name: install virtualenv
pip: name=virtualenv
become: yes
become_method: sudo
- name: Create the initial virtualenv
command: virtualenv /home/projects/myproject/venv -p python2.7 creates="/home/projects/myproject/venv"
- name: install requirements
pip:
requirements=/home/projects/myproject/requirements.txt
virtualenv=/home/projects/bankproblem/venv
My trouble is with the 4th task where I'm trying to install git.
ERROR: Syntax Error while loading YAML script, playbook.yml
Note: The error may actually appear before this position: line 21, column 1
become_method: sudo
^
Ansible failed to complete successfully. Any error output should be
visible above. Please fix these errors and try again.`
Someone please explain to me what's happening.
My Vagrantfile
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.box = "trusty-server-cloudimg-amd64-vagrant-disk1.box"
config.vm.box_url = "https://cloud-images.ubuntu.com/vagrant/trusty/current/trusty-server-cloudimg-amd64- vagrant-disk1.box"
config.vm.network "forwarded_port", guest: 80, host: 8080
config.vm.provision :ansible do |ansible|
ansible.playbook = "playbook.yml"
end
end
P.S. Please neglect the naive way the playbook is written as my intention is to simply get started with.
It was simply that
I had to make sure unnecessary white spaces aren't there and
The arguments to a task had to be in a single line separated by spaces, for instance,
Instead of
git: repo=https://github.com/path/to/repo.git
dest=/home/projects/myproject
I needed to use
git: repo=https://github.com/path/to/repo.git dest=/home/projects/myproject
Silly me! No more syntax errors now.
If I have Vagrantfile with ansible provision:
Vagrant.configure(2) do |config|
config.vm.box = 'hashicorp/precise32'
config.vm.network "forwarded_port", guest: 80, host: 8080
config.vm.provision :ansible do |ansible|
ansible.playbook = "playbook.yml"
ansible.inventory_path = "hosts"
ansible.limit = 'all'
ansible.sudo = true
end
end
My hosts file is very simple:
[local]
web ansible_connection=local
and playbook.yml is:
---
- hosts: local
sudo: true
remote_user: vagrant
tasks:
- name: update apt cache
apt: update_cache=yes
- name: install apache
apt: name=apache2 state=present
When I start vagrant with wagrant up I got error:
failed: [web] => {"failed": true, "parsed": false}
[sudo via ansible, key=daxgehmwoinwalgbzunaiovnrpajwbmj] password:
What's the problem?
The error is occurring because ansible is assuming key based ssh authentication, however your vagrant is creating a VM is uses password based authentication.
There are two ways you can solve this issue.
You can run your ansible playbook as
ansible-playbook playbook.yml --ask-pass
This will tell ansible to not assume key-based authentication, instead use password based ssh authentication and ask one before execution.