Guillaume Coré
2019-03-01 70c58e1bae57480fa629edf799aebd29d0e509c3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
:toc2:
image::https://travis-ci.org/redhat-cop/agnosticd.svg?branch=development[link="https://travis-ci.org/redhat-cop/agnosticd"]
 
= Introduction: Writing Configs
 
This document gives an overview of the process of writing either a new _config_ 
 from scratch or copying and modifying an existing _config_.
Well designed _configs_, can easily and *cleanly* be abstracted to allow 
 deployment to multiple different Public and Private Clouds including AWS, 
  Azure.
 
=== What are _configs_?
 
A _config_ is simply a lab, workshop, or other deployment that has been defined 
 and encapsulated in a series of playbooks, variable files, and templates in a
  _config_ directory.
This allows _Ansible Agnostic Deployer_ to deploy it simply and repeatedly on
 one or more Cloud Platforms.
 
=== How you Deploy _configs_
 
_configs_ are typically deployed via one of 3 methods:
 
. From the command line. A suitably configured Ansible Control Node, or
 laptop, can invoke a new _config_ deployment by invoking 
  `ansible-playbook main.yml -e @./configs/<CONFIG_NAME?sample_vars.yml` or other
    variable file with the appropriate parameters. See
     link:../ansible/configs/three-tier-app/README.adoc[Three Tier App]  for an
      example.
 
. Via a front-end application such as Red Hat Cloud Forms or ServiceNow which
 provides a user friendly catalog or "portal" type interface to the end user and
  can invoke the appropriate ansible command directly or via a "wrapper" script.
 
. It is also possible to invoke a _config_ by creating *AgnosticD* as an Ansible
 Tower Project and defining _configs_ as jobs. Going forward this pattern will
  influence the future evolution of *AgnosticD*.  Once a _config_ is defined as
   a job it can either be directly invoked or via a front-end application or 
    script making an API call to an Ansible Tower server.
 
=== How *AgnosticD* Deploys _configs_
 
*AgnosticD* deploys _configs_ via a 6 stage process, discussed in more detail
 below.
This provides _config_ creators considerable flexibility, without undue 
 complexity, to control the deployment process in a modular manner and enables
  you to abstract the Cloud Specific steps (e.g. *AWS ec2* or *Microsoft Azure*)
   from the application or OS specific steps. Greatly enhancing Cloud Portability.
 
 
The last point is key, as it allows developers to simply add new Cloud Platforms
 at a latter date, or provide their _configs_ with multi-cloud support from day 1.
The term *Cloud Provider* includes the ability to add a virtualization platform 
 (e.g. KVM, Hyper-V), Public Cloud Platform (e.g. Google Cloud Engine), or a 
  container based platform such as OpenShift or Docker.
 
Currently supported platforms (via Cloud Providers):
 
* AWS EC2
* Azure
 
==== Overview of Ansible Agnostic Deployer Flow
 
When ansible starts to deploy a _config_ the process involves 2 logically 
 distinct phases, Infrastructure and Software, each broken up into 3 Steps.
  This is illustrated below:
 
image::./images/agnosticd_flow.png[width=100%]
 
 
AAD deployments start by invoking a common `main.yml` with an environmental
 variable file identifying the cloud platform to deploy plus other meta-data.
 
e.g. `ansible-playbook main.yml -e @configs/three-tier-app/sample_vars.yml`
 
.Simplified execution flow of `main.yml`
[source,bash]
----
- import_playbook: "configs/{{ env_type }}/pre_infra.yml"
- import_playbook: "cloud_providers/{{ cloud_provider }}_infrastructure_deployment.yml"
- import_playbook: "configs/{{ env_type }}/post_infra.yml"
- import_playbook: "configs/{{ env_type }}/pre_software.yml"
- import_playbook: "configs/{{ env_type }}/software.yml"
- import_playbook: "configs/{{ env_type }}/post_software.yml"
----
 
For _config_ developers the above stages provide 5 _hooks_ for customizing the
 configuration of your environment and 1 _hook_ for customizing it for one or
  more cloud providers (e.g. AWS, Azure, etc).
 
An _example config_ is provided by `ansible/configs/just-some-nodes-example`
 
==== Stage 0 `pre_infra.yml`
 
 
In this stage *AAD* is the entry playbook and is typical used for setting up
 any infrastructure etc prior to launching a cloud deployment. Typical tasks
  could include:
 
* Creating necessary ssh keys
* Moving any ssh keys into place, setting permissions etc
* Creating any payloads to be used in later stages e.g. repo files etc
* Ensuring cloud credentials are available 
 
 
==== Stage 1 Cloud Provider Deploy
 
This stage is unique in the flow in that the _config_ creator doesn't supply a 
 playbook but typically has to provide cloud specific configuration data.
 
Clouds are selected via the value of the `cloud_provider` variable and supported
 clouds can be found in `ansible/cloud_providers`. Currently supported are:
 
* Amazon Web Services (AWS)
* Microsoft Azure
 
Example: *AWS* configs use CloudFormations templates to deploy their
 infrastructure so this can be provided. Take a look at Three Tier Apps
  link:../ansible/configs/three-tier-app/files/cloud_providers/ec2_cloud_template.j2[Cloud Formation Template].
   Notice it is written in Jinja2 and can easily be extended to deploy more, or
    less servers, plus you can change the Operating Systems, software payloads
     etc. This is done by overriding the default variables found in 
      link:../ansible/configs/three-tier-app/env_vars.yml[`env_vars.yml`]. 
 
[NOTE]
====
A Cloud Creators document exists to facilitate adding further clouds to *AAD*. Wish
list items include:
 
* OpenShift
* OpenStack
* Google Cloud Engine (GCE)
====
 
 
==== Stage 2 `post_infra.yml`
 
In this stage *AgnosticD* can execute any _"post infrastructure"_ tasks. It is 
 not uncommon for this phase to do nothing but it provides a convenient hook for
  any tasks that may need to be run after building your Cloud Infrastructure. For
   example running any smoke tests that may be required.
 
==== Stage 3 `pre_software.yml`
 
At this point the infrastructure should be up and running but typically in a
 un-configured state. This stage provides a convenient hook for running any tasks
  that may be needed before software payload deployment. For example"
 
* Running any pre software tests
* Setup software dependant yum repos or equivalent
* Retrieving any licenses etc.
* `ssh` key housekeeping - for example inserting additional keys and configuration
* Prepare `bastion` hosts or `jumpboxes`
 
==== Stage 4 `software.yml`
 
In this stage *AgnosticD* deploys any software payloads onto the infrastructure.
 This could be as simple as installing Apache or as complex as installing and
  configuring an N-tier application.
 
==== Stage 5 `post_software.yml`
 
In the final stage *AgnosticD* would typically perform a number of tasks including:
 
* Any cleanup from the prior stages
* Any end to end or component testing
* User notification of the running configuration 
 
 
== Overview of a Typical _Config_
 
_Configs_ are located in the `ansible/configs/` directory:
 
[source,bash]
----
README.adoc              linklight                 ocp-ha-disconnected-lab   quay-enterprise
ans-tower-lab            linklight-demo            ocp-ha-lab                rhte-ansible-net
ansible-cicd-lab         linklight-engine          ocp-implementation-lab    rhte-lb
ansible-provisioner      linklight-foundations     ocp-multi-cloud-example   rhte-oc-cluster-vms
archive                  linklight-networking      ocp-storage-cns           rhte-ocp-workshop
bu-workshop              linklight-networking-all  ocp-workloads             simple-multi-cloud
just-some-nodes-example  ocp-clientvm              ocp-workshop              three-tier-app
lightbulb                ocp-gpu-single-node       openshift-demos
----
_Above configs subject to change over time_
 
A typical _Config_ is well illustrated by link:../ansible/configs/three-tier-app/[Three Tier App]. 
 
[source,bash]
----
three-tier-app
├── README.adoc           # Config specific README
├── destroy_env.yml       # Teardown playbook to remove the config when finished
├── env_vars.yml          # Default vars containing configuration variables
├── files                 # Sub-directory for templates, cloud provider files etc
├── pre_infra.yml         # Stage 0 Playbook
├── post_infra.yml        # Stage 2 Playbook
├── pre_software.yml      # Stage 3 Playbook
├── software.yml          # Stage 4 Playbook
├── post_software.yml     # Stage 5 Playbook
├── sample_vars.yml       # Sample user supplied vars (cloud provider, ids etc)
└── topology.png          # Optional topology diagram
----
 
image::../ansible/configs/three-tier-app/topology.png[width=100%]