Skip to content

Commit 0526f52

Browse files
authored
Add Terraform deployment engine for cloud resources (#65)
* Add parameters for Terraform deployment engine * Update README with details of Terraform deployment * Use ansible tags to determine action on remote state resources * Consolidate Teardown tasks in main.yml into a single play Signed-off-by: Jim Enright <jenright@cloudera.com>
1 parent cc864f7 commit 0526f52

File tree

5 files changed

+174
-1
lines changed

5 files changed

+174
-1
lines changed

main.yml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
- name: Import the Cloud Interactions Playbook
2929
import_playbook: cloud.yml
3030

31-
- name: Teardown Dynamic Inventory when requested
31+
- name: Teardown Cleanup
3232
hosts: localhost
3333
tags: [teardown,never]
3434
gather_facts: yes
@@ -38,6 +38,15 @@
3838
name: cloudera_deploy
3939
tasks_from: clean_dynamic_inventory
4040

41+
- name: Remove Terraform remote state resources if requested
42+
when:
43+
- globals.infra_deployment_engine == 'terraform'
44+
- globals.terraform_auto_remote_state | bool
45+
- globals.terraform_state_storage in ['remote_s3']
46+
ansible.builtin.include_role:
47+
name: cloudera_deploy
48+
tasks_from: auto_terraform_state
49+
4150
- name: Prepare for Cloudera Cluster Run
4251
hosts: localhost
4352
tags: always

readme.adoc

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,46 @@ WARNING: Setting a deployment to a lower runlevel, e.g. from `run` to `infra` wi
447447

448448
For further details on the various _runlevel_-like tags for CDP Public Cloud, see the https://github.com/cloudera-labs/cloudera.exe/blob/main/docs/runlevels.md[Runlevel Guide] in the `cloudera.exe` project.
449449

450+
=== Terraform Deployment Engine
451+
452+
Terraform can optionally be used to create the cloud infrastructure. This will attempt to create the cloud provider assets at the `infra` (network, storage and compute) and `plat` (IAM policies and roles) runlevels using Terraform resources. A list of Terraform related parameters are shown in the table below.
453+
454+
.List of parameters used by Terraform deployment engine
455+
[cols="1,1,1,1"]
456+
|===
457+
|Parameter|Description|Default Value|Notes
458+
459+
|`infra_deployment_engine`
460+
|The engine (ansible or terraform) that will be used to create the infrastructure resources.
461+
| `ansible`
462+
| Needs to be set to `terraform` for Terraform-deployment.
463+
464+
|`terraform_base_dir`
465+
| Top-level directory where all Terraform assets will be placed. Includes processed Jinja template files for Terraform, timestamped artefact of Terraform files and the workspace directory where terraform apply/destroy is run.
466+
| `~/.config/cloudera-deploy/terraform`
467+
|
468+
469+
|`terraform_state_storage`
470+
|The type of backend storage to use for the Terraform state.
471+
| `local`
472+
| Current options are `local` or `remote_s3`
473+
474+
|`terraform_auto_remote_state`
475+
| Flag to allow Cloudera Deploy automatically provision remote state resources as part of its initialization. This will also teardown these resources during cleanup.
476+
| `False`
477+
|
478+
479+
|`terraform_remote_state_bucket`
480+
|The name of the Terraform state storage bucket.
481+
|
482+
| Required if using `remote_s3` state storage. Value is derived from `name_prefix` if terraform_auto_remote_state is True.
483+
484+
|`terraform_remote_state_lock_table`
485+
|The name of the table to track locks of remote Terraform state.
486+
|
487+
| Required if using `remote_s3` state storage. Value is derived from `name_prefix` if terraform_auto_remote_state is True.
488+
|===
489+
450490
== Definitions
451491

452492
Cloudera Deploy uses a set of configuration files within a directory to define and coordinate a deployment. This directory also stores any artifacts created during the deployment, such as Ansible inventory files, CDP environment readouts, etc.

roles/cloudera_deploy/defaults/main.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,5 +47,9 @@ default_parcel_distro: el7 # el8, bionic, focal
4747
default_download_link_expiry: 3600
4848

4949
# Default Deployment Controls
50+
default_infra_deployment_engine: ansible
5051
default_infra_type: aws
5152
default_infra_region: us-east-1
53+
54+
# Terraform defaults
55+
default_terraform_base_dir: "{{ [default_config_path, 'terraform'] | path_join }}"
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
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: Resources for remote_s3 state storage
18+
when:
19+
- globals.terraform_state_storage == 'remote_s3'
20+
block:
21+
22+
# Create or Teardown the resources
23+
- name: AWS Bucket for Remote State Storage
24+
amazon.aws.aws_s3:
25+
region: "{{ globals.region }}"
26+
bucket: "{{ globals.terraform_remote_state_bucket}}"
27+
mode: "{{ ('teardown' not in ansible_run_tags) | ternary('create', 'delete') }}" # Check ansible tag to determine action
28+
permission: private
29+
register: __infra_aws_storage_locations_info
30+
31+
- name: AWS DynamoDB for Remote State Locking
32+
community.aws.dynamodb_table:
33+
region: "{{ globals.region }}"
34+
name: "{{ globals.terraform_remote_state_lock_table }}"
35+
read_capacity: 1
36+
write_capacity: 1
37+
hash_key_name: LockID
38+
hash_key_type: STRING
39+
state: "{{ ('teardown' not in ansible_run_tags) | ternary('present', 'absent') }}" # Check ansible tag to determine action
40+
41+
- name: Print remote state configuration
42+
when: "'teardown' not in ansible_run_tags"
43+
ansible.builtin.debug:
44+
msg:
45+
- "Resources for remote_s3 Terraform State created."
46+
- "S3 Bucket Name: {{ globals.terraform_remote_state_bucket}}"
47+
- "DynamoDB Locking Table: {{ globals.terraform_remote_state_lock_table}}"
48+
verbosity: 3

roles/cloudera_deploy/tasks/init.yml

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,13 @@
173173
name_prefix: "{{ name_prefix | default(default_name_prefix) }}"
174174
tags: "{{ tags | default(omit) }}"
175175
region: "{{ infra_region | default(default_infra_region) }}"
176+
infra_deployment_engine: "{{ infra_deployment_engine | default(default_infra_deployment_engine) }}"
176177
infra_type: "{{ infra_type | default(default_infra_type) }}"
178+
terraform_base_dir: "{{ terraform_base_dir | default(default_terraform_base_dir) | expanduser }}"
179+
terraform_state_storage: "{{ terraform_state_storage | default(omit) }}"
180+
terraform_auto_remote_state: "{{ terraform_auto_remote_state | default(False) }}"
181+
terraform_remote_state_bucket: "{{ terraform_remote_state_bucket | default(omit) }}"
182+
terraform_remote_state_lock_table: "{{ terraform_remote_state_lock_table | default(omit) }}"
177183
ssh:
178184
public_key_id: "{{ public_key_id | default(omit) }}"
179185
public_key_file: "{{ public_key_file | default(omit) }}"
@@ -217,6 +223,31 @@
217223
fail_msg: "You must supply a valid Namespace"
218224
quiet: yes
219225

226+
- name: Check Deployment Engine variable
227+
ansible.builtin.assert:
228+
that:
229+
- globals.infra_deployment_engine in ['ansible', 'terraform']
230+
fail_msg: "The 'infra_deployment_engine' variable must be one of 'ansible', 'terraform'"
231+
232+
- name: Check Supplied terraform_base_dir variable
233+
when:
234+
- infra_deployment_engine == 'terraform'
235+
ansible.builtin.assert:
236+
that:
237+
- globals.terraform_base_dir is defined
238+
- globals.terraform_base_dir | length > 0
239+
fail_msg: "You must supply a 'terraform_base_dir' where Terraform assets will be placed"
240+
quiet: yes
241+
242+
- name: Check Supplied terraform_auto_remote_state variable
243+
when:
244+
- infra_deployment_engine == 'terraform'
245+
ansible.builtin.assert:
246+
that:
247+
- (globals.terraform_auto_remote_state|bool is sameas true) or (globals.terraform_auto_remote_state|bool is sameas false)
248+
fail_msg: "The terraform_auto_remote_state variable must be a boolean variable"
249+
quiet: yes
250+
220251
# SSH
221252
- name: Use default SSH public key id
222253
when: globals.ssh.public_key_id is undefined
@@ -405,3 +436,44 @@
405436
fail_msg: >-
406437
Admin Password must comply with CDP Public requirements: 1 Upper, 1 Special, 1 Number, 8-64 chars.
407438
quiet: yes
439+
440+
# Provision Terraform remote state resources if requested
441+
- name: Initialize Terraform remote state resources
442+
when:
443+
- init__call_cloud_role | bool
444+
- globals.infra_deployment_engine == 'terraform'
445+
- globals.terraform_auto_remote_state | bool
446+
- globals.terraform_state_storage in ['remote_s3']
447+
block:
448+
# Set resource variable names if not already done
449+
- name: Set variables for remote state bucket if not set
450+
when: (globals.terraform_remote_state_bucket is not defined) or
451+
( (globals.terraform_remote_state_bucket) | length == 0)
452+
ansible.builtin.set_fact:
453+
globals: "{{ globals | default({}) | combine(remote_state_vars, recursive=True) }}"
454+
vars:
455+
remote_state_vars:
456+
terraform_remote_state_bucket: "{{ [globals.name_prefix, 'state-bucket'] | join('-') }}"
457+
458+
- name: Set variables for remote state lock table if not set
459+
when: (globals.terraform_remote_state_lock_table is not defined) or
460+
(globals.terraform_remote_state_lock_table | length == 0)
461+
ansible.builtin.set_fact:
462+
globals: "{{ globals | default({}) | combine(remote_state_vars, recursive=True) }}"
463+
vars:
464+
remote_state_vars:
465+
terraform_remote_state_lock_table: "{{ [globals.name_prefix, 'state-lock-table'] | join('-') }}"
466+
467+
- name: Create remote state resources
468+
when: "'teardown' not in ansible_run_tags"
469+
ansible.builtin.include_role:
470+
name: cloudera_deploy
471+
tasks_from: auto_terraform_state
472+
473+
- name: Prepare for Download Mirror Population if requested and necessary
474+
when:
475+
- use_download_mirror | default(default_enable_download_mirror) | bool
476+
- "'teardown' not in ansible_run_tags"
477+
ansible.builtin.include_role:
478+
name: cloudera_deploy
479+
tasks_from: prepare_download_mirror

0 commit comments

Comments
 (0)