23
Create Your Own Module Yan Kurniawan, March 2015 EXTENDING ANSIBLE

Extending ansible

Embed Size (px)

Citation preview

Page 1: Extending ansible

Create Your Own Module

Yan Kurniawan, March 2015

EXTENDING ANSIBLE

Page 2: Extending ansible

ABOUT ME

• Cloud Engineer at Flux7 (http://flux7.com), a US-based AWS

Consulting Partner

• Writer of “Ansible for AWS” book

http://leanpub.com/ansible-for-aws

Page 3: Extending ansible

ANSIBLE MODULES

• "batteries-included" philosophy

Useful out-of-the-box modules

• Over 200 core modules available

http://docs.ansible.com/modules_by_category.html

Page 4: Extending ansible

ANSIBLE MODULE

PUPPET MODULE

Page 5: Extending ansible

PUPPET BUILT-IN RESOURCE TYPES

augeas

computer

cron

exec

file

filebucket

group

host

interface

k5login

macauthorization

mailalias

maillist

mcx

mount

nagios_command

nagios_contact

nagios_contactgroup

nagios_host

nagios_hostdepende

ncy

nagios_hostescalatio

n

nagios_hostextinfo

nagios_hostgroup

nagios_service

nagios_servicedepen

dency

nagios_serviceescala

tion

nagios_serviceextinf

o

nagios_servicegroup

nagios_timeperiod

notify

package

resources

router

schedule

scheduled_task

selboolean

selmodule

service

ssh_authorized_key

sshkey

stage

tidy

user

vlan

yumrepo

zfs

zone

Zpool

Page 6: Extending ansible

ANSIBLE CLOUD MODULES

• Amazon (AWS)

• Azure

• Digital Ocean

• Docker

• Google

• Linode

• Openstack

• Rackspace

• VMWare

Page 7: Extending ansible

AWS MODULES

• CloudFormation

• EC2

• VPC

• Security Groups

• AMI

• Auto Scaling Group

• ELB

• CloudWatch

• RDS

• S3

• Route53

Page 8: Extending ansible

EC2 MODULE

• create, terminate, start or stop an AWS EC2 instance

• http://docs.ansible.com/ec2_module.html

Page 9: Extending ansible

EXAMPLE – LAUNCH AWS EC2

- name: launch EC2 instance

ec2:

region: ap-southeast-2

key_name: mykey

instance_type: t2.micro

image: ami-xxxxxx

wait: yes

group: mysecgroup

instance_tags:

Name: test01

env: test

Page 10: Extending ansible

WRITING CUSTOM MODULE

• Any language (Python, Bash, C++, PHP, clojure, Ruby, etc); the only

requirement is being able to read/write files and write to stdout

• Output of the module should be in JSON format

• Recommended: Python

Boilerplate available; reduce the amount of code required

Arguments are handled automatically

Output is automatically converted to JSON

You can learn from Ansible core modules

https://github.com/ansible/ansible-modules-core

Chance to contribute to the Ansible project

Page 11: Extending ansible

DIRECTORY STRUCTURE

group_vars/library/ put custom modules hereroles/playbook.yml

Page 12: Extending ansible

THE BOILERPLATE

def main():module = AnsibleModule(

argument_spec = dict(arg1 = dict(choices=SOME_CHOICES),arg2 = dict(required=False)

),)

# Your code here

# import module snippetsfrom ansible.module_utils.basic import *main()

Page 13: Extending ansible

DEMO

• A simple module to return Amazon EC2 instance id(s)

using tags as input argument.

• Save the module as instance_lookup in

library/ directory

• Use the return value to start/stop/terminate

instance(s) using Ansible ec2 module.

Page 14: Extending ansible

CHOICES

AWS_REGIONS = ['ap-northeast-1',

'ap-southeast-1',

'ap-southeast-2',

'eu-central-1',

'eu-west-1',

'sa-east-1',

'us-east-1',

'us-west-1',

'us-west-2']

Page 15: Extending ansible

HANDLING EXCEPTION

import sys

try:

from boto.ec2 import connect_to_region

except ImportError:

print "failed=True msg='boto required for this module'"

sys.exit(1)

Page 16: Extending ansible

ARGUMENTS PARSING

def main():

module=AnsibleModule(

argument_spec=dict(

region=dict(choices=AWS_REGIONS),

tags=dict(default=None, type='dict'),

)

)

params = module.params

region = params['region']

tags = params['tags']

Page 17: Extending ansible

SOME CODES

if region:

try:

ec2 = connect_to_region(region)

except boto.exception.NoAuthHandlerFound, e:

module.fail_json(msg=str(e))

else:

module.fail_json(msg="region must be specified")

instance_ids = []

for tag, value in tags.iteritems():

for instance in ec2.get_only_instances\

(filters={'tag:' + tag: value}):

instance_ids.append(instance.id)

Page 18: Extending ansible

BOTO LIBRARY

get_only_instances

http://boto.readthedocs.org/en/latest/ref/ec2.htm

l#boto.ec2.connection.EC2Connection.get_only_inst

ances

Page 19: Extending ansible

HANDLING RETURN

module.exit_json(changed=False,

instance_ids=instance_ids)

Page 20: Extending ansible

THE PLAYBOOK

- name: get instance id

instance_lookup:

region: "{{ region }}”

tags:

Name: test01

register: instanceid

- name: start instance

ec2:

region: "{{ region }}"

instance_ids: "{{ instanceid.instance_ids }}"

state: running

wait: yes

when: instanceid is defined

Page 21: Extending ansible

MORE RESOURCES

• Module development guideline

http://docs.ansible.com/developing_modules.html

• Boto reference

https://boto.readthedocs.org/en/latest/

Page 22: Extending ansible

Source code available at http://git.io/pFEJ

Page 23: Extending ansible

THANK YOU