Security and Delegation with Ansible Tower, Part 2

November 23, 2016 by Bill Nottingham

Tower-Security-Series-part-2.png

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.

Tower-Screen-Create-SSH-Key

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.

Update SSH Key

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

Tower Provision Developer 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.

Tower Add Permissions


Then when our development team logs in, they can see these jobs and use them to provision new development environments.

Tower Launch Job
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.

Tower Job Template

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.
Share:

Topics:
Ansible Tower, Ansible, Security and Compliance


 

Bill Nottingham

Bill Nottingham is a Product Manager, Ansible, Red Hat. After 15+ years building and architecting Red Hat’s Linux products he joined Ansible ... which then became part of Red Hat a year and a half later. His days are spent chatting with users and customers about Ansible and Red Hat Ansible Tower. He can be found on Twitter at @bill_nottingham, and occasionally doing a very poor impersonation of a soccer player.


rss-icon  RSS Feed

Ansible Tower by Red Hat
Learn About Ansible Tower