When we talk about Ansible Tower, we talk about control, knowledge and delegation. But what does that mean?
In previous posts in this series, we've talked about the concept of 'control' for your automation and your inventory, and about the basics of security and delegation. Today we're going to show how Tower's security and delegation allows for simple self-service deployments for your users.
THE PROBLEM - SERVICE REQUESTS
If you've ever run a service desk, you've probably dealt with repetitive ticket requests. There's not a lot of thought involved - taking customer and user requests, then punching those values into commands or random scripts. You need a solution that lets you automate the boring work and get you back to the important work.You need Ansible and Ansible Tower.
THE SOLUTION - ANSIBLE, TOWER AND TOWER SURVEYS
One of Tower's key features is survey support. Tower surveys allow you to configure how a job runs via a series of questions, making it simple to customize your jobs in a user-friendly way.Say you have a team of developers. What they need is the ability to get their dev environments set up in the cloud quickly, easily and properly. What you need is the ability to get them set up and get out of the way.
You need to let your developers accomplish three tasks:
- Upload new SSH keys to get to their dev environments
- Provision new dev environments
- Deprovision those environments when done
In doing so, you need to make sure they can customize their dev environments, while ensuring they don't delete other people's environments. That's where Tower's survey features come in.
A Tower survey is a simple question-and-answer form that allows users to customize their job runs. Combine that with Tower's role-based access control, and you can build simple, easy self-service for your users.
Here's an example of three jobs - for these, we'll be using AWS as our cloud provider.
upload-key.yml
---
- name: Upload new ssh key
connection: local
hosts: localhost
gather_facts: false
tasks:
- name: Verify key
shell: ssh-keygen -l -f /dev/stdin <<< '{{ key_data }}'
- name: Upload user-provided key
ec2_key:
name: "{{ tower_user_name }}"
key_material: "{{ key_data }}"
region: us-east-1
state: present
launch-instances.yml
---
- name: Provision developer instances
hosts: localhost
connection: local
gather_facts: False
vars:
os_image: { 'CentOS 7': 'ami-61bbf104', 'CentOS 6': 'ami-bc8131d4' }
instance_type: m3.medium
image_type: 'CentOS 7'
tasks:
- name: Launch development instances
ec2:
keypair: "{{ tower_user_name }}"
group: default
region: us-east-1
type: "{{ instance_type }}"
image: "{{ os_image[image_type] }}"
instance_tags: "{ 'type': '{{ instance_type }}', 'group': 'default', 'Name': '{{ tower_user_name }}_{{ env_tag_name }}' }"
count: "{{ machine_count }}"
wait: true
register: ec2
- name: Wait for instances to boot
pause:
seconds: 60
- name: Wait for SSH to come up
wait_for:
host: "{{ item.public_dns_name }}"
port: 22
timeout: 60
state: started
with_items:
- "{{ ec2.instances }}"
delete-instances.yml
---
- name: terminate hosts
hosts: "{{ ec2_hosts }}"
gather_facts: false
connection: local
vars:
ec2_hosts: tag_Name_{{ tower_user_name }}_{{ env_tag_name }}
tasks:
- name: terminate EC2 hosts
ec2:
region: us-east-1
instance_ids: "{{ item }}"
state: absent
wait: True
with_items:
- "{{ hostvars[inventory_hostname]['ec2_id'] }}"
Now, we'll set up the job templates for these. For these jobs, we'll be using our master AWS key delegated to the job.
As part of this, we'll create our surveys. To do so, go to 'Add/Edit Survey' in the job template screen.
A survey consists of any number of questions, each of which will set an extra variable passed to our playbook run. In this case, we'll have a survey form to let the user specify their new public key to add to AWS.
More complicated surveys are available, which we'll use for our environment provisioning. In this example, the developer can pick:
- The operating system to provision (CentOS 6 or CentOS 7)
- The number of instances to provision (between 1 and 5)
- The size of the instances to provision (we can let them choose between a few Amazon instance sizes)
- The tag/name for their dev environment
As always, this is available via Tower's API as well. Surveys are stored in the 'survey_spec' field of a job template, in JSON format. Here are the surveys we're using for our three jobs, and an example of how you'd pass it in the API.
For uploading an SSH key:
{
"description": "",
"name": "",
"spec": [
{
"question_description": "",
"min": 0,
"default": "",
"max": 2048,
"required": true,
"choices": "",
"new_question": true,
"variable": "key_data",
"question_name": "Please paste the public key to upload to Amazon here.",
"type": "textarea"
}
]
}
For provisioning our developer environments:
{
"description": "",
"name": "",
"spec": [
{
"required": true,
"min": 0,
"default": 1,
"max": 5,
"question_description": "",
"choices": "",
"new_question": true,
"variable": "machine_count",
"question_name": "How many instances do you need?",
"type": "integer"
},
{
"question_description": "",
"min": null,
"default": "m3.medium",
"max": null,
"required": true,
"choices": "m3.medium\nm3.large\nm3.xlarge",
"variable": "instance_type",
"question_name": "What instance size should we provision?",
"type": "multiplechoice"
},
{
"required": true,
"min": null,
"default": "CentOS 7",
"max": null,
"question_description": "",
"choices": "CentOS 6\nCentOS 7",
"new_question": true,
"variable": "image_type",
"question_name": "What OS should we provision?",
"type": "multiplechoice"
},
{
"question_description": "",
"min": 0,
"default": "",
"max": 32,
"required": true,
"choices": "",
"variable": "env_tag_name",
"question_name": "Please name your development environment.",
"type": "text"
}
]
}
For de-provisioning our developer environments:
{
"description": "",
"name": "",
"spec": [
{
"question_description": "",
"min": 0,
"default": "",
"max": 32,
"required": true,
"choices": "",
"variable": "env_tag_name",
"question_name": "What environment should we deprovision?",
"type": "text"
}
]
}
Here's how you would pass and enable a survey via the Tower REST API:
curl -k --basic -u admin:passwd -H "Content-Type: application/json" -X PATCH -d '{ "survey_enabled": "true" }' https://${towerhost}/api/v1/job_templates/N/
curl -k --basic -u admin:passwd -H "Content-Type: application/json" -X POST https://${towerhost}/api/v1/job_templates/N/survey_spec/ -d @survey.json
Next, we delegate these jobs to our development team to execute.
Then when our development team logs in, they can see these jobs and use them to provision new development environments.
If you'd like an even simpler view for your developers to use, they can visit Tower's "My View" interface (also known as Portal Mode). This interface, available at https://your.tower.server/portal, eliminates much of the Tower user interface, only showing the user the jobs available to them, and the jobs they have run.
PUTTING IT ALL TOGETHER
In our example above, we only provisioned basic machines in AWS, but it's easy to extend that to provisioning more complex environments using any Ansible automation available, whether that's a LAMP web environment, an Elastic log cluster, or other options.By utilizing that simple Ansible automation in combination with Tower surveys, it then becomes easy to provide simple-self service to your users. This allows your Ops team to maintain the control they need, without the drudgery of manual ticket handling... giving both your developers and your operators time to get back to what's important to their roles.
We'll be back with more examples of how you can use Ansible and Ansible Tower to manage your infrastructure soon.
In the meantime, you can find some of the examples from our blog posts at https://github.com/ansible/ansible-blog-examples.