We’ve reached the final chapter in the book, and our journey toward automation mastery is almost complete. In this last chapter we’ll cover some miscellaneous tips that can help us when we work with CloudForms Automate.
When a minor update to CloudForms Management Engine is released and installed (e.g., 5.5.0 → 5.5.2), any changes to the Automate code are not automatically visible to the Automate Explorer.
Go to Import/Export, and “Reset all Datastore custom classes and instances to default” to get the updates added and visible (see Figure 47-1).
This does not, as the wording might suggest, reset our custom domains; it merely reloads the ManageIQ and RedHat domains.
There is a ManageIQ Coding Style and Standards Guide and a Ruby Style Guide. Although the guides don’t specifically refer to Automate coding style (they’re more a guideline for ManageIQ code development), we can adopt the recommendations to keep our code clean and standards-compliant.
The guides recommend using snake_case for symbols, methods, and variables, and CamelCase for classes and modules. Although this doesn’t explicitly refer to Automate Datastore classes and methods, we can adopt the same guidelines for our code.
The style guide doesn’t currently mention whether we should name instances in CamelCase or snake_case. Although the examples in this book have used CamelCase naming for instances, it is likely that future versions of CloudForms will standardize on snake_case naming for both instances and methods.
The dynamic nature of the object structure means that we have to be more careful about testing for nil
conditions, testing whether hash keys exist before we access them, testing whether variables are enumerable before we call each
on them, and so on.
Some examples are:
if
this_object
.
respond_to?
(
:attributes
)
if
this_object
.
attributes
.
respond_to?
:each
this_object
.
attributes
.
each
do
|
key
,
value
|
.
.
.
user
=
$evm
.
root
[
'user'
]
rescue
nil
unless
user
.
nil?
.
.
.
prov
=
$evm
.
root
[
'miq_provision'
]
if
prov
.
options
.
key?
(
:ws_values
)
ws_values
=
prov
.
options
[
:ws_values
]
.
.
.
As an extension of the tip “Defensive Programming”, we should also catch and handle exceptions wherever possible in our scripts. We have seen several examples of this in the scripts that we’ve studied in the book—for example:
begin
.
.
.
rescue
RestClient
:
:Exception
=>
err
unless
err
.
response
.
nil?
error
=
err
.
response
$evm
.
log
(
:error
,
"The REST request failed with code:
#{
error
.
code
}
"
)
$evm
.
log
(
:error
,
"The response body was:
#{
error
.
body
.
inspect
}
"
)
$evm
.
root
[
'ae_reason'
]
=
"The REST request failed with code:
#{
error
.
code
}
"
end
$evm
.
root
[
'ae_result'
]
=
'error'
exit
MIQ_STOP
rescue
=>
err
$evm
.
log
(
:error
,
"[
#{
err
}
]
#{
err
.
backtrace
.
join
(
"
"
)
}
"
)
$evm
.
root
[
'ae_reason'
]
=
"Unspecified error, see automation.log for backtrace"
$evm
.
root
[
'ae_result'
]
=
'error'
exit
MIQ_STOP
end
There isn’t any version control yet, although Git integration for the Automate Datastore is in development for a future release of CloudForms. In the meantime we should use our own Git repository, but this is a manual process, unfortunately.
Several of Red Hat’s United States consultants have created an open source project for handling version control and continuous integration (CI) of CloudForms artifacts, such as Automate code and dialogs, across regions.1
The CI workflow is created using Jenkins. It provides a pipeline view that allows us to visualize which version of any of the artifacts is in any region at a given time. We can implement regions as lifecycle stages in our development process—such as DEV, TEST, and QA—and promote code through the lifecycle as our testing progresses (see Figure 47-2).
We have seen several examples in the book in which system credentials have been retrieved from an instance schema, using $evm.object['attribute']
.
When we work on larger projects and implement some kind of version control as previously described, we will have separate CloudForms installations for our various automation code lifecycle environments—DEV, TEST, and QA, for example. It is likely (and good practice) that the credentials to connect to our various integration services will be different for each lifecycle environment, but we want to be able to promote our code through each environment with minimal change.
In this case it can be useful to create a separate configuration domain for each lifecycle environment, containing purely the classes and instances that define the usernames, passwords, or URLs specific to that environment. The configuration domain typically contains no methods; these are in the code domain being tested. When a method calls $evm.object['attribute']
, the attribute is retrieved from the running instance in the configuration domain, which has the highest priority.
The process of testing then becomes simpler as we cycle the code domain through each lifecycle environment, without having to modify any credentials; these are statically defined in the configuration domain. The process is illustrated in Table 47-1.
Sprints/environments | DEV | TEST | Q/A | PROD |
---|---|---|---|---|
Sprint1 |
Dev + Code_v4 domains |
Test + Code_v3 domains |
QA + Code_v2 domains |
Prod + Code_v1 domains |
Sprint2 |
Dev + Code_v5 domains |
Test + Code_v4 domains |
QA + Code_v3 domains |
Prod + Code_v2 domains |
Sprint3 |
Dev + Code_v6 domains |
Test + Code_v5 domains |
QA + Code_v4 domains |
Prod + Code_v3 domains |
This completes our study of the Automate capability of Red Hat CloudForms. Over the preceding chapters we have learned about the Automate Datastore and the entities that we use to create our automation scripts. We have taken a look behind the scenes at the objects that we work with and learned about their attributes, virtual columns, associations, and methods.
We discovered how these components come together to create the workflows that provision infrastructure virtual machines and cloud instances, and we have seen examples of how we can customize the provisioning state machines for our own purposes.
We created service catalogs to deploy servers both singly and in bundles, and we integrated our Automate workflows with an external Red Hat Satellite 6.1 server.
We have seen how CloudForms is able to manage our entire virtual machine lifcycle, including retirement, and we have studied the retirement process for virtual machines and services.
We looked at the integration capabilities of CloudForms Automate and saw how easily we can integrate our automation workflows with our wider enterprise.
Our journey toward automation mastery is now complete. All that is left is to practice, and start automating!
3.135.201.217