Permalink
Browse files

new blog post: vultr with ansible

  • Loading branch information...
resmo committed Mar 18, 2018
1 parent bd0eab1 commit beb0fe2a3355d7dea186552ef0a7e23eafc64e27
Showing with 218 additions and 0 deletions.
  1. +208 −0 content/blog/2018-03-18-vultr-with-ansible.md
  2. +10 −0 themes/axolotl/layouts/shortcodes/note.html
@@ -0,0 +1,208 @@
---
title: "Begin Vultr With Ansible"
date: 2018-03-18T15:14:49+01:00
categories:
- sysadmin
tags :
- ansible
- vultr
- ansible-2.5
---
Ansible 2.5 is just around the corner, perfect timing to show some of the new features I was involved with and included in this release. This is the first part of a post series _What's new in Ansible 2.5_.
## What is Vultr?
[Vultr](https://www.vultr.com) is a Public Cloud Service (IaaS) with a manageable feature set and datacenters in around 15 locations around the globe including North America, Europe, Asia and Australia.
The features include a.o. classical virtual servers, bare metal servers, firewall management, block storage, free DNS service, custom ISOs and predefined apps. An easy to use user interface allows to configure all of these services manually but unsurprisingly Vutlr also provides an [API](https://www.vultr.com/api/) for a programming interface.
## Ansible Vultr Modules
The modules related to Vultr included in 2.5 ([Ansible docs](http://docs.ansible.com/ansible/devel/modules/list_of_cloud_modules.html#vultr)) do not yet cover all APIs but some of the most interesting ones:
* vr_account_facts
* vr_dns_domain
* vr_dns_record
* vr_firewall_group
* vr_firewall_rule
* vr_server
* vr_ssh_key
* vr_startup_script
* vr_user
These modules allow to deploy a server with your selected plan in a chosen region with an SSH key, configure the firewall group and rules and run start scripts on the server.
## Quickstart
So let's get started quickly by [creating a new account](https://www.vultr.com/?ref=7151504) (You support my works by using this affiliate link).
### Configure API Authentication
The modules uses the API and have to authenticate. So the first thing is to allow the modules to access the account using the API. You find the API key in your Account settings in the UI.
There are several ways to pass the API key to the modules. We won't cover every option for now, just the most common way: create a `.vultr.ini` in your home directory just like the following:
~~~ini
[default]
key = <your api key>
~~~
Run a test, get some infos about your account:
~~~
$ ansible -m vr_account_facts localhost
~~~
The output we will get should look something like:
~~~
localhost | SUCCESS => {
"ansible_facts": {
"vultr_account_facts": {
"balance": -212.87,
"last_payment_amount": -250.0,
"last_payment_date": "2017-04-28 12:29:50",
"pending_charges": 0.06
}
},
"changed": false,
"vultr_account_facts": {
"balance": -212.87,
"last_payment_amount": -250.0,
"last_payment_date": "2017-04-28 12:29:50",
"pending_charges": 0.06
},
"vultr_api": {
"api_account": "default",
"api_endpoint": "https://api.vultr.com",
"api_retries": 5,
"api_timeout": 60
}
}
~~~
But what just happened? We run the module `vr_account_facts` locally, the module itself connects to the API by HTTPs. There is one more cool thing, did you note we didn't have to install any other dependencies other then Ansible? Pretty nice isn't it?
### Define an Inventory
When authentication was successful, we can go to the next step, deploying our first server.
But first things first, create a inventory which contains the server we want to deploy, we use a classical INI style ansible inventory named `production`
One server, the webserver is called `web-01` and we put it in the group `cloud`, this is just enough for the moment.
~~~
$ mkdir hosts
$ echo "[cloud]\nweb-01" > hosts/production
~~~
When we check the inventory with the command introduced in 2.4, `ansible-inventory` and pass the right arguments
~~~
$ ansible-inventory --inventory hosts/production --list
~~~
We should see a nice json about view of our inventory:
~~~json
{
"_meta": {
"hostvars": {
"web-01": {}
}
},
"all": {
"children": [
"cloud",
"ungrouped"
]
},
"cloud": {
"hosts": [
"web-01"
]
},
"ungrouped": {}
}
~~~
So far, so good.
### Your first playbook
As you may know, a playbook is usually a YAML document containing one or more plays with tasks for a target host or host group. That is just what we need:
~~~
$ mkdir playbooks
$ touch playbooks/cloud.yml
~~~
In the first play, we are going to deploy our cloud server defined in our production inventory.
{{< highlight yaml >}}
- hosts: cloud
gather_facts: no
tasks:
- name: Ensure a cloud server exists
local_action:
module: vr_server
name: "{{ inventory_hostname_short }}"
os: "CentOS 7 x64"
plan: "2048 MB RAM,40 GB SSD,2.00 TB BW"
region: New Jersey
{{< / highlight >}}
We run the module as local action, that is why we turned off facts gathering as it would fail in case the server does not yet exist.
{{% note %}}
The same task can be written in several different ways using `connection: local` or `delegate_to: localhost`.
{{% /note %}}
The playbook is ready, let's give it a shot in `--check` mode:
~~~
$ ansible-playbook playbooks/cloud.yml --inventory hosts/production --check --diff -v
No config file found; using defaults
PLAY [cloud] *******************************************************************
TASK [Ensure a cloud server exists] ********************************************
changed: [web-01 -> localhost] => {"changed": true, "vultr_api": {"api_account": "default", "api_endpoint": "https://api.vultr.com", "api_retries": 5, "api_timeout": 60}, "vultr_server": {}}
PLAY RECAP *********************************************************************
web-01 : ok=1 changed=1 unreachable=0 failed=0
~~~
Before we continue without `---check` mode, I must note, that Vultr is quite popular and especially for datacenters located in Europe, plans may run out. If this happens, the module will fail but will give a decent error message:
~~~
fatal: [web-01 -> localhost]: FAILED! => {"changed": true, "msg": "URL https://api.vultr.com/v1/server/create, method POST with data OSID=167&DCID=9&VPSPLANID=201&notify_activate=no&label=web-01. Returned 412, with body: HTTP Error 412: Request Failed Plan is not available in the selected datacenter. This could mean you have chosen the wrong plan (for example, a storage plan in a location that does not offer them), or the location you have selected does not have any more capacity.", "vultr_api": {"api_account": "default", "api_endpoint": "https://api.vultr.com", "api_retries": 5, "api_timeout": 60}, "vultr_server": {}}
~~~
{{% note %}}Use a Vultr CLI e.g. [https://github.com/JamesClonk/vultr](https://github.com/JamesClonk/vultr) to get a list of available plans per region (DCID):
~~~
$ vultr plans -r <DCID>
~~~
{{% /note %}}
Okay, back to the playbook,
~~~
$ ansible-playbook playbooks/cloud.yml --inventory hosts/production --diff -v
No config file found; using defaults
PLAY [cloud] *******************************************************************
TASK [Ensure a cloud server exists] ********************************************
changed: [web-01 -> localhost] => {"changed": true, "vultr_api": {"api_account": "default", "api_endpoint": "https://api.vultr.com", "api_retries": 5, "api_timeout": 60}, "vultr_server": {"allowed_bandwidth_gb": 2000, "auto_backup_enabled": false, "cost_per_month": 10.0, "current_bandwidth_gb": 0, "date_created": "2018-03-18 12:54:29", "default_password": "aV6=DY}U(Y)n_x3,", "disk": "Virtual 40 GB", "firewall_group": null, "id": "14294916", "internal_ip": "", "kvm_url": "https://my.vultr.com/subs/vps/novnc/api.php?data=GF3VUMSQJZWWMRKBKR2XISLKKRJXOZZZIY4GK5DZN44EO6THKY3U423YI5CU4NLTJZFES6TBNYYGKTSYNNEWMRLNIZ4FS3BTJVDUIZKJHF4XQYRWF5KWSQRYJVVFGMBXLJETMTC2HEZHK42NLFZVU4ZRKBSWIURSNZWXKV3GG52UWQRLKJZXQOKMIQVXS2KWJV3DAZSGKJRGG2SBOB3VQT3YMFXGIZTVOU2S6STFOFXEKWDEMRKVE2TPNNLGWU3QJ5RESURTJZIFA6BWM46Q", "name": "web-01", "os": "CentOS 7 x64", "pending_charges": 0.02, "plan": "2048 MB RAM,40 GB SSD,2.00 TB BW", "power_status": "running", "ram": "2048 MB", "region": "New Jersey", "server_state": "ok", "status": "active", "tag": "", "v4_gateway": "207.246.94.1", "v4_main_ip": "207.246.95.35", "v6_main_ip": "", "v6_network": "", "v6_network_size": "", "v6_networks": [], "vcpu_count": 1}}
PLAY RECAP *********************************************************************
web-01 : ok=1 changed=1 unreachable=0 failed=0
~~~
That seems to have worked!
However you may feel like _what a mess of output_. This is because we also added `-v` to get a verbose output. You are right. I wanted to show, that the module does return a lot of data which can be used later when registered in a variable, e.g. the `vultr_server.default_password` to login by SSH or the `vultr_server.v4_main_ip` which can be used later for a DNS A-record.
Is this it? Well, we have a lot more things to cover but this is enough for today. Stay tuned for the next part of this series.
@@ -0,0 +1,10 @@
<br/>
<div class="panel panel-info">
<div class="panel-heading">
<p class="panel-title">Note</p>
</div>
<div class="panel-body">
{{ .Inner }}
</div>
</div>
<br/>

0 comments on commit beb0fe2

Please sign in to comment.