We're sorry but this page doesn't work properly without JavaScript enabled. Please enable it to continue.
Feedback

Extending and embedding Ansible with Python

00:00

Formal Metadata

Title
Extending and embedding Ansible with Python
Title of Series
Part Number
124
Number of Parts
173
Author
License
CC Attribution - NonCommercial - ShareAlike 3.0 Unported:
You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal and non-commercial purpose as long as the work is attributed to the author in the manner specified by the author or licensor and the work or content is shared also in adapted form only under the conditions of this
Identifiers
Publisher
Release Date
Language
Production PlaceBilbao, Euskadi, Spain

Content Metadata

Subject Area
Genre
Abstract
Alejandro Guirao Rodríguez - Extending and embedding Ansible with Python [Ansible] is the _new cool kid in town_ in the configuration management world. It is easy to learn, fast to setup and works great! In the first part of the talk, I will do a super-fast introduction to Ansible for the newcomers. If you are a Pythonista, you can hack and leverage Ansible in many ways. In the second part of the talk, I will describe some options to extend and embed Ansible with Python: - Embedding Ansible with the Python API - Extending Ansible: creating modules, dynamic inventory scripts and plugins Previous experience with Ansible is advised in order to get the most of this talk, but beginners to the tool will also get an overview of the capabilities of this kind of integration.
Keywords
51
68
Thumbnail
39:40
108
Thumbnail
29:48
Point (geometry)Data managementMetropolitan area networkComputer fileAsynchronous Transfer ModeElectronic mailing listTask (computing)Parameter (computer programming)Data managementTask (computing)NeuroinformatikHypermediaVirtual machineData structureForm (programming)Series (mathematics)Programming languageEndliche ModelltheorieProduct (business)Level (video gaming)Computer architectureResultantSubject indexingSoftware testingGroup actionGame controllerConfiguration managementDescriptive statisticsExterior algebraRoboticsCuboidServer (computing)Service (economics)Point (geometry)INTEGRALDimensional analysisNumberScripting languageWeightDependent and independent variablesState of matterComputer fileOrder (biology)Multiplication signDirect numerical simulationArithmetic meanParameter (computer programming)Electronic mailing listPhysical systemCurveGradientIP addressModule (mathematics)Web 2.0MereologySpeech synthesisSoftwareVariable (mathematics)VirtualizationComputer configurationSmoothingComputer animation
Metropolitan area networkSinePole (complex analysis)Variable (mathematics)Computer fileTask (computing)Modul <Datentyp>CodeSample (statistics)System callComputer hardwareRevision controlSoftwareValue-added networkData managementParameter (computer programming)Repository (publishing)Multiplication signGroup actionComputer programmingEndliche ModelltheoriePattern languageService (economics)Function (mathematics)Civil engineeringState of matterElectronic mailing listTask (computing)Software developerBitCodeInformationResultantSoftware testingPhysical systemRevision controlForm (programming)Mechanism designAsynchronous Transfer ModeComputer hardwareRight angleSource codeEinbettung <Mathematik>QuicksortElectronic visual displayReduction of orderLengthWeightCASE <Informatik>Variety (linguistics)Divisor1 (number)Social classProof theoryEncapsulation (object-oriented programming)Presentation of a groupInstance (computer science)NumberRepresentational state transferModule (mathematics)Uniform resource locatorInstallation artLibrary (computing)Server (computing)Computer fileFlagOcean currentConfiguration managementComputer animation
Metropolitan area networkPersonal area networkAutomorphismServer (computing)BitRevision controlPhysical systemSoftwareInformationPlastikkarteComputer animationSource code
Metropolitan area networkSystem callSet (mathematics)Grand Unified TheoryValue-added networkInstance (computer science)Social classUtility softwareInstallation artBitCASE <Informatik>InformationBoilerplate (text)Electronic mailing listSystem callCodeEndliche ModelltheorieVelocityPlanningNetwork topologyTable (information)Division (mathematics)Computer animation
Metropolitan area networkInsertion lossGamma functionValue-added networkMaxima and minimaCodeInformationElectronic mailing listModulare ProgrammierungPhysical systemOcean currentProof theoryTask (computing)Installation artINTEGRALService (economics)Multiplication signScripting languageSource code
CodeRadio-frequency identificationScripting languageModul <Datentyp>Module (mathematics)Interface (computing)Metropolitan area networkSineProgramming languageData structureFunctional (mathematics)ResultantDifferent (Kate Ryan album)Point cloudComputer fileModule (mathematics)Library (computing)Data managementDynamical systemCodeFunction (mathematics)MereologyEinbettung <Mathematik>Endliche ModelltheorieDatabaseString (computer science)Template (C++)Interface (computing)Scripting languageoutputQuicksortServer (computing)Latent heatFamilyExtension (kinesiology)Point (geometry)Social classWeightLogicComputer animation
MereologySample (statistics)Software testingSheaf (mathematics)Value-added networkModule (mathematics)Asynchronous Transfer ModeInheritance (object-oriented programming)System callParsingInformation systemsCodeScripting languageChecklistIdempotentBounded variationParameter (computer programming)Software testingMusical ensembleLine (geometry)Message passingComputer fileGroup actionData managementScripting languageExclusive orSynchronizationVideo gameCondition numberReal numberVariable (mathematics)Series (mathematics)WhiteboardGame controllerArithmetic meanPreprocessorString (computer science)Physical systemFunctional (mathematics)Sheaf (mathematics)InformationEndliche ModelltheorieSubstitute goodExecution unitFunction (mathematics)Repository (publishing)MereologyMechanism designCode1 (number)Integrated development environmentResultantLibrary (computing)Default (computer science)Template (C++)StatuteAdditionAxiom of choiceAsynchronous Transfer ModeModule (mathematics)Virtual machineParticle systemMathematicsInstance (computer science)Computer configurationObservational studyNumberProjective planeStandard deviationChecklistLinear regressionRepresentational state transferError messageData dictionarySystem callRevision controlLetterpress printingComputer animation
Metropolitan area networkValue-added networkPersonal area networkPolar coordinate systemEndliche ModelltheorieInformationMultiplication signParameter (computer programming)Task (computing)Repository (publishing)Right anglePresentation of a groupTelecommunicationDatabaseData managementComputing platformState of matterComputer configurationDescriptive statisticsType theoryDistribution (mathematics)MereologyPhysical systemProjective planeModule (mathematics)Variable (mathematics)Computer fileCodeSoftware testingSource code
Metropolitan area networkSoftware testingDigital filterGrand Unified TheoryUniformer RaumOpen setSoftware bugSoftware testingTape driveComputer virusDistribution (mathematics)Computer animationSource code
Metropolitan area networkRing (mathematics)Gamma functionBitSoftware testingDigital filterScripting languageInformation systemsLine (geometry)Newton's law of universal gravitationGroup actionComputer fileServer (computing)Data dictionaryElectronic mailing listRevision controlSerial portDynamical systemScripting languageData storage devicePoint cloudIP addressVariable (mathematics)Key (cryptography)Gastropod shellForm (programming)Service (economics)Complex (psychology)TouchscreenSource codeComputer animation
Metropolitan area networkParsingMeta elementGame controllerDigital filterGroup actionCache (computing)Port scannerElectronic mailing listEvent horizonCloud computingEuler anglesEvent horizonModule (mathematics)Electronic mailing listDemo (music)Physical systemGame controllerPlug-in (computing)Repository (publishing)Configuration managementResultantMultiplication signSocial classOrder (biology)Computer fileEndliche ModelltheoriePlanningDifferent (Kate Ryan album)System callMusical ensembleCivil engineeringPattern languageSource codeComputer animation
Value-added networkMetropolitan area networkSet (mathematics)Cartesian coordinate systemMessage passingStatement (computer science)Endliche ModelltheorieHost Identity ProtocolTask (computing)Function (mathematics)Computer animation
Game controllerElectronic mailing listSample (statistics)Different (Kate Ryan album)Total S.A.Metropolitan area networkPlug-in (computing)Regulärer Ausdruck <Textverarbeitung>Service (economics)File systemArmImplementationTerm (mathematics)Element (mathematics)File systemExpressionConnected spacePlug-in (computing)Remote procedure callSocial classGastropod shellSource codeParameter (computer programming)Computer fileFunctional (mathematics)ResultantGame controllerModule (mathematics)Clique-widthKey (cryptography)Asynchronous Transfer ModeTerm (mathematics)InformationElectronic mailing listLoop (music)DatabaseChainAdditionLatin squareRevision controlPhysical systemVarianceEndliche ModelltheorieComputer iconSound effectComputer animation
Metropolitan area networkArmGamma functionInclusion mapAuthorizationWeb pageReading (process)Ocean currentLetterpress printingSource codeComputer animation
Digital filterExt functorClefMetropolitan area networkVariable (mathematics)Filter <Stochastik>Social classPosition operatorModule (mathematics)MappingRotationFunctional (mathematics)Plug-in (computing)Endliche ModelltheorieField (computer science)Variable (mathematics)Discrete groupComputer animation
Metropolitan area networkValue-added networkGame controllerModule (mathematics)ImplementationGroup actionCodeRepository (publishing)Sample (statistics)Physical systemInformationSoftware repositoryMereologyPlug-in (computing)Game controllerGroup actionModule (mathematics)Template (C++)Flow separationSocial classSource codeRevision controlPattern languageEndliche ModelltheorieAreaFunctional (mathematics)Different (Kate Ryan album)PlanningDirectory serviceTraffic reportingImplementationSource codeComputer animation
Curve fittingEuler anglesCache (computing)Read-only memoryIcosahedronHacker (term)Server (computing)Library (computing)Software testingComputer fileSocial classRevision controlProjective planeCodeSource codeLogicExecution unitOcean currentInformation1 (number)Plug-in (computing)Cache (computing)MereologyModule (mathematics)Computer iconLatent heatFunctional (mathematics)SubsetStandard deviationConfiguration managementProgramming languageFront and back endsBitStandard ModelEndliche ModelltheorieSpeech synthesisReliefDemosceneCondition numberGoodness of fitConnectivity (graph theory)Physical systemSign (mathematics)Data conversionMultiplication signProduct (business)Operator (mathematics)RadiusEvoluteTheoryTable (information)Selectivity (electronic)Video gameComputer animation
Transcript: English(auto-generated)
He's going to give his speech on what Ansible is, how to do some leverages, improvements and integrations,
which is the part of extending first the introduction, the 101 to Ansible, what Ansible is.
It's a configuration management tool, you maybe know many of those tools, there's also Puppet, Chef, SaltStack, CF Engine. The basic idea is to be able to automate the configuration of hosts,
and by hosts I mean virtual machines, bare metal, containers, everything can be managed. There are many alternatives, and basically the strong point of Ansible is that it works over SSH, out of the box, and it is agentless, that means that you do not have to install anything in the host system,
apart from Python 2.x, and another very strong point is that it is quite readable, and it has a smooth learning curve, it's not steep, because it's DSL, its language is YAML-based,
so it's quite readable, and it's easy, very easy to get on and start it. So this could be the example of an Ansible architecture in which there's a central node, called the management node of the controller, which could be a laptop, could be a server,
in which you run the Ansible software. Then you will have some inventory files that describe the IPs and DNS names of the hosts, and the groups of the hosts that you are managing, and then there are the hosts, which are remote machines that can be accessed over SSH, and there are series of playbooks,
like scripts, that the Ansible machine executes in each one of the hosts that it's managing. So this could be a very basic host file, in which we define two groups of servers, one of web, another of DB servers, we can define variables that are common to a group of servers,
for example the username of the DB group, and we can define metagroups that group another group, like this one, which is infrastructure group that joins the web and DB group. There are two ways to use Ansible, basically there are ad hoc commands and using playbooks.
So ad hoc commands is the easiest way, it's the hello world that everyone does, and they just throw away one-time executions in which you use the Ansible command in order to execute a module in a group of hosts, and the syntax is very simple,
just issue Ansible, name of the group, as described in your inventory file, minus M, name of the module, and minus I, the options. This could be the hello world that everyone has done, we are using the module called ping, the only thing that does is respond with a pong in the server,
so if we issue Ansible all minus M ping, and all is a magical group that groups everything in the inventory file, then we would have this response in each one of the servers, we would have the answer that is pong,
and also there's a value that states if anything has changed in the remote host. And the other way to use Ansible is to use playbooks. Playbooks are a much more structured way to do configuration management, they are basically YAML files that specify a list of plays,
and each play is a series of tasks that are applied to a group of hosts, and each one of those tasks is an execution of a module with some parameters and a description. This could be one task that is ensuring that the nginx server is started.
There's the description, this is the module name, and those are the parameters saying that the service is nginx, and the state we decide is started. This is an example of configuration management concept, that is that we define the desired state and not the actions to be performed, so that this module is clever enough to know that sometimes it has to start the service,
and sometimes just make a no-op and go on. This could be a playbook to deploy the nginx server. In this playbook we are targeting the group of hosts named web, we define some variables, and this is the list of tasks.
As you can see, there are modules to add repositories, APT repositories, modules to install APT packages, modules to manage services, modules to create or remove files, in this case we are removing a symlink,
and modules to template out things, like a Jinja 2 template, that we are going to template out in the remote host. Also there are handlers, that are special kind of tasks that are run once, independently of the number of times that they have been notified during the playbook.
This could be the execution of the playbook, we will have an output that sequentially shows the results of the task in each one of the hosts, and finally there's a nice recap. Just to finish this introduction, the way to manage things is using a kind of encapsulation,
that is roles. Roles is a little bit more advanced concept in Ansible, that just is a group of variables, of tasks, of handlers, files and templates, and maybe even dependencies to other roles. So, we have finished our introduction, now we'll be talking about how to hack Ansible.
There are two ways, embedding and extending Ansible. So, what do I mean by embedding? I mean calling Ansible modules and playbooks from your Python code. And this is basically possible because Ansible is based on Python,
it's written in Python, so it has some kind of a Python API. It's not very well documented, but it's quite easy to use, and if you read the source codes, you will see how to use it, although you can just continue and see how we can use it in this presentation.
Just before we start, a few disclaimers. This code is valid for Ansible version 1.9, which is the current stable one, probably in version 2, which is the current development one, things are going to change, this API is going to change,
and probably even things like the plug-in mechanism is going to change, so this is only valid. I can only guarantee that it's valid for the current stable version, and, well, everything in Ansible is Python 2.x only, it hasn't been ported to 3, and you can find the examples in this github repo.
So, first thing that we may want to do, we may want to run an Ansible task. This is the simpler kind of automation, it's just calling a module from your Ansible code. How do we do it? Very simple, just import some classes, basically the runner and the inventory from the Ansible library.
You will build your inventory, for example, directly in code, we may be just targeting our local host, and then making an instance of runner and calling the run method, just passing the module name, the arguments,
the inventory that we have just created, and the pattern of hosts that we want to target. And just a little bit, a little discretion, I'm talking about facts. What are the Ansible facts? Ansible facts are information that is retrieved
at the beginning of the execution of the playbook in each one of the hosts, and there's a bunch of information available for you to make things in your playbook, so you have the host name, IP addresses, the hardware information, even the installed version of the software.
So, I'm going to make an example, which is the flag factor, in which there's a proof of concept of embedding a module. I'm running a program that will create a REST API using the Flask RESTful module
that parses URLs in this format, getting a fact that we want to know about this system, and it will run the module setup and then parse the JSON that we have, showing the fact in our system. It could be just not very practical,
but it could be an idea of how we can retrieve information from a remote server. So, if we run in local host, we can retrieve the version of the software,
the base system that I'm running, the version of the kernel, or things a bit more complex, like the network card information. So, sometimes we need something more complex
than running a module. We need some kind of orchestration, so we may need to run a playbook, which is a more structured way. So, you have to import a little bit more classes, basically classes for the callbacks and utils. You have to build your inventory. It's similar to the other case.
In this case, we're also using host variables, because in this example, I'm going to attach some information to the inventory, the list of users and APD packets I want to install and create. You have to put some boilerplate code, just to set the verbosity of the execution of the playbook,
and also to register the typical callbacks for the runner and the playbook. And finally, creating a playbook instance and using the module run, specifying the playbook. In this case, the playbook is the installer.geml.
In this example, what I'm going to run, I'm going to run a playbook that install some APD packages
and create some users, because it's a typical task when you arrive at a system to begin creating users and installing software packages. So I've just created a proof of concept script,
in which I get, first I get the interactive console, the information of the name of the users and the list of packages, and then I call the Ansible playbook, which is called the installer.geml,
and I pass the list of packages and users via inventory variables, so that could be an example of this kind of integration. If I run it, I can create users, install packages,
and when I finish, it runs in local host, and it has shown that, although the current user, Alex, is created,
it has done anything, but for the new user that I've created, which is called George, it has changed the system, also installing another package. So I have called an Ansible playbook from my Python code. Well, one way to hack Ansible is by embedding,
another way is extending Ansible, and by extending I mean adding more functionality or customizing its behavior. Basically it's done by three ways, creating modules, creating dynamic inventory scripts, and creating plugins.
So let's start with creating an Ansible module. Ansible ships with tons of modules, ranging from creating usernames, managing databases, spinning cloud servers, but sometimes we need something more specific to our business, so we have to create a module, and what is an Ansible module?
It's just an executable file that you will find in some folders, in the .library relative to your playbook, or in the Ansible library path, and basically it has a JSON interface, so it expects JSON for the input, and also it emits a JSON for the output.
So it's language agnostic, you can do in bash, you can do in every language that you want, but if you are using Python, then it's easier because there are some helper functions that will make it really easier. This could be the structure of a typical module, I've borrowed some parts from the existing modules, and basically it's a file in which you have two strings,
we will come later to them, that are the documentation and examples, then this part of the code is what I call the Pythonic part, in which we do the hard work, we import the libraries, and we run our business logic, and then from that point, this is like a template,
let's say, in which we find a main module, we do some instantiation of the Ansible module class, we call our Pythonic part from this part, from this function, and then we emit a different kind of JSON depending on the result.
So let's get more detail, the documentation and examples are two strings, variables that are very important because they are used by Mac Web Docs to generate the HTML of the documentation, and some important parts are the version option part, in which we specified the values of the arguments,
and it's important to keep it in sync with the real code, which is the argument spec dictionary. You have to specify the requirements, if you need something, some more Python libraries to be installed in the controller, and you have to use the note section, if you need some environment variable,
for example, it's present at the controller, and in the examples, just put code, please, that is tested and worked, especially if you want to submit it to the Ansible repository. In the part that I call the Pythonic part, it's usually a good idea to put pure Python code,
import the libraries that you may need for dealing with the problem, but try not to use the Ansible part because it will make your code more robust to change in the Ansible API. However, there are some helper functions, for example, this one, coming from the Ansible module, from the Ansible library,
that allows you to easily run commands and find executables in the remote machine. And just some tips, try to return a value and a message, a meaningful message, and code every information on those values, and don't print to standard output or error
because this mechanism won't work. And in the main function, you have to create an Ansible module instance, and when you instantiate it, you pass an argument spec dictionary which defines the module arguments, defining the series of modules that are required, the ones that are optional, the default values, possible choices, aliases,
and then there's a section option in which you specify the module exclusion of the parameters, and also if you support check mode, this is the mode in which you do a dry run and you do not mess with the real system. It's just a test. So when you have created that,
you magically have a dictionary in which you have the parameters of the invocation of the module. So you have just to take those parameters, call the Pythonic part of the module with those parameters, and then pass the results depending on the status and the message. You have to create some kind of JSON,
and if you use some helper functions like this one, exeJson and failJson, then your life will be easier because they'll manage everything and create a JSON for you. And finally, probably you have seen those two lines at the end of the file. If you have Python tests that you allow,
probably you are now in tears and in pain because this is the Pythonic anti-pattern, the import asterisk. But please resist the temptation to make an explicit import because really it's like define a preprocessor in C because Ansible will substitute those lines
with the code of the helper functions. So if you do not put it, it won't find it, and you won't have an import. And if you do not put it at the end of the file, it will change the line numbering and debugging will be a hell. So some regression tips. Try to make a module you love to use,
module that is idempotent, that supports the check mode. Test your module, there's a very handy tool included that is the test module script. And if you want to submit it, please follow the module creation checklist that is available online
and it's much more comprehensive. I've created a model, an example, which is called the Taiga Issue. Taiga is an agile project management system that has a REST API and there's a library called Python Taiga that allows to manage it and to play with it. So I've created a very simple module
that is called Taiga Issue. This module is just for creating issues in this platform. For example, if we are deploying a system by Ansible and we find some problem
during the automation of the test, we can create an issue so that the team will see it, will have the information, will have the logs, will have everything. So I have submitted it to Ansible extra module repository and basically this is the documentation part.
You have to specify the different options that the module supports and you have to put some examples. This is what I call the Pythonic part. I import the Python Taiga and I'll do the issue management here.
It should be the Python code. And finally, this is the main part in which I specify the restrictions and the parameters. I part them and I call the Pythonic part with arguments and depending on the return status,
I issue one kind of JSON or the other. And if we see the playbook, we can just use this module to create a Taiga issue in our project. We can manage the description.
We can put also Ansible variables like the hostname and distribution. We can attach to the issue a file. For example, we can attach the playbook. Then I will pause and when I continue, it will delete the Taiga issue because the module supports the state present and absent.
So this is the test project that I've created with no issues. And then if I run the demo, it calls the Ansible playbook
of the playbook that we have seen. First, it has run the creation of the Taiga issue and it has stopped. If I check here, then I can see the issue. The issue has some tags. This is my Ansible distribution and this is the playbook also.
So if I resume, it will go in and delete it when possible.
So creating a dynamic inventory script, there's another way to hack it. If you are managing cloud servers and cloud infrastructure, probably you know about this. Dynamic inventory scripts are a way not to have to deal with a long list of servers
that probably are changing. Their IPs are changing. You can scale things. So dynamic inventory scripts are a way to deal with that complexity. And basically they are just an executable file that supports those command line switches. Minus minor list that will return a JSON dictionary
with the name of the groups and each group is a list of hosts. And minus minus host, which you specify a host name and then you get a dictionary of the host variables. Just pure JSON. So just for the fun of it, I've created an example which is shelf inventory.
You know shelf files. They are basically a key value store that Python supports natively in the serialization. So in the example, we are just using a shelf file that I've created and we can open it
and set the groups on the host version of it. I can through the demo. Because we are running out of time and I want to run another demo.
Plugins are a way to hack Ansible in very different ways. Basically the common thing is that they run in the controller node and there are different kinds of plugins. We're going to see some of them. And basically the way to add them is just drop them in a folder and if you want to use another folder,
just trick the Ansible config file. So the callback plugin is just a kind of plugin that reacts in the controller to the playbook and runner events. In order to create them, you just have to define a callback module class and then override the method you want to.
There's an example of the list of methods available for this class in the repository. So just a brief example. I'm going to create a callback plugin that reacts to the failed event of a module and then it will call the notify send binary
which will create a pop-up in my system with the name of the module and the result of the module.
I'm running this playbook which will just output a message. The first task will go up. The second one will fail. I'll get a pop-up
saying that the second one has failed. It's just an example of things that can be done. You can make Slack notifications, you can make a hip chat, everything you see is useful. You can create connection plugins. Basically, the connection plugins allow the controller to connect to the remote host
and ship all ships with lots of them but you can create much more. You'll just have to define a connection class and override the basic methods that are just connecting, disconnecting, executing commands, putting and fetching files
which are basically things that Ansible is doing in SSH mode. You can create lookup plugins. Lookup plugins allow to expand the functionality by accessing information in external sources from the controller, for example in databases,
in file systems and the syntax is just calling the lookup function and also if you define a lookup you'll get a width expression that allows you to loop over some results. You just have to create a lookup module class
and basically define an init method and a run method which will pass the terms which are the arguments of the lookup and then return a list of results. Following the example of the shell file I can define a shell file lookup
that will search for a shell file and retrieve a key from that shell file. Basically, I just implemented the run method and in this playbook
I'm opening the book.db and retrieving the current book name, book page and book author of the book I'm reading now
and print them. You can create filter plugins. Filter plugins are Jinja2 filters.
Ansible ships with usual Jinja filters but you can define some other filters. The syntax for using them is very simple. A variable followed by a pipe and the name of the filter. Those are example filters that Ansible comes with them but you can define many other.
It's very simple. Just create a filter module class that have a filters method that returns a mapping from the name of the filter to the Pythonic function that implements it. For example, we can create a filter to rotate 13 positions. This is the C star rotation
and just if we see an example of playbook, we can apply once and then apply twice and we can see that C star becomes PNRFNA
and then it becomes C star so it's working. Finally, just other plugins. Very fast action plugins that are plugins that allow separation of actions between the controller and the remote host.
For example, when you're templating out a file, there are some actions that need to be performed in the controller and some other different in the remote so that you can just implement an action module class with a method run and when you're dealing, doing things in the controller, then you execute this method,
runner execute module, to call the real module on the remote host. Can define bars plugins. Quite an undocumented part. They are possibly going to change with Ansible version 2 and it's the way that we can retrieve more information about the host via some external source like the host bars and group bars directory.
Basically, this is the template that you will find in the repo and you have to implement the get host bars and get group bars for a new plugin. You can create cache plugins, very modern functionality from Ansible version 1.8 in which we can retrieve the information
of hosts that have not been contacted in the current playbook execution. Just using a backend like Redis or memcache, you can run once, get the facts and then run without having to retrieve the facts of the rest of the host. You have to tweak your Ansible config file
and basically if you create a new one, you want to create a new one, you just have to implement this template. And finally, those are the references that I have used very good books not just for developing Ansible, but just for using them especially the first two ones and some articles talking about that.
So, that's it. Thank you very much and now if you have any questions Any questions?
Well, thanks for the talk and my question is, you mentioned that while using Ansible as embedded module, it's very
hard to find the documentation of API or is it very poorly documented, so actually how do I get this information to use it as embedded module? Okay, if you are if you want to embed a module like in the first example that I have said I have done
I had to do some research I had to go into the source code and see how the Ansible command is using the API and try to mimic it because we are using the same API that the command line version that is just an icon file is executing.
Also, I have seen some other examples which are here in the reference that are much more pragmatical examples, so I have been inspired from them. I think that in version 2.0 they are going to document it much better, they know in the Ansible project that there is lacking of documentation
in that part, I don't know if intentionally, but there is lacking of it, and it's changing, so when Ansible 2.0 comes as a stable one, probably it will have changed. It's not going to be I think not so simple, but more flexible. The way of testing
modules, do you need to write tests in some specific language or library for testing the code or
standard tests in Python? Well, testing things in Ansible is quite a tricky aspect, because even the Ansible code base is not very well covered with tests. If you see the project, they are just like
hundred and something assertions on the base code, so they are not very concerned about the testing and testing a module is even much more difficult. I would suggest you to test the Pythonic part separately, just this kind of part which is pure Python,
you can use Pytest, you can put the tests in another files, but there's no standard way to run programmatically tests to a module and you do not have even to make tests, to put tests in a pull request to get the module accepted. They are not very strict with this part, so I would
suggest testing only this Pythonic part, the business logic of your module, using an external library like Pytest, something like that, putting in a different file and importing the functions and the classes that you are defining. So maybe it's easier
using something like TestKitchen. Like? Sorry? Like TestKitchen. TestKitchen. Well, with TestKitchen you are not using like, I think it's unit testing, it's more like I don't know if it's functional testing or
something like that. TestKitchen just to focus, it's like is it a tool developed in Ruby for testing puppet or things like that?
I didn't know that it was possible to to use it. Thank you, I'll have a... Any more questions? Okay, if there are no more questions, then
please thank Alejandro.