-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Peter McGowan
committed
Dec 12, 2016
0 parents
commit 15eeeb8
Showing
650 changed files
with
18,092 additions
and
0 deletions.
There are no files selected for viewing
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
# <center>Mastering Automation in CloudForms 4.1 and ManageIQ Darga</center> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
# Summary | ||
|
||
* [Introduction](README.md) | ||
* [Preface](preface.asciidoc.wip) | ||
* [Part 1](part1.asciidoc) | ||
* [Introduction to CloudForms and ManageIQ](introduction/chapter.asciidoc) | ||
* [Introduction to the Automate Datastore](introduction_to_the_automate_datastore/chapter.asciidoc) | ||
* [Writing and Running Our Own Automation Scripts](writing_running_our_own_automation_scripts/chapter.asciidoc) | ||
* [Using Schema Variables](using_schema_variables/chapter.asciidoc) | ||
* [Working with Virtual Machines](working_with_virtual_machines/chapter.asciidoc) | ||
* [Peeping Under the Hood](peeping_under_the_hood/chapter.asciidoc) | ||
* [$evm and the Workspace](evm_and_the_workspace/chapter.asciidoc) | ||
* [A Practical Example: Enforcing Anti-Affinity Rules](enforcing_anti_affinity_rules/chapter.asciidoc) | ||
* [Using Tags from Automate](using_tags_from_automate/chapter.asciidoc) | ||
* [Investigative Debugging](investigative_debugging/chapter.asciidoc) | ||
* [Ways of Entering Automate](ways_of_entering_automate/chapter.asciidoc) | ||
* [Requests and Tasks](requests_and_tasks/chapter.asciidoc) | ||
* [State Machines](state_machines/chapter.asciidoc) | ||
* [More Advanced Schema and Instance Features](more_advanced_schema_features/chapter.asciidoc) | ||
* [Event Processing](event_processing/chapter.asciidoc) | ||
* [Part 2](part2.asciidoc) | ||
* [Provisioning a Virtual Machine](provisioning_a_virtual_machine/chapter.asciidoc) | ||
* [The Provisioning Profile](the_provisioning_profile/chapter.asciidoc) | ||
* [Approval](provisioning_approval/chapter.asciidoc) | ||
* [Quota Management](provisioning_quota_management/chapter.asciidoc) | ||
* [The Options Hash](the_options_hash/chapter.asciidoc) | ||
* [The Provisioning State Machine](vm_provision_state_machine/chapter.asciidoc) | ||
* [Customising Virtual Machine Provisioning](customising_vm_provisioning/chapter.asciidoc) | ||
* [Virtual Machine Naming During Provisioning](vm_naming_during_provisioning/chapter.asciidoc) | ||
* [Virtual Machine Placement During Provisioning](vm_placement_during_provisioning/chapter.asciidoc) | ||
* [The Provisioning Dialog](the_provisioning_dialog/chapter.asciidoc) | ||
* [Virtual Machine Provisioning Objects](vm_provisioning_objects/chapter.asciidoc) | ||
* [Creating Provisioning Requests Programmatically](creating_provisioning_requests_programmatically/chapter.asciidoc) | ||
* [Part 3](part3.asciidoc) | ||
* [Automation Using Ansible](automation_using_ansible/chapter.asciidoc) | ||
* [Tower-Related Automate Components](tower_related_automate_components/chapter.asciidoc) | ||
* [Running an Ansible Tower Job from a Button](running_an_ansible_tower_job_from_a_button/chapter.asciidoc) | ||
* [Integrating with Satellite 6 During Provisioning](integrating_with_satellite_6_during_provisioning/chapter.asciidoc) | ||
* [Part 4](part4.asciidoc) | ||
* [Service Dialogs](service_dialogs/chapter.asciidoc) | ||
* [The Service Provisioning State Machine](the_service_provisioning_state_machine/chapter.asciidoc) | ||
* [Catalog{Item,Bundle}Initialization](catalogitembundleinitialization/chapter.asciidoc) | ||
* [Approval and Quota](service_approval_and_quota/chapter.asciidoc) | ||
* [Creating a Service Catalog Item](creating_a_service_catalog_item/chapter.asciidoc) | ||
* [Creating a Service Catalog Bundle](creating_a_service_catalog_bundle/chapter.asciidoc) | ||
* [Ansible Tower Services](ansible_tower_services/chapter.asciidoc) | ||
* [Creating an Ansible Tower Service Catalog Item and Bundle](creating_an_ansible_tower_service_catalog_item_and_bundle/chapter.asciidoc) | ||
* [Service Objects](service_objects/chapter.asciidoc) | ||
* [Log Analysis During Service Provisioning](log_analysis_during_service_provisioning/chapter.asciidoc) | ||
* [Service Hierarchies](service_hierarchies/chapter.asciidoc) | ||
* [(placeholder) Service Reconfiguration](service_reconfiguration/chapter.asciidoc.wip) | ||
* [Service Tips and Tricks](service_tips_and_tricks/chapter.asciidoc) | ||
* [Part 5](part5.asciidoc) | ||
* [Virtual Machine and Instance Retirement](vm_instance_retirement/chapter.asciidoc) | ||
* [Service Retirement](service_retirement/chapter.asciidoc) | ||
* [Part 6](part6.asciidoc) | ||
* [Calling Automation Using the RESTful API](calling_automation_from_the_restful_api/chapter.asciidoc) | ||
* [Automation Request Approval](automation_request_approval/chapter.asciidoc) | ||
* [Calling External Services](calling_external_services/chapter.asciidoc) | ||
* [Part 7](part7.asciidoc) | ||
* [Tenancy and Automate](tenancy_and_automate/chapter.asciidoc) | ||
* [Distributed Automation Processing](distributed_automation_processing/chapter.asciidoc) | ||
* [Argument Passing and Handling](argument_passing_and_handling/chapter.asciidoc) | ||
* [(placeholder) Writing Testable Code](writing_testable_code/chapter.asciidoc.wip) | ||
* [Miscellaneous Tips](miscellaneous_tips/chapter.asciidoc) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,247 @@ | ||
[[ansible-tower-services]] | ||
== Ansible Tower Services | ||
|
||
One of the available catalog item types when we create a new service item is *AnsibleTower* (see <<i1>>) | ||
|
||
[[i1]] | ||
.Ansible Tower catalog item type | ||
image::images/ss1.png[Screenshot,500,align="center"] | ||
{zwsp} + | ||
|
||
In this chapter we'll investigate the Automate datastore components that allow us to create Ansible Tower services and service bundles that include Ansible Tower jobs. | ||
|
||
=== The Ansible Tower Service Provisioning State Machine | ||
|
||
The _/ConfigurationManagement/AnsibleTower/Service/Provisioning_ namespace in the datastore contains the service provisioning state machines, methods and associated email classes that are required to provisioning services into Ansible Tower (see <<i2>>). | ||
|
||
[[i2]] | ||
.ConfigurationManagement/AnsibleTower namespace | ||
image::images/ss2.png[Screenshot,320,align="center"] | ||
{zwsp} + | ||
|
||
The two out-of-the-box instances of the _Provision_ state machine are _default_ and __provision_from_bundle__. We use _default_ when we're creating a single standalone service, and __provision_from_bundle__ when we're running an Ansible Tower job as part of a service bundle comprising both VM provisioning and Ansible configuration operations. | ||
|
||
==== The _default_ State Machine Instance | ||
|
||
The _default_ state machine instance is called to process individual service catalog items. The fields of this state machine are shown in <<i3>>. | ||
|
||
[[i3]] | ||
.Fields of the default state machine | ||
image::images/ss3.png[Screenshot,800,align="center"] | ||
{zwsp} + | ||
|
||
===== pre1 | ||
|
||
The *pre1* state calls the _preprovision_ method, that checks whether the inputs are valid, and prints some of the input values to _automation.log_. It contains a useful method called __modify_job_options__ that by default is not called (the call is commented out), but would allow us to customise any of the job options if we wished to clone and edit the method. | ||
|
||
[source,ruby] | ||
---- | ||
def modify_job_options(service) | ||
# Example how to programmatically modify job options: | ||
job_options = service.job_options | ||
job_options[:limit] = 'someHost' | ||
job_options[:extra_vars]['flavor'] = 'm1.small' | ||
# Important: set stack_options | ||
service.job_options = job_options | ||
end | ||
---- | ||
|
||
===== provision | ||
|
||
The *provision* state calls the _provision_ method, which performs some preliminary checking before calling the service object's `launch_job` method. | ||
|
||
===== checkprovisioned | ||
|
||
The *checkprovisioned* state calls the __check_provisioned__ method, which calls the service object's `job` method to retrieve the ManageIQ_Providers_AnsibleTower_ConfigurationManager_Job object, and then calls the `normalized_live_status` job method to retrieve the current job status. | ||
|
||
===== post1 | ||
|
||
The *post1* state calls the __post_provisioned__ method which allows us to perform any optional post-processing that we might deem necessary. It contains a useful method called __dump_job_outputs__ that by default is not called (the call is commented out), but would allow us to write the job output to _automation.log_ if required. | ||
|
||
[source,ruby] | ||
---- | ||
def dump_job_outputs(job) | ||
log_type = job.status == 'failed' ? 'error' : 'info' | ||
@handle.log(log_type, "Ansible Tower Job #{job.name} standard output: #{job.raw_stdout}") | ||
end | ||
---- | ||
|
||
===== EmailOwner | ||
|
||
The *EmailOwner* state calls the __ServiceProvision_complete__ email instance to notify the service requester that the service has completed. | ||
|
||
===== Finished | ||
|
||
The *Finished* state calls the __/System/CommonMethods/StateMachineMethods/service_provision_finished__ instance to terminate the service provision state machine processing. | ||
|
||
==== The __provision_from_bundle__ State Machine Instance | ||
|
||
The __provision_from_bundle__ state machine instance is called when an Ansible service catalog item is to be called from a service bundle after a VM provisioning service catalog item. The fields of this state machine are shown in <<i4>>. | ||
|
||
[[i4]] | ||
.Fields of the provision_from_bundle state machine | ||
image::images/ss4.png[Screenshot,800,align="center"] | ||
{zwsp} + | ||
|
||
As can be seen, the difference between this state machine and _default_ is that _preprovision_ has moved to the *pre2* state, and there are new relationships in the *sequencer* and *pre1* states to call _GroupSequenceCheck_ and _CatalogItemInitialization_. | ||
|
||
===== Sequencer | ||
|
||
The *Sequencer* state calls the same _GroupSequenceCheck_ instance and method that the VM provision state machines run. The _GroupSequenceCheck_ method checks the eligibility of the current service template provisioning task to run, according to the provision order defined when the resources were added to the service bundle. _GroupSequenceCheck_ allows the state machine to continue if all other tasks with a lower provisioning priority have a `state` attribute of "finished". If any of the lower priority tasks are incomplete, _GroupSequenceCheck_ exits with a state retry and a retry interval of one minute. | ||
|
||
The common call to _GroupSequenceCheck_ made by both VM provisioning and AnsibleTower job state machines allows us to interleave VM provisioning service items with Ansible configuration service items. We can be sure that the Ansible configuration will not proceed until the virtual machine has been fully provisioned. | ||
|
||
===== pre1 | ||
|
||
The *pre1* state calls calls the same _CatalogItemInitialization_ instance and method that the VM provision state machines run. This is to ensure that any service dialog values passed into the service bundle are available to the Ansible service template provisioning task. | ||
|
||
=== Service Models | ||
|
||
The Ansible-related service model that is of interest to us is the MiqAeServiceServiceAnsibleTower object. | ||
|
||
==== MiqAeServiceServiceAnsibleTower | ||
|
||
The MiqAeServiceServiceAnsibleTower object represents an Ansible Tower service. An object_walker printout of a typical object is as follows: | ||
|
||
|
||
``` | ||
--- attributes follow --- | ||
service.ancestry = nil | ||
service.created_at = 2016-12-01 11:11:00 UTC | ||
service.description = Install a Simple LAMP Stack | ||
service.display = true | ||
service.evm_owner_id = 1 | ||
service.guid = d709ae06-b7b6-11e6-b465-001a4aa0151a | ||
service.id = 5 | ||
service.miq_group_id = 2 | ||
service.name = Simple LAMP Stack | ||
service.options[:dialog] = {"dialog_limit"=>"lampsrv001", "dialog_param_ntpserver"=>"192.168.xx.xx", "dialog_param_mysql_port"=>"3306", "dialog_param_dbname"=>"foodb", "dialog_param_dbuser"=>"foouser", "dialog_param_dbpass"=>"secret", "dialog_param_httpd_port"=>"80", "dialog_param_repository"=>"https://github.com/pemcg/mywebapp.git"} | ||
service.retired = nil | ||
service.retirement_last_warn = nil | ||
service.retirement_requester = nil | ||
service.retirement_state = nil | ||
service.retirement_warn = nil | ||
service.retires_on = nil | ||
service.service_template_id = 2 | ||
service.tenant_id = 1 | ||
service.type = ServiceAnsibleTower | ||
service.updated_at = 2016-12-01 11:11:00 UTC | ||
--- end of attributes --- | ||
--- virtual columns follow --- | ||
service.aggregate_all_vm_cpus = 0 | ||
service.aggregate_all_vm_disk_count = 0 | ||
service.aggregate_all_vm_disk_space_allocated = 0 | ||
service.aggregate_all_vm_disk_space_used = 0 | ||
service.aggregate_all_vm_memory = 0 | ||
service.aggregate_all_vm_memory_on_disk = 0 | ||
service.aggregate_direct_vm_cpus = 0 | ||
service.aggregate_direct_vm_disk_count = 0 | ||
service.aggregate_direct_vm_disk_space_allocated = 0 | ||
service.aggregate_direct_vm_disk_space_used = 0 | ||
service.aggregate_direct_vm_memory = 0 | ||
service.aggregate_direct_vm_memory_on_disk = 0 | ||
service.custom_1 = nil | ||
service.custom_2 = nil | ||
service.custom_3 = nil | ||
service.custom_4 = nil | ||
service.custom_5 = nil | ||
service.custom_6 = nil | ||
service.custom_7 = nil | ||
service.custom_8 = nil | ||
service.custom_9 = nil | ||
service.evm_owner_email = nil | ||
service.evm_owner_name = Administrator | ||
service.evm_owner_userid = admin | ||
service.has_parent = false | ||
service.owned_by_current_ldap_group = nil | ||
service.owned_by_current_user = nil | ||
service.owning_ldap_group = EvmGroup-super_administrator | ||
service.power_state = nil | ||
service.power_status = nil | ||
service.region_description = Region 0 | ||
service.region_number = 0 | ||
service.service_id = nil | ||
service.v_total_vms = 0 | ||
--- end of virtual columns --- | ||
--- associations follow --- | ||
service.all_service_children | ||
service.direct_service_children | ||
service.direct_vms | ||
service.indirect_service_children | ||
service.indirect_vms | ||
service.parent_service | ||
service.root_service | ||
service.service_resources | ||
service.service_template | ||
service.tenant | ||
service.vms | ||
--- end of associations --- | ||
--- methods follow --- | ||
service.automate_retirement_entrypoint | ||
service.configuration_manager | ||
service.custom_get | ||
service.custom_keys | ||
service.custom_set | ||
service.description= | ||
service.dialog_options | ||
service.display= | ||
service.error_retiring? | ||
service.extend_retires_on | ||
service.finish_retirement | ||
service.get_dialog_option | ||
service.group= | ||
service.inspect | ||
service.inspect_all | ||
service.job | ||
service.job_options | ||
service.job_options= | ||
service.job_template | ||
service.job_template= | ||
service.launch_job | ||
service.model_suffix | ||
service.name= | ||
service.owner= | ||
service.parent_service= | ||
service.reload | ||
service.remove_from_vmdb | ||
service.retire_now | ||
service.retire_service_resources | ||
service.retired? | ||
service.retirement_state= | ||
service.retirement_warn= | ||
service.retires_on= | ||
service.retiring? | ||
service.set_dialog_option | ||
service.shutdown_guest | ||
service.start | ||
service.start_retirement | ||
service.stop | ||
service.suspend | ||
service.tag_assign | ||
service.tag_unassign | ||
service.tagged_with? | ||
service.tags | ||
--- end of methods --- | ||
``` | ||
|
||
The object is an extension of the standard MiqAeServiceService object type, but adds several useful Ansible-specific methods, as follows: | ||
|
||
``` | ||
service.configuration_manager | ||
service.job | ||
service.job_options | ||
service.job_options= | ||
service.job_template | ||
service.job_template= | ||
service.launch_job | ||
``` | ||
|
||
It is the `launch_job` method that is called during the state machine *provision* state to initiate the running of the Ansible Tower job. | ||
|
||
=== Summary | ||
|
||
The chapter has completed our examination of the Tower-related components in the Automate datastore that we started in link:../tower_related_automate_components/chapter.asciidoc[Tower Related Automate Components]. The state machines, instances and methods that we've studied here are used when we create services to deploy Ansible configuration scripts. | ||
|
||
In the next chapter we'll run through two examples of creating Ansible Tower services; one for a single catalog item, and another as part of a catalog bundle. | ||
|
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Oops, something went wrong.