Skip to content

Commit 5c3b33b

Browse files
authored
Add Terraform deployment engine for cloud resources (#56)
* Add Terraform templates for AWS infra and roles * Update infrastructure and platform roles to execute Terraform tasks * Push Terraform template and workspace variables to common * Add S3 remote state for Terraform * Create timestamped artefact of the generated Terraform files * Refactor download of AWS policy docs to initialize * Add validation of variables used for Terraform * Update Terraform infra templates for L0, L1 and L2 networking Signed-off-by: Jim Enright <[email protected]>
1 parent 5e6c978 commit 5c3b33b

36 files changed

+1526
-45
lines changed

roles/common/defaults/main.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ common__ngw_suffix: "{{ globals.labels.nat_gateway | defau
5757
common__unique_storage_name_suffix: "{{ globals.storage.name | default((common__region + common__aws_profile) if 'aws' in common__infra_type else common__region) }}"
5858

5959
# Infra
60+
common__infra_deployment_engine: "{{ globals.infra_deployment_engine | default('ansible') }}"
6061
common__infra_type: "{{ globals.infra_type | default('aws') }}"
6162
common__public_key_file: "{{ globals.ssh.public_key_file | default('') }}"
6263
common__namespace_cdp: "{{ globals.namespace_cdp | default([common__namespace, common__namespace_unique_suffix] | join('-')) }}"
@@ -66,6 +67,20 @@ common__public_key_text: "{{ globals.ssh.public_key_text | defa
6667
common__region: "{{ globals.region | default(common__region_default[common__infra_type]) }}"
6768
common__storage_name: "{{ infra.storage.name | default([common__namespace, common__unique_storage_name_suffix[::2] | replace('-','')] | join('-')) }}"
6869

70+
# Terraform
71+
common__terraform_base_dir: "{{ globals.terraform_base_dir | default( [playbook_dir , 'terraform'] | path_join ) }}"
72+
# The processed Jinja template files for Terraform are placed in common__terraform_template_dir
73+
common__terraform_template_dir: "{{ [common__terraform_base_dir , 'processed_template_code'] | path_join }}"
74+
# A timestamped artefact directory storing a copy of the Terraform code from each run
75+
common__terraform_artefact_dir: "{{ [common__terraform_base_dir , ('tf_artefacts_' + ansible_date_time.iso8601 ) ] | path_join | regex_replace(':','_')}}"
76+
# Terraform apply/destroy run from under this directory
77+
common__terraform_workspace_dir: "{{ [common__terraform_base_dir, 'workspace'] | path_join }}"
78+
79+
common__terraform_allowed_state_storage: "['local', 'remote_s3']"
80+
common__terraform_state_storage: "{{ globals.terraform_state_storage | default('local') }}"
81+
common__terraform_remote_state_bucket: "{{ globals.terraform_remote_state_bucket | default('') }}"
82+
common__terraform_remote_state_lock_table: "{{ globals.terraform_remote_state_lock_table | default('') }}"
83+
6984
common__vpc_name: "{{ infra.vpc.name | default([common__namespace, common__vpc_name_suffix] | join('-')) }}"
7085
common__vpc_public_subnet_cidrs: "{{ infra.vpc.public_subnets | default(['10.10.0.0/19', '10.10.32.0/19', '10.10.64.0/19']) }}"
7186
common__vpc_private_subnet_cidrs: "{{ infra.vpc.private_subnets | default(['10.10.96.0/19', '10.10.128.0/19', '10.10.160.0/19']) }}"

roles/infrastructure/defaults/main.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,18 @@ infra__vpc_svcnet_suffix: "{{ common__vpc_svcnet_suffix }}"
2626
infra__vpc_private_subnets_suffix: "{{ common__vpc_private_subnets_suffix }}"
2727
infra__vpc_public_subnets_suffix: "{{ common__vpc_public_subnets_suffix }}"
2828

29+
# Deployment type
30+
infra__deployment_engine: "{{ common__infra_deployment_engine }}"
31+
# Location of output from template module which creates Terraform
32+
infra__terraform_template_dir: "{{ common__terraform_template_dir }}"
33+
infra__terraform_artefact_dir: "{{ common__terraform_artefact_dir }}"
34+
infra__terraform_workspace_dir: "{{ common__terraform_workspace_dir }}"
35+
36+
infra__terraform_allowed_state_storage: "{{ common__terraform_allowed_state_storage }}"
37+
infra__terraform_state_storage: "{{ common__terraform_state_storage }}"
38+
infra__terraform_remote_state_bucket: "{{ common__terraform_remote_state_bucket }}"
39+
infra__terraform_remote_state_lock_table: "{{ common__terraform_remote_state_lock_table }}"
40+
2941
# Infra
3042
infra__type: "{{ common__infra_type }}"
3143
infra__tunnel: "{{ common__tunnel }}"
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# Copyright 2021 Cloudera, Inc. All Rights Reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
- name: Create directory for processed Terraform template files
16+
ansible.builtin.file:
17+
path: "{{ infra__terraform_template_dir }}/infra"
18+
state: directory
19+
20+
- name: Create artefact directory for Terraform infra code
21+
ansible.builtin.file:
22+
path: "{{ infra__terraform_artefact_dir }}/infra"
23+
state: directory
24+
25+
# Apply template for Terraform provider
26+
- name: Generate Terraform Provider
27+
ansible.builtin.template:
28+
src: 'template/{{ infra__type }}/provider.tf.j2'
29+
dest: "{{ infra__terraform_template_dir }}/infra/provider.tf"
30+
31+
# Apply template for Terraform backend state
32+
- name: Generate Terraform Backend State
33+
ansible.builtin.template:
34+
src: 'template/{{ infra__type }}/backend_state.tf.j2'
35+
dest: "{{ infra__terraform_template_dir }}/infra/backend_state.tf"
36+
37+
# Apply template for Terraform variables
38+
- name: Generate Terraform Variables
39+
ansible.builtin.template:
40+
src: 'template/{{ infra__type }}/terraform_variables.tf.j2'
41+
dest: "{{ infra__terraform_template_dir }}/infra/variables.tf"
42+
no_log: false
43+
44+
# Apply template for Terraform infra....
45+
# ...network resources
46+
- name: Generate Terraform infra file for network resources
47+
ansible.builtin.template:
48+
src: 'template/{{ infra__type }}/infra_{{ infra__type }}_network.tf.j2'
49+
dest: "{{ infra__terraform_template_dir }}/infra/infra_network.tf"
50+
no_log: false
51+
52+
# ...storage resources
53+
- name: Generating Terraform infra file for storage resources
54+
ansible.builtin.template:
55+
src: 'template/{{ infra__type }}/infra_{{ infra__type }}_storage.tf.j2'
56+
dest: "{{ infra__terraform_template_dir }}/infra/infra_storage.tf"
57+
no_log: false
58+
59+
# ...compute resources
60+
- name: Generating Terraform infra file for compute resources
61+
ansible.builtin.template:
62+
src: 'template/{{ infra__type }}/infra_{{ infra__type }}_compute.tf.j2'
63+
dest: "{{ infra__terraform_template_dir }}/infra/infra_compute.tf"
64+
no_log: false

roles/infrastructure/tasks/initialize_setup.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,8 @@
2222
ansible.builtin.include_tasks: "initialize_{{ infra__type | lower }}.yml"
2323

2424
- name: Include tasks fpr provider-specific Infrastructure setup initialization
25-
ansible.builtin.include_tasks: "initialize_setup_{{ infra__type | lower }}.yml"
25+
ansible.builtin.include_tasks: "initialize_setup_{{ infra__type | lower }}.yml"
26+
27+
- name: Include Terraform tasks for provider-specific Infrastructure initialization
28+
ansible.builtin.include_tasks: "initialize_{{ infra__type | lower }}_{{ infra__deployment_engine }}.yml"
29+
when: infra__deployment_engine == 'terraform'

roles/infrastructure/tasks/initialize_teardown.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,8 @@
2121
ansible.builtin.include_tasks: "initialize_{{ infra__type | lower }}.yml"
2222

2323
- name: Include tasks for provider-specific Infrastructure teardown initialization
24-
ansible.builtin.include_tasks: "initialize_teardown_{{ infra__type | lower }}.yml"
24+
ansible.builtin.include_tasks: "initialize_teardown_{{ infra__type | lower }}.yml"
25+
26+
- name: Include Terraform tasks for provider-specific Infrastructure teardown initialization
27+
ansible.builtin.include_tasks: "initialize_teardown_{{ infra__type | lower }}_{{ infra__deployment_engine }}.yml"
28+
when: infra__deployment_engine == 'terraform'
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Copyright 2021 Cloudera, Inc. All Rights Reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
- name: Create directory for processed Terraform template files
16+
ansible.builtin.file:
17+
path: "{{ infra__terraform_template_dir }}/infra"
18+
state: directory
19+
20+
# Apply template for Terraform provider
21+
- name: Generate Terraform Provider
22+
ansible.builtin.template:
23+
src: 'template/{{ infra__type }}/provider.tf.j2'
24+
dest: "{{ infra__terraform_template_dir }}/infra/provider.tf"
25+
26+
# Apply template for Terraform backend state
27+
- name: Generate Terraform Backend State
28+
ansible.builtin.template:
29+
src: 'template/{{ infra__type }}/backend_state.tf.j2'
30+
dest: "{{ infra__terraform_template_dir }}/infra/backend_state.tf"
31+
32+
# Apply template for Terraform variables
33+
- name: Generate Terraform Variables
34+
ansible.builtin.template:
35+
src: 'template/{{ infra__type }}/terraform_variables.tf.j2'
36+
dest: "{{ infra__terraform_template_dir }}/infra/variables.tf"
37+
no_log: false

roles/infrastructure/tasks/setup.yml

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,25 @@
1919
- name: Set up provider-specific Infrastructure artifacts
2020
ansible.builtin.include_tasks: "setup_{{ infra__type | lower }}.yml"
2121

22-
- name: Set up provider-specific Infrastructure network
23-
ansible.builtin.include_tasks: "setup_{{ infra__type | lower }}_network.yml"
22+
- name: Set up for Ansible deployment engine
23+
when: infra__deployment_engine == 'ansible'
24+
block:
25+
- name: Set up provider-specific Infrastructure network
26+
ansible.builtin.include_tasks: "setup_{{ infra__type | lower }}_network.yml"
2427

25-
- name: Set up provider-specific Infrastructure storage
26-
ansible.builtin.include_tasks: "setup_{{ infra__type | lower }}_storage.yml"
28+
- name: Set up provider-specific Infrastructure storage
29+
ansible.builtin.include_tasks: "setup_{{ infra__type | lower }}_storage.yml"
2730

28-
- name: Set Up localised provider-specific Storage Utility Service
29-
when: infra__create_utility_service
30-
ansible.builtin.include_tasks: "setup_{{ infra__type | lower }}_utility_service.yml"
31+
- name: Set Up localised provider-specific Storage Utility Service
32+
when: infra__create_utility_service
33+
ansible.builtin.include_tasks: "setup_{{ infra__type | lower }}_utility_service.yml"
3134

32-
- name: Set up provider-specific Infrastructure Compute
33-
when: infra__dynamic_inventory_count
34-
ansible.builtin.include_tasks: "setup_{{ infra__type | lower }}_compute.yml"
35+
- name: Set up provider-specific Infrastructure Compute
36+
when: infra__dynamic_inventory_count
37+
ansible.builtin.include_tasks: "setup_{{ infra__type | lower }}_compute.yml"
38+
39+
- name: Set up for Terraform deployment engine
40+
when: infra__deployment_engine == 'terraform'
41+
block:
42+
- name: Set up Terraform Infrastructure artifacts
43+
ansible.builtin.include_tasks: "setup_{{ infra__deployment_engine }}.yml"
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
---
2+
3+
# Copyright 2021 Cloudera, Inc. All Rights Reserved.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
- name: Ensure the Terraform workspace directory exists
18+
ansible.builtin.copy:
19+
src: "{{ infra__terraform_template_dir }}/infra/"
20+
dest: "{{ infra__terraform_workspace_dir }}/infra"
21+
22+
- name: Copy Terraform infra code to the artefact directory
23+
ansible.builtin.copy:
24+
src: "{{ infra__terraform_template_dir }}/infra/"
25+
dest: "{{ infra__terraform_artefact_dir }}/infra"
26+
27+
- name: Applying Terraform
28+
community.general.terraform:
29+
project_path: "{{ infra__terraform_workspace_dir }}/infra"
30+
state: "present"
31+
force_init: yes
32+
register: tf_result
33+
retries: 3
34+
delay: 10
35+
until: tf_result is succeeded
36+
37+
- name: Remove the Terraform template directory
38+
ansible.builtin.file:
39+
path: "{{ infra__terraform_template_dir }}/infra"
40+
state: absent
41+
42+
- name: Remove the Terraform workspace directory when using remote state
43+
ansible.builtin.file:
44+
path: "{{ infra__terraform_workspace_dir }}/infra"
45+
state: absent
46+
when: infra__terraform_state_storage in ['remote_s3']
47+
48+
# Get information about Dynamic Inventory VMs if created via Terraform
49+
- name: Fetch EC2 Instance info for Dynamic Inventory Nodes
50+
register: __infra_dynamic_inventory_discovered
51+
community.aws.ec2_instance_info:
52+
region: "{{ infra__region }}"
53+
filters: "{{ __filters | items2dict }}"
54+
vars:
55+
__filters:
56+
- key: "tag:{{ infra__dynamic_inventory_tag_key }}"
57+
value: "{{ infra__dynamic_inventory_tag_value }}*"
58+
59+
- name: Create output Dictionary for producing Static Inventory artefact
60+
ansible.builtin.set_fact:
61+
infra__dynamic_inventory_host_entries: "{{ infra__dynamic_inventory_host_entries | default([]) | union([host_entry]) }}"
62+
vars:
63+
host_entry: "{{ [__infra_di_item.private_dns_name, 'ansible_host=' + __infra_di_item.public_ip_address, infra__dynamic_inventory_connectors] | join(' ') }}"
64+
loop: "{{ __infra_dynamic_inventory_discovered.instances }}"
65+
loop_control:
66+
loop_var: __infra_di_item
67+
68+
# If created Utility Instance via Terraform then
69+
# need to get it's info and add to an Ansible host group
70+
- name: Add Utility Instance to host group
71+
when: infra__create_utility_service
72+
block:
73+
- name: Discover the Utility Instance details
74+
community.aws.ec2_instance_info:
75+
region: "{{ infra__region }}"
76+
filters: "{{ __filters | items2dict }}"
77+
vars:
78+
__filters:
79+
- key: "tag:Name"
80+
value: "{{ infra__namespace }}*"
81+
register: __infra_utility_compute_discovered
82+
83+
- name: Add discovered Utility Instance to host group
84+
ansible.builtin.add_host:
85+
hostname: "{{__infra_utility_compute_discovered.instances[0].public_ip_address}}"
86+
ansible_user: "{{ infra__dynamic_inventory_images_default[infra__type][infra__dynamic_inventory_os].user }}"
87+
ansible_ssh_private_key_file: "{{ (infra__private_key_file == '') | ternary(omit, infra__private_key_file) }}"
88+
groupname: cldr_utility

roles/infrastructure/tasks/teardown.yml

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,26 @@
1414
# See the License for the specific language governing permissions and
1515
# limitations under the License.
1616

17-
- name: Teardown provider-specific Infrastructure compute
18-
ansible.builtin.include_tasks: "teardown_{{ infra__type | lower }}_compute.yml"
17+
- name: Teardown for Ansible deployment engine
18+
when: infra__deployment_engine == 'ansible'
19+
block:
20+
- name: Teardown provider-specific Infrastructure compute
21+
ansible.builtin.include_tasks: "teardown_{{ infra__type | lower }}_compute.yml"
1922

20-
- name: Teardown provider-specific Infrastructure storage
21-
ansible.builtin.include_tasks: "teardown_{{ infra__type | lower }}_storage.yml"
23+
- name: Teardown provider-specific Infrastructure storage
24+
ansible.builtin.include_tasks: "teardown_{{ infra__type | lower }}_storage.yml"
2225

23-
- name: Teardown provider-specific Infrastructure network
24-
ansible.builtin.include_tasks: "teardown_{{ infra__type | lower }}_network.yml"
26+
- name: Teardown provider-specific Infrastructure network
27+
ansible.builtin.include_tasks: "teardown_{{ infra__type | lower }}_network.yml"
2528

26-
- name: Teardown provider-specific Utility Services
27-
ansible.builtin.include_tasks: "teardown_{{ infra__type | lower }}_utility_service.yml"
29+
- name: Teardown provider-specific Utility Services
30+
ansible.builtin.include_tasks: "teardown_{{ infra__type | lower }}_utility_service.yml"
2831

29-
- name: Teardown provider-specific Infrastructure artifacts
30-
ansible.builtin.include_tasks: "teardown_{{ infra__type | lower }}.yml"
32+
- name: Teardown provider-specific Infrastructure artifacts
33+
ansible.builtin.include_tasks: "teardown_{{ infra__type | lower }}.yml"
34+
35+
- name: Teardown for Terraform deployment engine
36+
when: infra__deployment_engine == 'terraform'
37+
block:
38+
- name: Teardown Terraform Infrastructure artifacts
39+
ansible.builtin.include_tasks: "teardown_{{ infra__deployment_engine }}.yml"
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
---
2+
3+
# Copyright 2021 Cloudera, Inc. All Rights Reserved.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
- name: Ensure the Terraform workspace directory exists
18+
ansible.builtin.copy:
19+
src: "{{ infra__terraform_template_dir }}/infra/"
20+
dest: "{{ infra__terraform_workspace_dir }}/infra"
21+
22+
- name: Destroy Terraform infra resources
23+
community.general.terraform:
24+
project_path: "{{ infra__terraform_workspace_dir }}/infra"
25+
state: "absent"
26+
force_init: yes
27+
register: tf_result
28+
retries: 3
29+
delay: 10
30+
until: tf_result is succeeded
31+
32+
- name: Remove the Terraform template directory
33+
ansible.builtin.file:
34+
path: "{{ infra__terraform_template_dir }}/infra"
35+
state: absent
36+
37+
- name: Remove the Terraform workspace directory
38+
ansible.builtin.file:
39+
path: "{{ infra__terraform_workspace_dir }}/infra"
40+
state: absent

0 commit comments

Comments
 (0)