From d09465685cd017c084d20269fd882cf46f116e05 Mon Sep 17 00:00:00 2001 From: Jim Enright Date: Fri, 1 Oct 2021 09:54:26 +0100 Subject: [PATCH 01/33] Add Terraform templates for AWS infra and roles Signed-off-by: Jim Enright --- roles/common/defaults/main.yml | 1 + roles/infrastructure/defaults/main.yml | 7 + .../tasks/initialize_aws_terraform.yml | 42 +++ .../infrastructure/tasks/initialize_setup.yml | 6 +- roles/infrastructure/tasks/main.yml | 4 +- roles/infrastructure/tasks/setup.yml | 22 +- .../tasks/setup_aws_terraform.yml | 37 ++ roles/infrastructure/tasks/validate.yml | 3 +- .../tasks/validate_aws_terraform.yml | 35 ++ .../template/aws/infra_aws_compute.tf.j2 | 63 ++++ .../template/aws/infra_aws_network.tf.j2 | 163 +++++++++ .../template/aws/infra_aws_storage.tf.j2 | 35 ++ .../template/aws/provider.tf.j2 | 6 + .../template/aws/terraform_variables.tf.j2 | 29 ++ roles/platform/defaults/main.yml | 7 + .../tasks/initialize_aws_terraform.yml | 36 ++ roles/platform/tasks/initialize_setup.yml | 6 +- roles/platform/tasks/setup.yml | 8 +- roles/platform/tasks/setup_aws_authz.yml | 4 + roles/platform/tasks/validate.yml | 3 +- .../platform/tasks/validate_aws_terraform.yml | 32 ++ .../template/aws/plat_aws_authz.tf.j2 | 320 ++++++++++++++++++ roles/platform/template/aws/provider.tf.j2 | 6 + .../template/aws/terraform_variables.tf.j2 | 29 ++ 24 files changed, 883 insertions(+), 21 deletions(-) create mode 100644 roles/infrastructure/tasks/initialize_aws_terraform.yml create mode 100644 roles/infrastructure/tasks/setup_aws_terraform.yml create mode 100644 roles/infrastructure/tasks/validate_aws_terraform.yml create mode 100644 roles/infrastructure/template/aws/infra_aws_compute.tf.j2 create mode 100644 roles/infrastructure/template/aws/infra_aws_network.tf.j2 create mode 100644 roles/infrastructure/template/aws/infra_aws_storage.tf.j2 create mode 100644 roles/infrastructure/template/aws/provider.tf.j2 create mode 100644 roles/infrastructure/template/aws/terraform_variables.tf.j2 create mode 100644 roles/platform/tasks/initialize_aws_terraform.yml create mode 100644 roles/platform/tasks/validate_aws_terraform.yml create mode 100644 roles/platform/template/aws/plat_aws_authz.tf.j2 create mode 100644 roles/platform/template/aws/provider.tf.j2 create mode 100644 roles/platform/template/aws/terraform_variables.tf.j2 diff --git a/roles/common/defaults/main.yml b/roles/common/defaults/main.yml index 81b0a69f..11cfa48e 100644 --- a/roles/common/defaults/main.yml +++ b/roles/common/defaults/main.yml @@ -57,6 +57,7 @@ common__ngw_suffix: "{{ globals.labels.nat_gateway | defau common__unique_storage_name_suffix: "{{ globals.storage.name | default((common__region + common__aws_profile) if 'aws' in common__infra_type else common__region) }}" # Infra +common__infra_deployment: "{{ globals.infra_deployment | default() }}" common__infra_type: "{{ globals.infra_type | default('aws') }}" common__public_key_file: "{{ globals.ssh.public_key_file | default('') }}" common__namespace_cdp: "{{ globals.namespace_cdp | default([common__namespace, common__namespace_unique_suffix] | join('-')) }}" diff --git a/roles/infrastructure/defaults/main.yml b/roles/infrastructure/defaults/main.yml index 01642d19..2abf6994 100644 --- a/roles/infrastructure/defaults/main.yml +++ b/roles/infrastructure/defaults/main.yml @@ -26,6 +26,13 @@ infra__vpc_svcnet_suffix: "{{ common__vpc_svcnet_suffix }}" infra__vpc_private_subnets_suffix: "{{ common__vpc_private_subnets_suffix }}" infra__vpc_public_subnets_suffix: "{{ common__vpc_public_subnets_suffix }}" +# NOTE: Added by jenright for Terraform +# Deployment type +infra__deployment: "{{ common__infra_deployment }}" +# Location of output from template module which creates Terraform +infra__terraform_tmp_dir: "{{ common__terraform_tmp_dir | default('./jenright_tmp_terraform_code') }}" +infra__terraform_workspace_dir: "{{ common__terraform_workspace_dir | default( playbook_dir + '/.namespaces') }}" + # Infra infra__type: "{{ common__infra_type }}" infra__tunnel: "{{ common__tunnel }}" diff --git a/roles/infrastructure/tasks/initialize_aws_terraform.yml b/roles/infrastructure/tasks/initialize_aws_terraform.yml new file mode 100644 index 00000000..1145f242 --- /dev/null +++ b/roles/infrastructure/tasks/initialize_aws_terraform.yml @@ -0,0 +1,42 @@ +- name: Create terraform template .tf files + when: infra__terraform_tmp_dir is defined # TODO: Is this needed? + block: + - name: Create terraform template dir + file: + path: "{{ infra__terraform_tmp_dir }}/infra" + state: directory + + # Apply template for Terraform provider + - name: Generate Terraform Provider + template: + src: 'template/{{ infra__type }}/provider.tf.j2' + dest: "{{ infra__terraform_tmp_dir }}/infra/provider.tf" + + # Apply template for Terraform variables + - name: Generate Terraform Variables + template: + src: 'template/{{ infra__type }}/terraform_variables.tf.j2' + dest: "{{ infra__terraform_tmp_dir }}/infra/variables.tf" + no_log: false + + # Apply template for Terraform infra.... + # ...network resources + - name: Generate Terraform infra file for network resources + template: + src: 'template/{{ infra__type }}/infra_{{ infra__type }}_network.tf.j2' + dest: "{{ infra__terraform_tmp_dir }}/infra/infra_network.tf" + no_log: false + + # ...storage resources + - name: Generating Terraform infra file for storage resources + template: + src: 'template/{{ infra__type }}/infra_{{ infra__type }}_storage.tf.j2' + dest: "{{ infra__terraform_tmp_dir }}/infra/infra_storage.tf" + no_log: false + + # ...compute resources + - name: Generating Terraform infra file for compute resources + template: + src: 'template/{{ infra__type }}/infra_{{ infra__type }}_compute.tf.j2' + dest: "{{ infra__terraform_tmp_dir }}/infra/infra_compute.tf" + no_log: false \ No newline at end of file diff --git a/roles/infrastructure/tasks/initialize_setup.yml b/roles/infrastructure/tasks/initialize_setup.yml index 2a1aaa50..71535967 100644 --- a/roles/infrastructure/tasks/initialize_setup.yml +++ b/roles/infrastructure/tasks/initialize_setup.yml @@ -22,4 +22,8 @@ ansible.builtin.include_tasks: "initialize_{{ infra__type | lower }}.yml" - name: Include tasks fpr provider-specific Infrastructure setup initialization - ansible.builtin.include_tasks: "initialize_setup_{{ infra__type | lower }}.yml" \ No newline at end of file + ansible.builtin.include_tasks: "initialize_setup_{{ infra__type | lower }}.yml" + +# NOTE: Added by jenright, Terraform +- name: Include tasks for provider-specific Infrastructure initialization + ansible.builtin.include_tasks: "initialize_{{ infra__type | lower }}_{{ infra__deployment }}.yml" diff --git a/roles/infrastructure/tasks/main.yml b/roles/infrastructure/tasks/main.yml index 2e92466b..9d096444 100644 --- a/roles/infrastructure/tasks/main.yml +++ b/roles/infrastructure/tasks/main.yml @@ -15,5 +15,5 @@ # limitations under the License. - include_tasks: validate.yml -- include_tasks: initialize_setup.yml -- include_tasks: setup.yml +# - include_tasks: initialize_setup.yml +# - include_tasks: setup.yml diff --git a/roles/infrastructure/tasks/setup.yml b/roles/infrastructure/tasks/setup.yml index 2fbd6a0c..59a9298a 100644 --- a/roles/infrastructure/tasks/setup.yml +++ b/roles/infrastructure/tasks/setup.yml @@ -17,18 +17,18 @@ # tasks file for setup - name: Set up provider-specific Infrastructure artifacts - ansible.builtin.include_tasks: "setup_{{ infra__type | lower }}.yml" + ansible.builtin.include_tasks: "setup_{{ infra__type | lower }}_{{ infra_deployment }}.yml" -- name: Set up provider-specific Infrastructure network - ansible.builtin.include_tasks: "setup_{{ infra__type | lower }}_network.yml" +# - name: Set up provider-specific Infrastructure network +# ansible.builtin.include_tasks: "setup_{{ infra__type | lower }}_network.yml" -- name: Set up provider-specific Infrastructure storage - ansible.builtin.include_tasks: "setup_{{ infra__type | lower }}_storage.yml" +# - name: Set up provider-specific Infrastructure storage +# ansible.builtin.include_tasks: "setup_{{ infra__type | lower }}_storage.yml" -- name: Set Up localised provider-specific Storage Utility Service - when: infra__create_utility_service - ansible.builtin.include_tasks: "setup_{{ infra__type | lower }}_utility_service.yml" +# - name: Set Up localised provider-specific Storage Utility Service +# when: infra__create_utility_service +# ansible.builtin.include_tasks: "setup_{{ infra__type | lower }}_utility_service.yml" -- name: Set up provider-specific Infrastructure Compute - when: infra__dynamic_inventory_count - ansible.builtin.include_tasks: "setup_{{ infra__type | lower }}_compute.yml" \ No newline at end of file +# - name: Set up provider-specific Infrastructure Compute +# when: infra__dynamic_inventory_count +# ansible.builtin.include_tasks: "setup_{{ infra__type | lower }}_compute.yml" \ No newline at end of file diff --git a/roles/infrastructure/tasks/setup_aws_terraform.yml b/roles/infrastructure/tasks/setup_aws_terraform.yml new file mode 100644 index 00000000..c12e2796 --- /dev/null +++ b/roles/infrastructure/tasks/setup_aws_terraform.yml @@ -0,0 +1,37 @@ +- name: Deploy terraform infrastructure + block: + + - name: Confirm I got to setup_aws_terraform + ansible.builtin.debug: + msg: + - "I'm here doing to terraform apply" + - "Here's the workspace: {{ infra__terraform_workspace_dir }}" + + - name: Terraform local state + # when: terraform_state == "local" # TODO: Handle state + block: + - name: Check if workspace directory exists + # TODO: Fix workspace_dir_path + # stat: path={{ infra__terraform_workspace_dir }}/workspace_dir_path + stat: path={{ infra__terraform_workspace_dir }}/workspace/infra + register: workdir + + - name: Ensure the workspace directory exists + copy: + src: "{{ infra__terraform_tmp_dir }}/infra/" + # TODO: Fix workspace_dir_path + # dest: "{{ infra__terraform_workspace_dir }}/{{ workspace_dir_path }}" + dest: "{{ infra__terraform_workspace_dir }}/workspace/infra" + # when: not workdir.stat.exists # TODO: This won't override if any changes to .tf are made. Good or Bad? + + - name: Applying terraform + community.general.terraform: + # TODO: Fix workspace_dir_path + # project_path: "{{ infra__terraform_workspace_dir }}/{{ workspace_dir_path }}" + project_path: "{{ infra__terraform_workspace_dir }}/workspace/infra" + state: "present" + force_init: yes + register: tf_result + retries: 3 + delay: 10 + until: tf_result is succeeded \ No newline at end of file diff --git a/roles/infrastructure/tasks/validate.yml b/roles/infrastructure/tasks/validate.yml index 1df37ade..7b64cf59 100644 --- a/roles/infrastructure/tasks/validate.yml +++ b/roles/infrastructure/tasks/validate.yml @@ -23,4 +23,5 @@ fail_msg: "Invalid SSH private key file for Dynamic Inventory. Key file must be a string." - name: Validate provider-specific Infrastructure parameters - ansible.builtin.include_tasks: "validate_{{ infra__type | lower }}.yml" + ansible.builtin.include_tasks: "validate_{{ infra__type | lower }}_{{ infra_deployment }}.yml" + # ansible.builtin.include_tasks: "validate_{{ infra__type | lower }}_terraform.yml" diff --git a/roles/infrastructure/tasks/validate_aws_terraform.yml b/roles/infrastructure/tasks/validate_aws_terraform.yml new file mode 100644 index 00000000..98a303cb --- /dev/null +++ b/roles/infrastructure/tasks/validate_aws_terraform.yml @@ -0,0 +1,35 @@ +--- + +# Copyright 2021 Cloudera, Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +- name: Check public key ID + ansible.builtin.assert: + that: + - "__auth_item is defined" + - "__auth_item is string" + - "__auth_item | trim | length > 0" + fail_msg: "AWS authentication parameter, '{{ __auth_item }}', is invalid." + quiet: yes + loop_control: + loop_var: __auth_item + loop: + - "{{ infra__public_key_id }}" + +- name: Print AWS Profile to debug + ansible.builtin.command: echo AWS_PROFILE is $AWS_PROFILE + +- name: Print Executing Terraform message + ansible.builtin.debug: + msg: "Executing Terraform. Value of infra__deployment = {{ infra__deployment }}" \ No newline at end of file diff --git a/roles/infrastructure/template/aws/infra_aws_compute.tf.j2 b/roles/infrastructure/template/aws/infra_aws_compute.tf.j2 new file mode 100644 index 00000000..dab875ae --- /dev/null +++ b/roles/infrastructure/template/aws/infra_aws_compute.tf.j2 @@ -0,0 +1,63 @@ +# ------- Dynamic Inventory VMs ------- +{% for __infra_compute_instance_item in range(0, infra__dynamic_inventory_count | int ) | list %} +resource "aws_instance" "{{ '-'.join([infra__namespace, infra__dynamic_inventory_vm_suffix, '%02d' | format(__infra_compute_instance_item)]) }}" { + # NOTE: Security group...taken directly from infra__security_group_default_name variable rather than infra__aws_security_group_default_id fact + vpc_security_group_ids = [aws_security_group.{{ infra__security_group_default_name }}.id] + # DONE: key pair + key_name = "{{ infra__public_key_id }}" + # DONE: instance type + instance_type = "{{ infra__dynamic_inventory_vm_type_default[infra__type][infra__dynamic_inventory_vm_type] }}" + # DONE: image + ami = "{{ __infra_aws_ami_info.image_id }}" + # DONE: EBS ebs_optimized + ebs_optimized = true + # NOTE: VPC vpc_subnet_id....direct + # subnet_id = aws_subnet.{{ infra__vpc_public_subnet_cidrs | union(infra__vpc_private_subnet_cidrs) | first }}.id + subnet_id = aws_subnet.{{ infra__namespace }}_subnet1.id + # DONE: Public IP + associate_public_ip_address = true + # DONE: Tag + {# to_json is used to convert single quotes around IP to double #} + tags = merge({{ infra__dynamic_inventory_tags | to_json }},{Name = "{{ '-'.join([infra__namespace, infra__dynamic_inventory_vm_suffix, '%02d' | format(__infra_compute_instance_item)]) }}"}) + # TODO: Volume / root_block_device + root_block_device { + # NOTE: Need to cast from string (yes) to bool, option 1 + delete_on_termination = {{ infra__dynamic_inventory_delete_storage | bool | lower }} + # NOTE: Need to cast from string (yes) to bool, option 2 + # delete_on_termination = {{ true if infra__dynamic_inventory_delete_storage in ['yes', 1, "True", "true"] else false }} + volume_size = "{{ infra__dynamic_inventory_storage_size }}" + volume_type = "{{ infra__dynamic_inventory_storage_type_default[infra__type][infra__dynamic_inventory_storage_type] }}" + } +} +{% endfor %} + +{% if infra__create_utility_service %} +# ------- Localised Utility VM Instance ------- +resource "aws_instance" "{{ '-'.join([infra__namespace, infra__region, 'utility_vm' ]) }}" { + # NOTE: Security group...taken directly from infra__security_group_default_name variable rather than infra__aws_security_group_default_id fact + vpc_security_group_ids = [aws_security_group.{{ infra__security_group_default_name }}.id] + # DONE: key pair + key_name = "{{ infra__public_key_id }}" + # DONE: instance type + instance_type = "{{ infra__dynamic_inventory_vm_type_default[infra__type]['sml'] }}" + # DONE: image + ami = "{{ __infra_aws_ami_info.image_id }}" + # DONE: EBS ebs_optimized + ebs_optimized = true + # NOTE: VPC vpc_subnet_id....direct + subnet_id = aws_subnet.{{ infra__namespace }}_subnet1.id + # DONE: Public IP + associate_public_ip_address = true + # DONE: Tag + {# to_json is used to convert single quotes around IP to double #} + tags = merge({{ infra__dynamic_inventory_tags | to_json }},{Name = "{{ '-'.join([infra__namespace, infra_region, 'utility_vm' ]) }}"}) + + # TODO: Volume / root_block_device + root_block_device { + # NOTE: Need to cast from string (yes) to bool, option 1 + delete_on_termination = {{ infra__dynamic_inventory_delete_storage | bool | lower }} + volume_size = 100 + volume_type = "{{ infra__dynamic_inventory_storage_type_default[infra__type]['std'] }}" + } +} +{% endif %} \ No newline at end of file diff --git a/roles/infrastructure/template/aws/infra_aws_network.tf.j2 b/roles/infrastructure/template/aws/infra_aws_network.tf.j2 new file mode 100644 index 00000000..e5880c01 --- /dev/null +++ b/roles/infrastructure/template/aws/infra_aws_network.tf.j2 @@ -0,0 +1,163 @@ +# ------- VPC ------- +# Create the VPC's +resource "aws_vpc" "{{ infra__vpc_name }}" { + cidr_block = "{{ infra__vpc_cidr }}" + tags = merge(var.env_tags,{Name = "{{ infra__vpc_name }}"}) + # NOTE: Below variables not available in cloudera.exe + #instance_tenancy = "aws.vpc.vpc_instanceTenancy" + #enable_dns_support = "aws.vpc.vpc_enable_dns_support" + #enable_dns_hostnames = "aws.vpc.vpc_enable_dns_hostnames" +} + +# ------- Internet Gateway ------- +# NOTE: In EDU code there's a loop over internet_gateways +resource "aws_internet_gateway" "{{ infra__aws_igw_name }}" { + vpc_id = aws_vpc.{{ infra__vpc_name }}.id + tags = merge(var.env_tags,{Name = "{{ infra__aws_igw_name }}"}) +} + +# ------- VPC Subnets ------- +{% for __aws_subnet_cidr_item in infra__vpc_public_subnet_cidrs | union(infra__vpc_private_subnet_cidrs) %} +resource "aws_subnet" "{{ infra__namespace }}_subnet{{ loop.index }}" { + vpc_id = aws_vpc.{{ infra__vpc_name }}.id + cidr_block = "{{ __aws_subnet_cidr_item }}" + map_public_ip_on_launch = true + availability_zone = "{{ __aws_az_info.availability_zones[loop.index0 % infra__aws_vpc_az_count | int].zone_name }}" + tags = merge(var.env_tags,{Name = "{{ infra__namespace }}"}) +} +{% endfor %} + +# ------- Route Table ------- +# NOTE: In EDU code a new route table is created; in Ansible main is reused & updated. +resource "aws_default_route_table" "{{ infra__aws_route_table_name }}" { + default_route_table_id = aws_vpc.{{ infra__vpc_name }}.default_route_table_id + + route { + cidr_block = "0.0.0.0/0" + gateway_id = aws_internet_gateway.{{ infra__aws_igw_name }}.id + } + + + tags = merge(var.env_tags,{Name = "{{ infra__aws_route_table_name }}"}) +} + +# Associate the Route Table with the Subnet +{% for subnet in infra__vpc_public_subnet_cidrs | union(infra__vpc_private_subnet_cidrs) %} +resource "aws_route_table_association" "{{ infra__namespace }}_subnet{{ loop.index }}-association" { + subnet_id = aws_subnet.{{ infra__namespace }}_subnet{{ loop.index }}.id + route_table_id = aws_vpc.{{ infra__vpc_name }}.default_route_table_id +} +{% endfor %} + +# ------- Security Groups ------- +{% set __security_group_names = [infra__security_group_knox_name, infra__security_group_default_name] %} + +{% for __security_group_name_item in __security_group_names %} +resource "aws_security_group" "{{ __security_group_name_item }}" { + vpc_id = aws_vpc.{{ infra__vpc_name }}.id + name = "{{ __security_group_name_item }}" + + # Create self reference ingress rule to allow + # communication among resources in the security group. + ingress { + from_port = 0 + to_port = 0 + protocol = "all" + self = true + } + +{# ******* NOTE: HERE COMES THE MESSY PART! *******#} +{# Need to loop over each security group rule:#} +{# Need to Process & Translate *CIDR Block* according to following rules:#} +{# * Can be empty in which case remove entry - DONE#} +{# * Can be a string. Check if this works; if not cast to list element#} +{# * Can be a list. Use directly - DONE #} + +{# Need to Process & Translate *Ports* according to following rules: #} +{# * If proto is `all` (or -1) then ports are 0 - DONE#} +{# * If toPort and fromPort specified use those#} +{# * ports: can be a range. Split and select - DONE#} +{# * ports: could be a list. Loop over each - DONE #} +{# * If no ports, toPort and fromPort then use default of full range (0)#} + +{# **Loop over security group rule**#} +{% for ingress in infra__aws_security_group_rules %} +# ----- Raw Inputs ----- +# ports = {{ ingress.ports|pprint }} +# cidr_blocks = {{ ingress.cidr_ip }} +# protocol = {{ ingress.proto }} +# ---------------------- +{# **Process CIDR Block**#} +{# 1. CIDR block can be empty, in which case remove entry#} +{% if ingress.cidr_ip | length > 0 %} +{# 1a. If CIDR is a single string value then we need to convert single item list #} +{# to_json is used to convert single quotes around IP to double #} +{% if ingress.cidr_ip is string %} +{% set cidr_ingress = 'cidr_blocks = ' + [ingress.cidr_ip]| to_json | string %} +{% else %} +{# 1b. If CIDR is a list to convert single quotes to double (to_json) and stringify #} +{% set cidr_ingress = 'cidr_blocks = ' + ingress.cidr_ip| to_json | string %} +{% endif %} +{% else %} +{# 1c. If CIDR is empty we remove the entry #} +{% set cidr_ingress = '' %} +{% endif %} +{# **Process Ports**#} +{# 1. If proto is 'all' or -1 #} +{% if ingress.proto in ['all', -1] or ingress.ports is not defined %} +{# 1a. to and from ports are 0 #} +{% set toPort = 0 %} +{% set fromPort = 0 %} +{# 1b. Print out ingress #} + ingress { + {{ cidr_ingress }} + from_port = "{{ toPort }}" + to_port = "{{ fromPort }}" + protocol = "{{ ingress.proto }}" + } +{# 2. Ports can be a String (either a single value or a range)#} +{% elif ingress.ports is string %} +{# 2a. Attempt to split the string at '-' to create a list#} +{% set portList = ingress.ports.split('-') %} +{# 2b. In the list toPort is the first element#} +{% set toPort = portList[0] %} +{# 2c. Value of fromPort depends on length of the split string.#} +{% if portList|length > 1 %} +{# ...it's the second element if a range is given (i.e. length > 1)#} +{% set fromPort = portList[1] %} +{% else %} +{# ...it's also the first element if a single value is given#} +{% set fromPort = portList[0] %} +{% endif %} +{# 2d. Print the ingress block#} + ingress { + {{ cidr_ingress }} + from_port = "{{ toPort }}" + to_port = "{{ fromPort }}" + protocol = "{{ ingress.proto }}" + } +{# 3. Ports can be a List of individual ports which we need to loop over#} +{% elif ingress.ports is iterable and (ingress.ports is not string and ingress.ports is not mapping) %} +{# 3a. Loop over each port separately and print ingress #} +{% for port in ingress.ports %} + ingress { + {{ cidr_ingress }} + from_port = "{{ port }}" + to_port = "{{ port }}" + protocol = "{{ ingress.proto }}" + } +{% endfor %} +{% endif %} +{% endfor %} + + # Terraform removes the default ALLOW ALL egress. Let's recreate this + egress { + cidr_blocks = ["0.0.0.0/0"] + from_port = 0 + to_port = 0 + protocol = "all" + } + + tags = merge(var.env_tags,{Name = "{{ __security_group_name_item }}"}) +} +{% endfor %} diff --git a/roles/infrastructure/template/aws/infra_aws_storage.tf.j2 b/roles/infrastructure/template/aws/infra_aws_storage.tf.j2 new file mode 100644 index 00000000..900977d5 --- /dev/null +++ b/roles/infrastructure/template/aws/infra_aws_storage.tf.j2 @@ -0,0 +1,35 @@ +# ------- S3 Buckets ------- +# Get unique list of buckets from infra__aws_storage_locations +{% for __aws_storage_location_item in ( infra__aws_storage_locations | map(attribute='bucket') | list | unique ) %} +resource "aws_s3_bucket" "{{ __aws_storage_location_item }}" { + bucket = "{{ __aws_storage_location_item }}" + acl = "private" + force_destroy = true + + tags = merge(var.env_tags,{Name = "{{ __aws_storage_location_item }}"}) +} +{% endfor %} + +# ------- AWS Buckets directory structures ------- +{% for __aws_storage_object_item in infra__aws_storage_locations %} +{# Terraform resources cannot have '/' so replace with '_' #} +{% set __aws_storage_object_resource = __aws_storage_object_item.path |replace("/", "_") %} + +resource "aws_s3_bucket_object" "{{ __aws_storage_object_resource}}" { + bucket = aws_s3_bucket.{{ __aws_storage_object_item.bucket}}.id + key = "{{ __aws_storage_object_item.path }}/" + # Below may not be required once we have the '/' + content_type = "application/x-directory" +} +{% endfor %} + +# ------- Download Mirror Bucket ------- +# QUESTION: How to not fail if already exists from non-Terraform code. +# resource "aws_s3_bucket" "{{ infra__utlity_bucket_name }}" { +# bucket = "{{ infra__utlity_bucket_name }}" +# acl = "private" +# force_destroy = true + +# tags = merge(var.env_tags,{Name = "{{ infra__utlity_bucket_name }}"}) +# } + diff --git a/roles/infrastructure/template/aws/provider.tf.j2 b/roles/infrastructure/template/aws/provider.tf.j2 new file mode 100644 index 00000000..02557562 --- /dev/null +++ b/roles/infrastructure/template/aws/provider.tf.j2 @@ -0,0 +1,6 @@ +provider "aws" { + # access_key = var.access_key + # secret_key = var.secret_key + profile = var.aws_profile + region = var.region +} diff --git a/roles/infrastructure/template/aws/terraform_variables.tf.j2 b/roles/infrastructure/template/aws/terraform_variables.tf.j2 new file mode 100644 index 00000000..4dc1b669 --- /dev/null +++ b/roles/infrastructure/template/aws/terraform_variables.tf.j2 @@ -0,0 +1,29 @@ +# NOTE: We no longer have access & secret key readily available +# variable "access_key" { +# default = " access_key " +# } +# variable "secret_key" { +# default = " secret_key " +# } + +# NOTE: Added by jenright because we have profile and not access & secret key +variable "aws_profile" { + # TODO: How to make this default if blank + # default = "{{ infra__aws_profile | default('default') }}" + default = "default" +} + +# Region +variable "region" { + default = "{{ infra__region }}" +} + + +variable "env_tags" { + default = { + {% for key, value in infra__tags.items() %} + {{ key }} = "{{ value }}" + {% endfor %} + comment = "Created with Terraform by cloudera-deploy" + } +} diff --git a/roles/platform/defaults/main.yml b/roles/platform/defaults/main.yml index 219e7356..d236f1d0 100644 --- a/roles/platform/defaults/main.yml +++ b/roles/platform/defaults/main.yml @@ -19,6 +19,13 @@ # Role prefix is 'plat__' # Labels +# NOTE: Added by jenright for Terraform +# Deployment type +plat__infra_deployment: "{{ common__infra_deployment }}" +# Location of output from template module which creates Terraform +plat__terraform_tmp_dir: "{{ common__terraform_tmp_dir | default('./jenright_tmp_terraform_code') }}" +plat__terraform_workspace_dir: "{{ common__terraform_workspace_dir | default( playbook_dir + '/.namespaces') }}" + plat__infra_type: "{{ common__infra_type }}" plat__region: "{{ common__region }}" plat__namespace: "{{ common__namespace }}" diff --git a/roles/platform/tasks/initialize_aws_terraform.yml b/roles/platform/tasks/initialize_aws_terraform.yml new file mode 100644 index 00000000..30ef287c --- /dev/null +++ b/roles/platform/tasks/initialize_aws_terraform.yml @@ -0,0 +1,36 @@ +--- + +# Copyright 2021 Cloudera, Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +- name: Create terraform template .tf files + when: plat__terraform_tmp_dir is defined # TODO: Is this needed? + block: + - name: Create terraform template dir + file: + path: "{{ plat__terraform_tmp_dir }}/roles" + state: directory + + # Apply template for Terraform provider + - name: Generate Terraform Provider + template: + src: 'template/{{ plat__infra_type }}/provider.tf.j2' + dest: "{{ plat__terraform_tmp_dir }}/roles/provider.tf" + + # Apply template for Terraform variables + - name: Generate Terraform Variables + template: + src: 'template/{{ plat__infra_type }}/terraform_variables.tf.j2' + dest: "{{ plat__terraform_tmp_dir }}/roles/variables.tf" + no_log: false diff --git a/roles/platform/tasks/initialize_setup.yml b/roles/platform/tasks/initialize_setup.yml index 3fb17995..a87f43b3 100644 --- a/roles/platform/tasks/initialize_setup.yml +++ b/roles/platform/tasks/initialize_setup.yml @@ -21,4 +21,8 @@ ansible.builtin.include_tasks: "initialize_{{ plat__infra_type | lower }}.yml" - name: Include provider-specific initialization setup - ansible.builtin.include_tasks: "initialize_setup_{{ plat__infra_type | lower }}.yml" \ No newline at end of file + ansible.builtin.include_tasks: "initialize_setup_{{ plat__infra_type | lower }}.yml" + +# Added by jenright, Terraform +- name: Include tasks for provider-specific Infrastructure initialization + ansible.builtin.include_tasks: "initialize_{{ plat__infra_type | lower }}_{{ plat__infra_deployment }}.yml" diff --git a/roles/platform/tasks/setup.yml b/roles/platform/tasks/setup.yml index 714247f5..bb132f8f 100644 --- a/roles/platform/tasks/setup.yml +++ b/roles/platform/tasks/setup.yml @@ -17,8 +17,8 @@ - name: Include provider-specific CDP Public Roles and Policies setup tasks ansible.builtin.include_tasks: "setup_{{ plat__infra_type | lower }}_authz.yml" -- name: Include provider-specific CDP Environment setup tasks - ansible.builtin.include_tasks: "setup_{{ plat__infra_type | lower }}_env.yml" +# - name: Include provider-specific CDP Environment setup tasks +# ansible.builtin.include_tasks: "setup_{{ plat__infra_type | lower }}_env.yml" -- name: Include shared CDP Public Environment Setup Tasks - ansible.builtin.include_tasks: "setup_base.yml" +# - name: Include shared CDP Public Environment Setup Tasks +# ansible.builtin.include_tasks: "setup_base.yml" diff --git a/roles/platform/tasks/setup_aws_authz.yml b/roles/platform/tasks/setup_aws_authz.yml index 8d331bd4..8e28747b 100644 --- a/roles/platform/tasks/setup_aws_authz.yml +++ b/roles/platform/tasks/setup_aws_authz.yml @@ -30,6 +30,10 @@ loop: "{{ plat__aws_policy_urls | dict2items }}" register: __aws_policy_documents +- name: JE Debug Print __aws_policy_tmpdir + ansible.builtin.debug: + var: __aws_policy_tmpdir + - name: Process AWS default policy documents ansible.builtin.include_tasks: aws_policy_regex.yml loop: "{{ __aws_policy_documents.results }}" diff --git a/roles/platform/tasks/validate.yml b/roles/platform/tasks/validate.yml index ac0344cf..81eed5ed 100644 --- a/roles/platform/tasks/validate.yml +++ b/roles/platform/tasks/validate.yml @@ -73,4 +73,5 @@ ansible.builtin.command: echo CDP_PROFILE is $CDP_PROFILE - name: Include provider-specific Platform validation Tasks - ansible.builtin.include_tasks: "validate_{{ plat__infra_type | lower }}.yml" \ No newline at end of file + ansible.builtin.include_tasks: "validate_{{ plat__infra_type | lower }}_{{ plat__infra_deployment }}.yml" + # ansible.builtin.include_tasks: "validate_{{ plat__infra_type | lower }}.yml" diff --git a/roles/platform/tasks/validate_aws_terraform.yml b/roles/platform/tasks/validate_aws_terraform.yml new file mode 100644 index 00000000..986117c0 --- /dev/null +++ b/roles/platform/tasks/validate_aws_terraform.yml @@ -0,0 +1,32 @@ +--- + +# Copyright 2021 Cloudera, Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +- name: Mandatory auth parameters for AWS + ansible.builtin.assert: + that: + - "{{ __auth_fact_item }} is defined" + - "{{ __auth_fact_item }} is string" + - "{{ __auth_fact_item }} | trim | length > 0" + fail_msg: "Authentication parameter, '{{ __auth_fact_item }}', is invalid." + quiet: yes + loop_control: + loop_var: __auth_fact_item + loop: + - plat__public_key_id + +- name: Print Executing Terraform message + ansible.builtin.debug: + msg: "Executing Terraform. Value of plat__infra_deployment = {{ plat__infra_deployment }}" \ No newline at end of file diff --git a/roles/platform/template/aws/plat_aws_authz.tf.j2 b/roles/platform/template/aws/plat_aws_authz.tf.j2 new file mode 100644 index 00000000..4d29020b --- /dev/null +++ b/roles/platform/template/aws/plat_aws_authz.tf.j2 @@ -0,0 +1,320 @@ +# ------- IAM Managed Policies ------- +# **1. AWS Cross Account Policy** +# The policy here is a dict variable so we'll use the variable +# directly in the aws_iam_policy resource. +resource "aws_iam_policy" "{{ plat__aws_xaccount_policy_name }}" { + name = "{{ plat__aws_xaccount_policy_name }}" + description = "CDP Cross Account policy for {{ plat__namespace }}" + + tags = merge(var.env_tags,{Name = "{{ plat__aws_xaccount_policy_name }}"}) + + policy = < Date: Fri, 1 Oct 2021 09:54:27 +0100 Subject: [PATCH 02/33] Refactor name of deployment engine variable Signed-off-by: Jim Enright --- roles/common/defaults/main.yml | 2 +- roles/infrastructure/defaults/main.yml | 2 +- .../infrastructure/tasks/initialize_aws_terraform.yml | 6 +++++- roles/infrastructure/tasks/setup_aws_terraform.yml | 10 +++++++++- roles/infrastructure/tasks/validate_aws_terraform.yml | 2 +- roles/platform/defaults/main.yml | 6 +++--- roles/platform/tasks/initialize_aws_terraform.yml | 4 ++++ 7 files changed, 24 insertions(+), 8 deletions(-) diff --git a/roles/common/defaults/main.yml b/roles/common/defaults/main.yml index 11cfa48e..af0a0fff 100644 --- a/roles/common/defaults/main.yml +++ b/roles/common/defaults/main.yml @@ -57,7 +57,7 @@ common__ngw_suffix: "{{ globals.labels.nat_gateway | defau common__unique_storage_name_suffix: "{{ globals.storage.name | default((common__region + common__aws_profile) if 'aws' in common__infra_type else common__region) }}" # Infra -common__infra_deployment: "{{ globals.infra_deployment | default() }}" +common__infra_deployment_engine: "{{ globals.infra_deployment_engine | default() }}" common__infra_type: "{{ globals.infra_type | default('aws') }}" common__public_key_file: "{{ globals.ssh.public_key_file | default('') }}" common__namespace_cdp: "{{ globals.namespace_cdp | default([common__namespace, common__namespace_unique_suffix] | join('-')) }}" diff --git a/roles/infrastructure/defaults/main.yml b/roles/infrastructure/defaults/main.yml index 2abf6994..34d194db 100644 --- a/roles/infrastructure/defaults/main.yml +++ b/roles/infrastructure/defaults/main.yml @@ -28,7 +28,7 @@ infra__vpc_public_subnets_suffix: "{{ common__vpc_public_subnets_suffix }}" # NOTE: Added by jenright for Terraform # Deployment type -infra__deployment: "{{ common__infra_deployment }}" +infra__deployment_engine: "{{ common__infra_deployment_engine }}" # Location of output from template module which creates Terraform infra__terraform_tmp_dir: "{{ common__terraform_tmp_dir | default('./jenright_tmp_terraform_code') }}" infra__terraform_workspace_dir: "{{ common__terraform_workspace_dir | default( playbook_dir + '/.namespaces') }}" diff --git a/roles/infrastructure/tasks/initialize_aws_terraform.yml b/roles/infrastructure/tasks/initialize_aws_terraform.yml index 1145f242..a2754394 100644 --- a/roles/infrastructure/tasks/initialize_aws_terraform.yml +++ b/roles/infrastructure/tasks/initialize_aws_terraform.yml @@ -39,4 +39,8 @@ template: src: 'template/{{ infra__type }}/infra_{{ infra__type }}_compute.tf.j2' dest: "{{ infra__terraform_tmp_dir }}/infra/infra_compute.tf" - no_log: false \ No newline at end of file + no_log: false + + - name: Prompt added by jenright + pause: + prompt: "Terraform infra files created in {{ infra__terraform_tmp_dir }}/infra" \ No newline at end of file diff --git a/roles/infrastructure/tasks/setup_aws_terraform.yml b/roles/infrastructure/tasks/setup_aws_terraform.yml index c12e2796..41580481 100644 --- a/roles/infrastructure/tasks/setup_aws_terraform.yml +++ b/roles/infrastructure/tasks/setup_aws_terraform.yml @@ -24,6 +24,10 @@ dest: "{{ infra__terraform_workspace_dir }}/workspace/infra" # when: not workdir.stat.exists # TODO: This won't override if any changes to .tf are made. Good or Bad? + - name: Prompt added by jenright + pause: + prompt: "Ready to do Terraform apply on infra files in {{ infra__terraform_workspace_dir }}/workspace/infra" + - name: Applying terraform community.general.terraform: # TODO: Fix workspace_dir_path @@ -34,4 +38,8 @@ register: tf_result retries: 3 delay: 10 - until: tf_result is succeeded \ No newline at end of file + until: tf_result is succeeded + + - name: Prompt added by jenright + pause: + prompt: "Terraform apply on infra files complete. Check AWS Console." diff --git a/roles/infrastructure/tasks/validate_aws_terraform.yml b/roles/infrastructure/tasks/validate_aws_terraform.yml index 98a303cb..28ec10d4 100644 --- a/roles/infrastructure/tasks/validate_aws_terraform.yml +++ b/roles/infrastructure/tasks/validate_aws_terraform.yml @@ -32,4 +32,4 @@ - name: Print Executing Terraform message ansible.builtin.debug: - msg: "Executing Terraform. Value of infra__deployment = {{ infra__deployment }}" \ No newline at end of file + msg: "Executing Terraform. Value of infra__deployment_engine = {{ infra__deployment_engine }}" \ No newline at end of file diff --git a/roles/platform/defaults/main.yml b/roles/platform/defaults/main.yml index d236f1d0..2326f763 100644 --- a/roles/platform/defaults/main.yml +++ b/roles/platform/defaults/main.yml @@ -21,10 +21,10 @@ # Labels # NOTE: Added by jenright for Terraform # Deployment type -plat__infra_deployment: "{{ common__infra_deployment }}" +plat__infra_deployment_engine_engine: "{{ common__infra_deployment_engine }}" # Location of output from template module which creates Terraform -plat__terraform_tmp_dir: "{{ common__terraform_tmp_dir | default('./jenright_tmp_terraform_code') }}" -plat__terraform_workspace_dir: "{{ common__terraform_workspace_dir | default( playbook_dir + '/.namespaces') }}" +plat__terraform_tmp_dir: "{{ common__terraform_tmp_dir | default('./jenright_tmp_terraform_code') }}" +plat__terraform_workspace_dir: "{{ common__terraform_workspace_dir | default( playbook_dir + '/.namespaces') }}" plat__infra_type: "{{ common__infra_type }}" plat__region: "{{ common__region }}" diff --git a/roles/platform/tasks/initialize_aws_terraform.yml b/roles/platform/tasks/initialize_aws_terraform.yml index 30ef287c..bcdd9b77 100644 --- a/roles/platform/tasks/initialize_aws_terraform.yml +++ b/roles/platform/tasks/initialize_aws_terraform.yml @@ -34,3 +34,7 @@ src: 'template/{{ plat__infra_type }}/terraform_variables.tf.j2' dest: "{{ plat__terraform_tmp_dir }}/roles/variables.tf" no_log: false + + - name: Prompt added by jenright + pause: + prompt: "PART 1 - Terraform role & policy files created in {{ plat__terraform_tmp_dir }}/roles" From 30117ee9d734862583ec0294471f674758287b29 Mon Sep 17 00:00:00 2001 From: Jim Enright Date: Fri, 1 Oct 2021 09:54:28 +0100 Subject: [PATCH 03/33] Update infrastructure and platform roles to execute Terraform tasks Signed-off-by: Jim Enright --- .../infrastructure/tasks/initialize_setup.yml | 6 +- roles/infrastructure/tasks/setup.yml | 30 ++-- ..._aws_terraform.yml => setup_terraform.yml} | 0 roles/infrastructure/tasks/validate.yml | 10 +- roles/platform/defaults/main.yml | 2 +- .../tasks/initialize_aws_terraform.yml | 8 +- roles/platform/tasks/initialize_setup.yml | 6 +- roles/platform/tasks/setup.yml | 16 ++- roles/platform/tasks/setup_aws_authz.yml | 4 - roles/platform/tasks/setup_aws_env.yml | 19 +++ .../tasks/setup_aws_terraform_authz.yml | 131 ++++++++++++++++++ roles/platform/tasks/validate.yml | 12 +- .../platform/tasks/validate_aws_terraform.yml | 4 +- 13 files changed, 211 insertions(+), 37 deletions(-) rename roles/infrastructure/tasks/{setup_aws_terraform.yml => setup_terraform.yml} (100%) create mode 100644 roles/platform/tasks/setup_aws_terraform_authz.yml diff --git a/roles/infrastructure/tasks/initialize_setup.yml b/roles/infrastructure/tasks/initialize_setup.yml index 71535967..8b4c9082 100644 --- a/roles/infrastructure/tasks/initialize_setup.yml +++ b/roles/infrastructure/tasks/initialize_setup.yml @@ -25,5 +25,7 @@ ansible.builtin.include_tasks: "initialize_setup_{{ infra__type | lower }}.yml" # NOTE: Added by jenright, Terraform -- name: Include tasks for provider-specific Infrastructure initialization - ansible.builtin.include_tasks: "initialize_{{ infra__type | lower }}_{{ infra__deployment }}.yml" +# QUESTION: Do we make this generic (i.e. no infra__type) +- name: Include Terraform tasks for provider-specific Infrastructure initialization + ansible.builtin.include_tasks: "initialize_{{ infra__type | lower }}_{{ infra__deployment_engine }}.yml" + when: infra__deployment_engine == 'terraform' diff --git a/roles/infrastructure/tasks/setup.yml b/roles/infrastructure/tasks/setup.yml index 59a9298a..c97462f1 100644 --- a/roles/infrastructure/tasks/setup.yml +++ b/roles/infrastructure/tasks/setup.yml @@ -16,19 +16,25 @@ # tasks file for setup -- name: Set up provider-specific Infrastructure artifacts - ansible.builtin.include_tasks: "setup_{{ infra__type | lower }}_{{ infra_deployment }}.yml" +- name: Set up for Ansible deployment engine + when: infra__deployment_engine == 'ansible' + block: + - name: Set up provider-specific Infrastructure network + ansible.builtin.include_tasks: "setup_{{ infra__type | lower }}_network.yml" -# - name: Set up provider-specific Infrastructure network -# ansible.builtin.include_tasks: "setup_{{ infra__type | lower }}_network.yml" + - name: Set up provider-specific Infrastructure storage + ansible.builtin.include_tasks: "setup_{{ infra__type | lower }}_storage.yml" -# - name: Set up provider-specific Infrastructure storage -# ansible.builtin.include_tasks: "setup_{{ infra__type | lower }}_storage.yml" + - name: Set Up localised provider-specific Storage Utility Service + when: infra__create_utility_service + ansible.builtin.include_tasks: "setup_{{ infra__type | lower }}_utility_service.yml" -# - name: Set Up localised provider-specific Storage Utility Service -# when: infra__create_utility_service -# ansible.builtin.include_tasks: "setup_{{ infra__type | lower }}_utility_service.yml" + - name: Set up provider-specific Infrastructure Compute + when: infra__dynamic_inventory_count + ansible.builtin.include_tasks: "setup_{{ infra__type | lower }}_compute.yml" -# - name: Set up provider-specific Infrastructure Compute -# when: infra__dynamic_inventory_count -# ansible.builtin.include_tasks: "setup_{{ infra__type | lower }}_compute.yml" \ No newline at end of file +- name: Set up for Terraform deployment engine + when: infra__deployment_engine == 'terraform' + block: + - name: Set up Terraform Infrastructure artifacts + ansible.builtin.include_tasks: "setup_{{ infra__deployment_engine }}.yml" diff --git a/roles/infrastructure/tasks/setup_aws_terraform.yml b/roles/infrastructure/tasks/setup_terraform.yml similarity index 100% rename from roles/infrastructure/tasks/setup_aws_terraform.yml rename to roles/infrastructure/tasks/setup_terraform.yml diff --git a/roles/infrastructure/tasks/validate.yml b/roles/infrastructure/tasks/validate.yml index 7b64cf59..7dcb289a 100644 --- a/roles/infrastructure/tasks/validate.yml +++ b/roles/infrastructure/tasks/validate.yml @@ -22,6 +22,10 @@ - infra__private_key_file is string fail_msg: "Invalid SSH private key file for Dynamic Inventory. Key file must be a string." -- name: Validate provider-specific Infrastructure parameters - ansible.builtin.include_tasks: "validate_{{ infra__type | lower }}_{{ infra_deployment }}.yml" - # ansible.builtin.include_tasks: "validate_{{ infra__type | lower }}_terraform.yml" +- name: Validate provider-specific Infrastructure parameters - Ansible + ansible.builtin.include_tasks: "validate_{{ infra__type | lower }}.yml" + when: infra__deployment_engine == 'ansible' + +- name: Validate Terraform provider-specific Infrastructure parameters + ansible.builtin.include_tasks: "validate_{{ infra__type | lower }}_{{ infra__deployment_engine }}.yml" + when: infra__deployment_engine == 'terraform' diff --git a/roles/platform/defaults/main.yml b/roles/platform/defaults/main.yml index 2326f763..1b81a70e 100644 --- a/roles/platform/defaults/main.yml +++ b/roles/platform/defaults/main.yml @@ -21,7 +21,7 @@ # Labels # NOTE: Added by jenright for Terraform # Deployment type -plat__infra_deployment_engine_engine: "{{ common__infra_deployment_engine }}" +plat__infra_deployment_engine: "{{ common__infra_deployment_engine }}" # Location of output from template module which creates Terraform plat__terraform_tmp_dir: "{{ common__terraform_tmp_dir | default('./jenright_tmp_terraform_code') }}" plat__terraform_workspace_dir: "{{ common__terraform_workspace_dir | default( playbook_dir + '/.namespaces') }}" diff --git a/roles/platform/tasks/initialize_aws_terraform.yml b/roles/platform/tasks/initialize_aws_terraform.yml index bcdd9b77..5e01c1be 100644 --- a/roles/platform/tasks/initialize_aws_terraform.yml +++ b/roles/platform/tasks/initialize_aws_terraform.yml @@ -19,22 +19,22 @@ block: - name: Create terraform template dir file: - path: "{{ plat__terraform_tmp_dir }}/roles" + path: "{{ plat__terraform_tmp_dir }}/plat" state: directory # Apply template for Terraform provider - name: Generate Terraform Provider template: src: 'template/{{ plat__infra_type }}/provider.tf.j2' - dest: "{{ plat__terraform_tmp_dir }}/roles/provider.tf" + dest: "{{ plat__terraform_tmp_dir }}/plat/provider.tf" # Apply template for Terraform variables - name: Generate Terraform Variables template: src: 'template/{{ plat__infra_type }}/terraform_variables.tf.j2' - dest: "{{ plat__terraform_tmp_dir }}/roles/variables.tf" + dest: "{{ plat__terraform_tmp_dir }}/plat/variables.tf" no_log: false - name: Prompt added by jenright pause: - prompt: "PART 1 - Terraform role & policy files created in {{ plat__terraform_tmp_dir }}/roles" + prompt: "PART 1 - Terraform role & policy files created in {{ plat__terraform_tmp_dir }}/plat" diff --git a/roles/platform/tasks/initialize_setup.yml b/roles/platform/tasks/initialize_setup.yml index a87f43b3..0770abcd 100644 --- a/roles/platform/tasks/initialize_setup.yml +++ b/roles/platform/tasks/initialize_setup.yml @@ -23,6 +23,8 @@ - name: Include provider-specific initialization setup ansible.builtin.include_tasks: "initialize_setup_{{ plat__infra_type | lower }}.yml" -# Added by jenright, Terraform +# NOTE: Added by jenright, Terraform +# QUESTION: Do we make this generic (i.e. no infra__type) - name: Include tasks for provider-specific Infrastructure initialization - ansible.builtin.include_tasks: "initialize_{{ plat__infra_type | lower }}_{{ plat__infra_deployment }}.yml" + ansible.builtin.include_tasks: "initialize_{{ plat__infra_type | lower }}_{{ plat__infra_deployment_engine }}.yml" + when: plat__infra_deployment_engine == 'terraform' \ No newline at end of file diff --git a/roles/platform/tasks/setup.yml b/roles/platform/tasks/setup.yml index bb132f8f..f63649d6 100644 --- a/roles/platform/tasks/setup.yml +++ b/roles/platform/tasks/setup.yml @@ -14,11 +14,17 @@ # See the License for the specific language governing permissions and # limitations under the License. -- name: Include provider-specific CDP Public Roles and Policies setup tasks +- name: Include Ansible deployment engine provider-specific CDP Public Roles and Policies setup tasks ansible.builtin.include_tasks: "setup_{{ plat__infra_type | lower }}_authz.yml" + when: plat__infra_deployment_engine == 'ansible' -# - name: Include provider-specific CDP Environment setup tasks -# ansible.builtin.include_tasks: "setup_{{ plat__infra_type | lower }}_env.yml" +# NOTE: Could make this generic if we didn't have the template and policy download +- name: Include Terraform deployment engine provider-specific CDP Public Roles and Policies setup tasks + ansible.builtin.include_tasks: "setup_{{ plat__infra_type | lower }}_{{ plat__infra_deployment_engine }}_authz.yml" + when: plat__infra_deployment_engine == 'terraform' -# - name: Include shared CDP Public Environment Setup Tasks -# ansible.builtin.include_tasks: "setup_base.yml" +- name: Include provider-specific CDP Environment setup tasks + ansible.builtin.include_tasks: "setup_{{ plat__infra_type | lower }}_env.yml" + +- name: Include shared CDP Public Environment Setup Tasks + ansible.builtin.include_tasks: "setup_base.yml" diff --git a/roles/platform/tasks/setup_aws_authz.yml b/roles/platform/tasks/setup_aws_authz.yml index 8e28747b..8d331bd4 100644 --- a/roles/platform/tasks/setup_aws_authz.yml +++ b/roles/platform/tasks/setup_aws_authz.yml @@ -30,10 +30,6 @@ loop: "{{ plat__aws_policy_urls | dict2items }}" register: __aws_policy_documents -- name: JE Debug Print __aws_policy_tmpdir - ansible.builtin.debug: - var: __aws_policy_tmpdir - - name: Process AWS default policy documents ansible.builtin.include_tasks: aws_policy_regex.yml loop: "{{ __aws_policy_documents.results }}" diff --git a/roles/platform/tasks/setup_aws_env.yml b/roles/platform/tasks/setup_aws_env.yml index 61378d9a..3727e7a1 100644 --- a/roles/platform/tasks/setup_aws_env.yml +++ b/roles/platform/tasks/setup_aws_env.yml @@ -14,6 +14,25 @@ # See the License for the specific language governing permissions and # limitations under the License. +# - name: Debug variables with Terraform +# debug: +# msg: +# - "name: {{ plat__env_name }}" +# - "state: started" +# - "credential: {{ plat__xacccount_credential_name }}" +# - "cloud: {{ plat__infra_type }}" +# - "region: {{ plat__region }}" +# - "default_sg: {{ plat__aws_security_group_default_id }}" +# - "knox_sg: {{ plat__aws_security_group_knox_id }}" +# - "log_location: {{ plat__aws_storage_location }}" +# - "log_identity: {{ plat__aws_log_instance_profile_arn }}" +# - "public_key_id: {{ plat__public_key_id }}" +# - "workload_analytics: {{ plat__workload_analytics }}" +# - "vpc_id: {{ plat__aws_vpc_id }}" +# - "subnet_ids: {{ plat__aws_subnet_ids }}" +# - "s3_guard_name: {{ plat__aws_dynamodb_table_name }}" +# - "tags: {{ plat__tags }}" + - name: Set up CDP Environment Deployment on AWS cloudera.cloud.env: name: "{{ plat__env_name }}" diff --git a/roles/platform/tasks/setup_aws_terraform_authz.yml b/roles/platform/tasks/setup_aws_terraform_authz.yml new file mode 100644 index 00000000..a7a6d183 --- /dev/null +++ b/roles/platform/tasks/setup_aws_terraform_authz.yml @@ -0,0 +1,131 @@ +--- + +# Copyright 2021 Cloudera, Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +- name: Create a temporary directory for policy documents + ansible.builtin.tempfile: + prefix: "aws-policy-" + state: directory + register: __aws_policy_tmpdir + +- name: Download AWS default policy documents + ansible.builtin.get_url: + dest: "{{ __aws_policy_tmpdir.path }}" + url: "{{ __policy_url_item.value }}" + loop_control: + loop_var: __policy_url_item + label: "{{ __policy_url_item.key }}" + loop: "{{ plat__aws_policy_urls | dict2items }}" + register: __aws_policy_documents + +- name: JE Debug Print __aws_policy_tmpdir + ansible.builtin.debug: + var: __aws_policy_tmpdir + +- name: Process AWS default policy documents + ansible.builtin.include_tasks: aws_policy_regex.yml + loop: "{{ __aws_policy_documents.results }}" + loop_control: + loop_var: __aws_policy_document_item + label: "{{ __aws_policy_document_item.__policy_url_item.key }}" + +- name: Some variables for creation of IAM + debug: + msg: + - plat__aws_xaccount_account_policy = {{ plat__aws_xaccount_account_policy }} + - plat__aws_xaccount_policy_name = {{ plat__aws_xaccount_policy_name }} + +# ***************** TERRAFORM TEMPLATE PART 2 *********************** +# Needed here because the policy documents are only available after above tasks +# QUESTION: HOW CAN WE REARRANGE THIS? +# Apply template for Terraform auth resources +- name: Generate Terraform authz file + template: + src: 'template/{{ plat__infra_type }}/plat_{{ infra__type }}_authz.tf.j2' + dest: "{{ plat__terraform_tmp_dir }}/plat/plat_authz.tf" + no_log: false + +- name: Prompt added by jenright + pause: + prompt: "PART 2 - Terraform role & policy files created in {{ plat__terraform_tmp_dir }}/plat" +# ***************** END TERRAFORM TEMPLATE PART 2 *********************** + +# ***************** TERRAFORM APPLY *********************** +- name: Terraform local state + # when: terraform_state == "local" # TODO: Handle state + block: + - name: Check if workspace directory exists + # TODO: Fix workspace_dir_path + # stat: path={{ plat__terraform_tmp_dir }}/workspace_dir_path + stat: path={{ plat__terraform_tmp_dir }}/workspace/plat + register: workdir + + - name: Ensure the workspace directory exists + copy: + src: "{{ plat__terraform_tmp_dir }}/plat/" + # TODO: Fix workspace_dir_path + # dest: "{{ plat__terraform_workspace_dir }}/{{ workspace_dir_path }}" + dest: "{{ plat__terraform_workspace_dir }}/workspace/plat" + # when: not workdir.stat.exists # TODO: This won't override if any changes to .tf are made. Good or Bad? + + - name: Prompt added by jenright + pause: + prompt: "Ready to do Terraform apply on role files in {{ plat__terraform_workspace_dir }}/workspace/plat" + + - name: Applying terraform + community.general.terraform: + # TODO: Fix workspace_dir_path + # project_path: "{{ plat__terraform_workspace_dir }}/{{ workspace_dir_path }}" + project_path: "{{ plat__terraform_workspace_dir }}/workspace/plat" + state: "present" + force_init: yes + register: tf_result + retries: 3 + delay: 10 + until: tf_result is succeeded + + - name: Prompt added by jenright + pause: + prompt: "Terraform apply on role files complete. Check AWS Console." + +# ***************** END TERRAFORM APPLY *********************** + +# Now need to get create CDP Cross Account Credential +# TODO: Is there a better place to put this? +# First get the AWS Cross Account Role +- name: Query the AWS Cross Account Role + community.aws.iam_role_info: + name: "{{ plat__aws_xaccount_role_name }}" + region: "{{ plat__region }}" + register: __aws_xaccount_role_info + +- name: Print details of AWS cross account role + debug: + msg: + - Cross account role "{{ __aws_xaccount_role_info }}" + +- name: Create CDP Cross Account Credential for AWS + when: plat__xacccount_credential_name not in plat__cdp_credentials_list + cloudera.cloud.env_cred: + cloud: "{{ plat__infra_type }}" + name: "{{ plat__xacccount_credential_name }}" + role: "{{ __aws_xaccount_role_info.iam_roles[0].arn }}" + state: present + +# TODO: Need to figure out how to handle this with Terraform +# - name: Remove temporary directory for policy documents +# ansible.builtin.file: +# path: "{{ __aws_policy_tmpdir.path }}" +# state: absent diff --git a/roles/platform/tasks/validate.yml b/roles/platform/tasks/validate.yml index 81eed5ed..43682994 100644 --- a/roles/platform/tasks/validate.yml +++ b/roles/platform/tasks/validate.yml @@ -72,6 +72,12 @@ - name: Print CDP Profile to debug ansible.builtin.command: echo CDP_PROFILE is $CDP_PROFILE -- name: Include provider-specific Platform validation Tasks - ansible.builtin.include_tasks: "validate_{{ plat__infra_type | lower }}_{{ plat__infra_deployment }}.yml" - # ansible.builtin.include_tasks: "validate_{{ plat__infra_type | lower }}.yml" +- name: Include provider-specific Platform validation Tasks - Ansible + ansible.builtin.include_tasks: "validate_{{ plat__infra_type | lower }}.yml" + when: plat__infra_deployment_engine == 'ansible' + +- name: Include Terraform provider-specific Platform validation Tasks + ansible.builtin.include_tasks: "validate_{{ plat__infra_type | lower }}_{{ plat__infra_deployment_engine }}.yml" + when: plat__infra_deployment_engine == 'terraform' + + diff --git a/roles/platform/tasks/validate_aws_terraform.yml b/roles/platform/tasks/validate_aws_terraform.yml index 986117c0..fd3a70af 100644 --- a/roles/platform/tasks/validate_aws_terraform.yml +++ b/roles/platform/tasks/validate_aws_terraform.yml @@ -29,4 +29,6 @@ - name: Print Executing Terraform message ansible.builtin.debug: - msg: "Executing Terraform. Value of plat__infra_deployment = {{ plat__infra_deployment }}" \ No newline at end of file + msg: "Executing Terraform. Value of plat__infra_deployment_engine = {{ plat__infra_deployment_engine }}" + +# TODO: Put any Terraform specific stuff here \ No newline at end of file From 1635ac26931f58454098d343b4a0f9761b8aba50 Mon Sep 17 00:00:00 2001 From: Jim Enright Date: Fri, 1 Oct 2021 09:54:28 +0100 Subject: [PATCH 04/33] Add Terraform templates for AWS infra and roles Signed-off-by: Jim Enright --- roles/platform/template/aws/plat_aws_authz.tf.j2 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/roles/platform/template/aws/plat_aws_authz.tf.j2 b/roles/platform/template/aws/plat_aws_authz.tf.j2 index 4d29020b..d99ddc45 100644 --- a/roles/platform/template/aws/plat_aws_authz.tf.j2 +++ b/roles/platform/template/aws/plat_aws_authz.tf.j2 @@ -153,7 +153,7 @@ resource "aws_iam_role" "{{ plat__aws_idbroker_role_name }}" { # Create an instance profile for the iam_role resource "aws_iam_instance_profile" "{{ plat__aws_idbroker_role_name }}-instance-profile" { - name = "{{ plat__aws_idbroker_role_name }}-instance-profile" + name = "{{ plat__aws_idbroker_role_name }}" role = aws_iam_role.{{ plat__aws_idbroker_role_name }}.name } @@ -191,7 +191,7 @@ resource "aws_iam_role" "{{ plat__aws_log_role_name }}" { # Create an instance profile for the iam_role resource "aws_iam_instance_profile" "{{ plat__aws_log_role_name }}-instance-profile" { - name = "{{ plat__aws_log_role_name }}-instance-profile" + name = "{{ plat__aws_log_role_name }}" role = aws_iam_role.{{ plat__aws_log_role_name }}.name } @@ -245,7 +245,7 @@ resource "aws_iam_role" "{{ plat__aws_datalake_admin_role_name }}" { # Create an instance profile for the iam_role resource "aws_iam_instance_profile" "{{ plat__aws_datalake_admin_role_name }}-instance-profile" { - name = "{{ plat__aws_datalake_admin_role_name }}-instance-profile" + name = "{{ plat__aws_datalake_admin_role_name }}" role = aws_iam_role.{{ plat__aws_datalake_admin_role_name }}.name } @@ -296,7 +296,7 @@ resource "aws_iam_role" "{{ plat__aws_ranger_audit_role_name }}" { # Create an instance profile for the iam_role resource "aws_iam_instance_profile" "{{ plat__aws_ranger_audit_role_name }}-instance-profile" { - name = "{{ plat__aws_ranger_audit_role_name }}-instance-profile" + name = "{{ plat__aws_ranger_audit_role_name }}" role = aws_iam_role.{{ plat__aws_ranger_audit_role_name }}.name } From e2d90a98dd878d2e0a06a17e985321fb8193a378 Mon Sep 17 00:00:00 2001 From: Jim Enright Date: Fri, 1 Oct 2021 09:54:29 +0100 Subject: [PATCH 05/33] Add Terraform templates for AWS infra and roles Signed-off-by: Jim Enright --- roles/platform/tasks/initialize_setup.yml | 2 +- .../tasks/setup_aws_terraform_authz.yml | 16 ++- .../aws/plat_aws_authz_policies.tf.j2 | 85 ++++++++++++++++ ...authz.tf.j2 => plat_aws_authz_roles.tf.j2} | 98 +------------------ 4 files changed, 103 insertions(+), 98 deletions(-) create mode 100644 roles/platform/template/aws/plat_aws_authz_policies.tf.j2 rename roles/platform/template/aws/{plat_aws_authz.tf.j2 => plat_aws_authz_roles.tf.j2} (67%) diff --git a/roles/platform/tasks/initialize_setup.yml b/roles/platform/tasks/initialize_setup.yml index 0770abcd..9f657c31 100644 --- a/roles/platform/tasks/initialize_setup.yml +++ b/roles/platform/tasks/initialize_setup.yml @@ -25,6 +25,6 @@ # NOTE: Added by jenright, Terraform # QUESTION: Do we make this generic (i.e. no infra__type) -- name: Include tasks for provider-specific Infrastructure initialization +- name: Include tasks for provider-specific Terraform initialization ansible.builtin.include_tasks: "initialize_{{ plat__infra_type | lower }}_{{ plat__infra_deployment_engine }}.yml" when: plat__infra_deployment_engine == 'terraform' \ No newline at end of file diff --git a/roles/platform/tasks/setup_aws_terraform_authz.yml b/roles/platform/tasks/setup_aws_terraform_authz.yml index a7a6d183..d2b3dd3b 100644 --- a/roles/platform/tasks/setup_aws_terraform_authz.yml +++ b/roles/platform/tasks/setup_aws_terraform_authz.yml @@ -50,11 +50,19 @@ # ***************** TERRAFORM TEMPLATE PART 2 *********************** # Needed here because the policy documents are only available after above tasks # QUESTION: HOW CAN WE REARRANGE THIS? -# Apply template for Terraform auth resources -- name: Generate Terraform authz file +# Apply template for Terraform auth resources.... +# ...policies +- name: Generate Terraform authz file for policies template: - src: 'template/{{ plat__infra_type }}/plat_{{ infra__type }}_authz.tf.j2' - dest: "{{ plat__terraform_tmp_dir }}/plat/plat_authz.tf" + src: 'template/{{ plat__infra_type }}/plat_{{ plat__infra_type }}_authz_policies.tf.j2' + dest: "{{ plat__terraform_tmp_dir }}/plat/plat_authz_policies.tf" + no_log: false + +# ...roles +- name: Generate Terraform authz file for roles + template: + src: 'template/{{ plat__infra_type }}/plat_{{ plat__infra_type }}_authz_roles.tf.j2' + dest: "{{ plat__terraform_tmp_dir }}/plat/plat_authz_roles.tf" no_log: false - name: Prompt added by jenright diff --git a/roles/platform/template/aws/plat_aws_authz_policies.tf.j2 b/roles/platform/template/aws/plat_aws_authz_policies.tf.j2 new file mode 100644 index 00000000..f4a178c1 --- /dev/null +++ b/roles/platform/template/aws/plat_aws_authz_policies.tf.j2 @@ -0,0 +1,85 @@ +# ------- AWS Cross Account Policy ------- +# The policy here is a dict variable so we'll use the variable +# directly in the aws_iam_policy resource. +resource "aws_iam_policy" "{{ plat__aws_xaccount_policy_name }}" { + name = "{{ plat__aws_xaccount_policy_name }}" + description = "CDP Cross Account policy for {{ plat__namespace }}" + + tags = merge(var.env_tags,{Name = "{{ plat__aws_xaccount_policy_name }}"}) + + policy = < Date: Fri, 1 Oct 2021 09:54:29 +0100 Subject: [PATCH 06/33] Cleanup of Terraform tasks Signed-off-by: Jim Enright --- .../tasks/initialize_aws_terraform.yml | 14 ++++++++++++++ roles/infrastructure/tasks/setup_terraform.yml | 16 ++++++++++++++++ .../platform/tasks/setup_aws_terraform_authz.yml | 8 ++++---- 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/roles/infrastructure/tasks/initialize_aws_terraform.yml b/roles/infrastructure/tasks/initialize_aws_terraform.yml index a2754394..e4d9c1d8 100644 --- a/roles/infrastructure/tasks/initialize_aws_terraform.yml +++ b/roles/infrastructure/tasks/initialize_aws_terraform.yml @@ -1,3 +1,17 @@ +# Copyright 2021 Cloudera, Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + - name: Create terraform template .tf files when: infra__terraform_tmp_dir is defined # TODO: Is this needed? block: diff --git a/roles/infrastructure/tasks/setup_terraform.yml b/roles/infrastructure/tasks/setup_terraform.yml index 41580481..bf0076e4 100644 --- a/roles/infrastructure/tasks/setup_terraform.yml +++ b/roles/infrastructure/tasks/setup_terraform.yml @@ -1,3 +1,19 @@ +--- + +# Copyright 2021 Cloudera, Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + - name: Deploy terraform infrastructure block: diff --git a/roles/platform/tasks/setup_aws_terraform_authz.yml b/roles/platform/tasks/setup_aws_terraform_authz.yml index d2b3dd3b..410d9f7f 100644 --- a/roles/platform/tasks/setup_aws_terraform_authz.yml +++ b/roles/platform/tasks/setup_aws_terraform_authz.yml @@ -76,15 +76,15 @@ block: - name: Check if workspace directory exists # TODO: Fix workspace_dir_path - # stat: path={{ plat__terraform_tmp_dir }}/workspace_dir_path - stat: path={{ plat__terraform_tmp_dir }}/workspace/plat + # stat: path={{ plat__terraform_workspace_dir }}/workspace_dir_path/plat + stat: path={{ plat__terraform_workspace_dir }}/workspace/plat register: workdir - name: Ensure the workspace directory exists copy: src: "{{ plat__terraform_tmp_dir }}/plat/" # TODO: Fix workspace_dir_path - # dest: "{{ plat__terraform_workspace_dir }}/{{ workspace_dir_path }}" + # dest: "{{ plat__terraform_workspace_dir }}/{{ workspace_dir_path }}/plat" dest: "{{ plat__terraform_workspace_dir }}/workspace/plat" # when: not workdir.stat.exists # TODO: This won't override if any changes to .tf are made. Good or Bad? @@ -95,7 +95,7 @@ - name: Applying terraform community.general.terraform: # TODO: Fix workspace_dir_path - # project_path: "{{ plat__terraform_workspace_dir }}/{{ workspace_dir_path }}" + # project_path: "{{ plat__terraform_workspace_dir }}/{{ workspace_dir_path }}/plat" project_path: "{{ plat__terraform_workspace_dir }}/workspace/plat" state: "present" force_init: yes From 13fba68c04ca76a6ef02284eb414a7f99f872c3a Mon Sep 17 00:00:00 2001 From: Jim Enright Date: Fri, 1 Oct 2021 09:54:30 +0100 Subject: [PATCH 07/33] Update infrastructure and platform roles for teardown of Terraform resources Signed-off-by: Jim Enright --- .../tasks/initialize_teardown.yml | 7 +- .../initialize_teardown_aws_terraform.yml | 61 ++++++++++++++ roles/infrastructure/tasks/teardown.yml | 29 ++++--- .../tasks/teardown_terraform.yml | 61 ++++++++++++++ roles/platform/tasks/initialize_teardown.yml | 6 ++ .../initialize_teardown_aws_terraform.yml | 82 ++++++++++++++++++ roles/platform/tasks/teardown.yml | 9 +- .../tasks/teardown_aws_terraform_authz.yml | 84 +++++++++++++++++++ 8 files changed, 326 insertions(+), 13 deletions(-) create mode 100644 roles/infrastructure/tasks/initialize_teardown_aws_terraform.yml create mode 100644 roles/infrastructure/tasks/teardown_terraform.yml create mode 100644 roles/platform/tasks/initialize_teardown_aws_terraform.yml create mode 100644 roles/platform/tasks/teardown_aws_terraform_authz.yml diff --git a/roles/infrastructure/tasks/initialize_teardown.yml b/roles/infrastructure/tasks/initialize_teardown.yml index f8bea6ca..5e04dd8b 100644 --- a/roles/infrastructure/tasks/initialize_teardown.yml +++ b/roles/infrastructure/tasks/initialize_teardown.yml @@ -21,4 +21,9 @@ ansible.builtin.include_tasks: "initialize_{{ infra__type | lower }}.yml" - name: Include tasks for provider-specific Infrastructure teardown initialization - ansible.builtin.include_tasks: "initialize_teardown_{{ infra__type | lower }}.yml" \ No newline at end of file + ansible.builtin.include_tasks: "initialize_teardown_{{ infra__type | lower }}.yml" + +# NOTE: Added by jenright, Terraform +- name: Include Terraform tasks for provider-specific Infrastructure teardown initialization + ansible.builtin.include_tasks: "initialize_teardown_{{ infra__type | lower }}_{{ infra__deployment_engine }}.yml" + when: infra__deployment_engine == 'terraform' \ No newline at end of file diff --git a/roles/infrastructure/tasks/initialize_teardown_aws_terraform.yml b/roles/infrastructure/tasks/initialize_teardown_aws_terraform.yml new file mode 100644 index 00000000..5126b2d1 --- /dev/null +++ b/roles/infrastructure/tasks/initialize_teardown_aws_terraform.yml @@ -0,0 +1,61 @@ +# Copyright 2021 Cloudera, Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +- name: Create terraform template .tf files + when: infra__terraform_tmp_dir is defined # TODO: Is this needed? + block: + - name: Create terraform template dir + file: + path: "{{ infra__terraform_tmp_dir }}/infra" + state: directory + + # Apply template for Terraform provider + - name: Generate Terraform Provider + template: + src: 'template/{{ infra__type }}/provider.tf.j2' + dest: "{{ infra__terraform_tmp_dir }}/infra/provider.tf" + + # Apply template for Terraform variables + - name: Generate Terraform Variables + template: + src: 'template/{{ infra__type }}/terraform_variables.tf.j2' + dest: "{{ infra__terraform_tmp_dir }}/infra/variables.tf" + no_log: false + + # NOTE: These don't work because not all variables are defined during teardown + # # Apply template for Terraform infra.... + # # ...network resources + # - name: Generate Terraform infra file for network resources + # template: + # src: 'template/{{ infra__type }}/infra_{{ infra__type }}_network.tf.j2' + # dest: "{{ infra__terraform_tmp_dir }}/infra/infra_network.tf" + # no_log: false + + # # ...storage resources + # - name: Generating Terraform infra file for storage resources + # template: + # src: 'template/{{ infra__type }}/infra_{{ infra__type }}_storage.tf.j2' + # dest: "{{ infra__terraform_tmp_dir }}/infra/infra_storage.tf" + # no_log: false + + # # ...compute resources + # - name: Generating Terraform infra file for compute resources + # template: + # src: 'template/{{ infra__type }}/infra_{{ infra__type }}_compute.tf.j2' + # dest: "{{ infra__terraform_tmp_dir }}/infra/infra_compute.tf" + # no_log: false + + - name: Prompt added by jenright + pause: + prompt: "Terraform infra files for Teardown created in {{ infra__terraform_tmp_dir }}/infra" \ No newline at end of file diff --git a/roles/infrastructure/tasks/teardown.yml b/roles/infrastructure/tasks/teardown.yml index b91ab13a..1b35287b 100644 --- a/roles/infrastructure/tasks/teardown.yml +++ b/roles/infrastructure/tasks/teardown.yml @@ -14,17 +14,26 @@ # See the License for the specific language governing permissions and # limitations under the License. -- name: Teardown provider-specific Infrastructure compute - ansible.builtin.include_tasks: "teardown_{{ infra__type | lower }}_compute.yml" +- name: Teardown for Ansible deployment engine + when: infra__deployment_engine == 'ansible' + block: + - name: Teardown provider-specific Infrastructure compute + ansible.builtin.include_tasks: "teardown_{{ infra__type | lower }}_compute.yml" -- name: Teardown provider-specific Infrastructure storage - ansible.builtin.include_tasks: "teardown_{{ infra__type | lower }}_storage.yml" + - name: Teardown provider-specific Infrastructure storage + ansible.builtin.include_tasks: "teardown_{{ infra__type | lower }}_storage.yml" -- name: Teardown provider-specific Infrastructure network - ansible.builtin.include_tasks: "teardown_{{ infra__type | lower }}_network.yml" + - name: Teardown provider-specific Infrastructure network + ansible.builtin.include_tasks: "teardown_{{ infra__type | lower }}_network.yml" -- name: Teardown provider-specific Utility Services - ansible.builtin.include_tasks: "teardown_{{ infra__type | lower }}_utility_service.yml" + - name: Teardown provider-specific Utility Services + ansible.builtin.include_tasks: "teardown_{{ infra__type | lower }}_utility_service.yml" -- name: Teardown provider-specific Infrastructure artifacts - ansible.builtin.include_tasks: "teardown_{{ infra__type | lower }}.yml" \ No newline at end of file + - name: Teardown provider-specific Infrastructure artifacts + ansible.builtin.include_tasks: "teardown_{{ infra__type | lower }}.yml" + +- name: Teardown for Terraform deployment engine + when: infra__deployment_engine == 'terraform' + block: + - name: Teardown Terraform Infrastructure artifacts + ansible.builtin.include_tasks: "teardown_{{ infra__deployment_engine }}.yml" diff --git a/roles/infrastructure/tasks/teardown_terraform.yml b/roles/infrastructure/tasks/teardown_terraform.yml new file mode 100644 index 00000000..c5e42adb --- /dev/null +++ b/roles/infrastructure/tasks/teardown_terraform.yml @@ -0,0 +1,61 @@ +--- + +# Copyright 2021 Cloudera, Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +- name: Destroy terraform infrastructure + block: + + - name: Confirm I got to teardown_terraform + ansible.builtin.debug: + msg: + - "I'm here doing to terraform destroy" + - "Here's the workspace: {{ infra__terraform_workspace_dir }}" + + - name: Terraform local state + # when: terraform_state == "local" # TODO: Handle state + block: + - name: Check if workspace directory exists + # TODO: Fix workspace_dir_path + # stat: path={{ infra__terraform_workspace_dir }}/workspace_dir_path + stat: path={{ infra__terraform_workspace_dir }}/workspace/infra + register: workdir + + - name: Ensure the workspace directory exists + copy: + src: "{{ infra__terraform_tmp_dir }}/infra/" + # TODO: Fix workspace_dir_path + # dest: "{{ infra__terraform_workspace_dir }}/{{ workspace_dir_path }}" + dest: "{{ infra__terraform_workspace_dir }}/workspace/infra" + # when: not workdir.stat.exists # TODO: This won't override if any changes to .tf are made. Good or Bad? + + - name: Prompt added by jenright + pause: + prompt: "Ready to do Terraform destroy on infra files in {{ infra__terraform_workspace_dir }}/workspace/infra" + + - name: Destroy terraform infra resources + community.general.terraform: + # TODO: Fix workspace_dir_path + # project_path: "{{ infra__terraform_workspace_dir }}/{{ workspace_dir_path }}" + project_path: "{{ infra__terraform_workspace_dir }}/workspace/infra" + state: "absent" + force_init: yes + register: tf_result + retries: 3 + delay: 10 + until: tf_result is succeeded + + - name: Prompt added by jenright + pause: + prompt: "Terraform destroy on infra files complete. Check AWS Console." diff --git a/roles/platform/tasks/initialize_teardown.yml b/roles/platform/tasks/initialize_teardown.yml index 81dab28f..a5d0ad4a 100644 --- a/roles/platform/tasks/initialize_teardown.yml +++ b/roles/platform/tasks/initialize_teardown.yml @@ -37,3 +37,9 @@ - name: Include provider-specific resources for CDP Public Environment teardown ansible.builtin.include_tasks: "initialize_teardown_{{ plat__infra_type | lower }}.yml" + +# NOTE: Added by jenright, Terraform +# QUESTION: Do we make this generic (i.e. no infra__type) +- name: Include tasks for provider-specific Terraform teardown + ansible.builtin.include_tasks: "initialize_teardown_{{ plat__infra_type | lower }}_{{ plat__infra_deployment_engine }}.yml" + when: plat__infra_deployment_engine == 'terraform' diff --git a/roles/platform/tasks/initialize_teardown_aws_terraform.yml b/roles/platform/tasks/initialize_teardown_aws_terraform.yml new file mode 100644 index 00000000..1f3f73fa --- /dev/null +++ b/roles/platform/tasks/initialize_teardown_aws_terraform.yml @@ -0,0 +1,82 @@ +# Copyright 2021 Cloudera, Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +- name: Create terraform template .tf files + when: plat__terraform_tmp_dir is defined # TODO: Is this needed? + block: + - name: Create terraform template dir + file: + path: "{{ plat__terraform_tmp_dir }}/plat" + state: directory + + # Apply template for Terraform provider + - name: Generate Terraform Provider + template: + src: 'template/{{ plat__infra_type }}/provider.tf.j2' + dest: "{{ plat__terraform_tmp_dir }}/plat/provider.tf" + + # Apply template for Terraform variables + - name: Generate Terraform Variables + template: + src: 'template/{{ plat__infra_type }}/terraform_variables.tf.j2' + dest: "{{ plat__terraform_tmp_dir }}/plat/variables.tf" + no_log: false + +- name: Create a temporary directory for policy documents + ansible.builtin.tempfile: + prefix: "aws-policy-" + state: directory + register: __aws_policy_tmpdir + +- name: Download AWS default policy documents + ansible.builtin.get_url: + dest: "{{ __aws_policy_tmpdir.path }}" + url: "{{ __policy_url_item.value }}" + loop_control: + loop_var: __policy_url_item + label: "{{ __policy_url_item.key }}" + loop: "{{ plat__aws_policy_urls | dict2items }}" + register: __aws_policy_documents + +- name: Process AWS default policy documents + ansible.builtin.include_tasks: aws_policy_regex.yml + loop: "{{ __aws_policy_documents.results }}" + loop_control: + loop_var: __aws_policy_document_item + label: "{{ __aws_policy_document_item.__policy_url_item.key }}" + +- name: Copy AWS policy documents to Terraform workspace_dir_path + copy: + src: "{{ __aws_policy_tmpdir.path }}/" + dest: "{{ plat__terraform_tmp_dir }}/plat/policy_docs/" + +# NOTE: These don't work because not all variables are defined during teardown +# # Apply template for Terraform auth resources.... +# # ...policies +# - name: Generate Terraform authz file for policies +# template: +# src: 'template/{{ plat__infra_type }}/plat_{{ plat__infra_type }}_authz_policies.tf.j2' +# dest: "{{ plat__terraform_tmp_dir }}/plat/plat_authz_policies.tf" +# no_log: false + +# # ...roles +# - name: Generate Terraform authz file for roles +# template: +# src: 'template/{{ plat__infra_type }}/plat_{{ plat__infra_type }}_authz_roles.tf.j2' +# dest: "{{ plat__terraform_tmp_dir }}/plat/plat_authz_roles.tf" +# no_log: false + +- name: Prompt added by jenright + pause: + prompt: "Terraform role & policy files for Teardown created in {{ plat__terraform_tmp_dir }}/plat" diff --git a/roles/platform/tasks/teardown.yml b/roles/platform/tasks/teardown.yml index ae839299..066afdcd 100644 --- a/roles/platform/tasks/teardown.yml +++ b/roles/platform/tasks/teardown.yml @@ -36,5 +36,10 @@ name: "{{ plat__env_name }}" state: absent -- name: Tear down provider-specific roles and policies - ansible.builtin.include_tasks: "teardown_{{ plat__infra_type | lower }}_authz.yml" \ No newline at end of file +- name: Tear down provider-specific roles and policies - Ansible + ansible.builtin.include_tasks: "teardown_{{ plat__infra_type | lower }}_authz.yml" + when: plat__infra_deployment_engine == 'ansible' + +- name: Tear down provider-specific roles and policies - Terraform + ansible.builtin.include_tasks: "teardown_{{ plat__infra_type | lower }}_{{ plat__infra_deployment_engine }}_authz.yml" + when: plat__infra_deployment_engine == 'terraform' \ No newline at end of file diff --git a/roles/platform/tasks/teardown_aws_terraform_authz.yml b/roles/platform/tasks/teardown_aws_terraform_authz.yml new file mode 100644 index 00000000..f1a799cd --- /dev/null +++ b/roles/platform/tasks/teardown_aws_terraform_authz.yml @@ -0,0 +1,84 @@ +--- + +# Copyright 2021 Cloudera, Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +- name: Remove CDP Cross Account Credential for AWS + when: plat__teardown_deletes_credential + cloudera.cloud.env_cred: + name: "{{ plat__xacccount_credential_name }}" # TODO: Make specific to AWS Teardown as credentials can be for multiple environments + state: absent + +- name: Destroy terraform infrastructure + block: + + - name: Confirm I got to setup_aws_terraform + ansible.builtin.debug: + msg: + - "I'm here doing to terraform destroy" + - "Here's the workspace: {{ plat__terraform_workspace_dir }}" + + - name: Terraform local state + # when: terraform_state == "local" # TODO: Handle state + block: + - name: Check if workspace directory exists + # TODO: Fix workspace_dir_path + # stat: path={{ infra__terraform_workspace_dir }}/workspace_dir_path/plat + stat: path={{ plat__terraform_tmp_dir }}/workspace/plat + register: workdir + + - name: Ensure the workspace directory exists + copy: + src: "{{ plat__terraform_tmp_dir }}/plat/" + # TODO: Fix workspace_dir_path + # dest: "{{ plat__terraform_workspace_dir }}/{{ workspace_dir_path }}/plat" + dest: "{{ plat__terraform_workspace_dir }}/workspace/plat" + # when: not workdir.stat.exists # TODO: This won't override if any changes to .tf are made. Good or Bad? + + - name: Prompt added by jenright + pause: + prompt: "Ready to do Terraform destroy on role files in {{ plat__terraform_workspace_dir }}/workspace/plat" + + - name: Destroy terraform authz resources + community.general.terraform: + # TODO: Fix workspace_dir_path + # project_path: "{{ plat__terraform_workspace_dir }}/{{ workspace_dir_path }}/plat" + project_path: "{{ plat__terraform_workspace_dir }}/workspace/plat" + state: "absent" + force_init: yes + register: tf_result + retries: 3 + delay: 10 + until: tf_result is succeeded + + - name: Prompt added by jenright + pause: + prompt: "Terraform destroy on role files complete. Check AWS Console." + + +# TODO: Figure out how to handle below conditional with Terraform +# - name: Tear down AWS Cross Acount +# when: plat__teardown_deletes_xaccount +# block: +# - name: Remove AWS Cross Account Role +# community.aws.iam_role: +# name: "{{ plat__aws_xaccount_role_name }}" +# region: "{{ plat__region }}" +# state: absent + +# - name: Remove AWS Cross Account Policy +# community.aws.iam_managed_policy: +# region: "{{ plat__region }}" +# policy_name: "{{ plat__aws_xaccount_policy_name }}" +# state: absent \ No newline at end of file From 39c3ca4a8e2b854586eb0f7dbafce7e9731fc618 Mon Sep 17 00:00:00 2001 From: Jim Enright Date: Fri, 1 Oct 2021 09:54:31 +0100 Subject: [PATCH 08/33] Cleanup of Terraform tasks and variables Signed-off-by: Jim Enright --- roles/infrastructure/defaults/main.yml | 2 +- .../tasks/initialize_aws_terraform.yml | 17 +++++----- .../initialize_teardown_aws_terraform.yml | 17 +++++----- .../infrastructure/tasks/setup_terraform.yml | 9 +++++- .../tasks/teardown_terraform.yml | 9 +++++- roles/platform/defaults/main.yml | 2 +- .../tasks/initialize_aws_terraform.yml | 11 ++++--- .../initialize_teardown_aws_terraform.yml | 22 ++++++++----- .../tasks/setup_aws_terraform_authz.yml | 32 +++++++++++++------ .../tasks/teardown_aws_terraform_authz.yml | 10 ++++-- .../aws/plat_aws_authz_policies.tf.j2 | 10 +++--- 11 files changed, 92 insertions(+), 49 deletions(-) diff --git a/roles/infrastructure/defaults/main.yml b/roles/infrastructure/defaults/main.yml index 34d194db..92075840 100644 --- a/roles/infrastructure/defaults/main.yml +++ b/roles/infrastructure/defaults/main.yml @@ -30,7 +30,7 @@ infra__vpc_public_subnets_suffix: "{{ common__vpc_public_subnets_suffix }}" # Deployment type infra__deployment_engine: "{{ common__infra_deployment_engine }}" # Location of output from template module which creates Terraform -infra__terraform_tmp_dir: "{{ common__terraform_tmp_dir | default('./jenright_tmp_terraform_code') }}" +infra__terraform_template_dir: "{{ common__terraform_template_dir | default('./terraform_processed_template_code') }}" infra__terraform_workspace_dir: "{{ common__terraform_workspace_dir | default( playbook_dir + '/.namespaces') }}" # Infra diff --git a/roles/infrastructure/tasks/initialize_aws_terraform.yml b/roles/infrastructure/tasks/initialize_aws_terraform.yml index e4d9c1d8..a7847a12 100644 --- a/roles/infrastructure/tasks/initialize_aws_terraform.yml +++ b/roles/infrastructure/tasks/initialize_aws_terraform.yml @@ -13,24 +13,24 @@ # limitations under the License. - name: Create terraform template .tf files - when: infra__terraform_tmp_dir is defined # TODO: Is this needed? + when: infra__terraform_template_dir is defined # TODO: Is this needed? block: - name: Create terraform template dir file: - path: "{{ infra__terraform_tmp_dir }}/infra" + path: "{{ infra__terraform_template_dir }}/infra" state: directory # Apply template for Terraform provider - name: Generate Terraform Provider template: src: 'template/{{ infra__type }}/provider.tf.j2' - dest: "{{ infra__terraform_tmp_dir }}/infra/provider.tf" + dest: "{{ infra__terraform_template_dir }}/infra/provider.tf" # Apply template for Terraform variables - name: Generate Terraform Variables template: src: 'template/{{ infra__type }}/terraform_variables.tf.j2' - dest: "{{ infra__terraform_tmp_dir }}/infra/variables.tf" + dest: "{{ infra__terraform_template_dir }}/infra/variables.tf" no_log: false # Apply template for Terraform infra.... @@ -38,23 +38,24 @@ - name: Generate Terraform infra file for network resources template: src: 'template/{{ infra__type }}/infra_{{ infra__type }}_network.tf.j2' - dest: "{{ infra__terraform_tmp_dir }}/infra/infra_network.tf" + dest: "{{ infra__terraform_template_dir }}/infra/infra_network.tf" no_log: false # ...storage resources - name: Generating Terraform infra file for storage resources template: src: 'template/{{ infra__type }}/infra_{{ infra__type }}_storage.tf.j2' - dest: "{{ infra__terraform_tmp_dir }}/infra/infra_storage.tf" + dest: "{{ infra__terraform_template_dir }}/infra/infra_storage.tf" no_log: false # ...compute resources - name: Generating Terraform infra file for compute resources template: src: 'template/{{ infra__type }}/infra_{{ infra__type }}_compute.tf.j2' - dest: "{{ infra__terraform_tmp_dir }}/infra/infra_compute.tf" + dest: "{{ infra__terraform_template_dir }}/infra/infra_compute.tf" no_log: false - name: Prompt added by jenright pause: - prompt: "Terraform infra files created in {{ infra__terraform_tmp_dir }}/infra" \ No newline at end of file + prompt: "Terraform infra files created in {{ infra__terraform_template_dir }}/infra" + when: debug_terraform | default(false) | bool \ No newline at end of file diff --git a/roles/infrastructure/tasks/initialize_teardown_aws_terraform.yml b/roles/infrastructure/tasks/initialize_teardown_aws_terraform.yml index 5126b2d1..26add72a 100644 --- a/roles/infrastructure/tasks/initialize_teardown_aws_terraform.yml +++ b/roles/infrastructure/tasks/initialize_teardown_aws_terraform.yml @@ -13,24 +13,24 @@ # limitations under the License. - name: Create terraform template .tf files - when: infra__terraform_tmp_dir is defined # TODO: Is this needed? + when: infra__terraform_template_dir is defined # TODO: Is this needed? block: - name: Create terraform template dir file: - path: "{{ infra__terraform_tmp_dir }}/infra" + path: "{{ infra__terraform_template_dir }}/infra" state: directory # Apply template for Terraform provider - name: Generate Terraform Provider template: src: 'template/{{ infra__type }}/provider.tf.j2' - dest: "{{ infra__terraform_tmp_dir }}/infra/provider.tf" + dest: "{{ infra__terraform_template_dir }}/infra/provider.tf" # Apply template for Terraform variables - name: Generate Terraform Variables template: src: 'template/{{ infra__type }}/terraform_variables.tf.j2' - dest: "{{ infra__terraform_tmp_dir }}/infra/variables.tf" + dest: "{{ infra__terraform_template_dir }}/infra/variables.tf" no_log: false # NOTE: These don't work because not all variables are defined during teardown @@ -39,23 +39,24 @@ # - name: Generate Terraform infra file for network resources # template: # src: 'template/{{ infra__type }}/infra_{{ infra__type }}_network.tf.j2' - # dest: "{{ infra__terraform_tmp_dir }}/infra/infra_network.tf" + # dest: "{{ infra__terraform_template_dir }}/infra/infra_network.tf" # no_log: false # # ...storage resources # - name: Generating Terraform infra file for storage resources # template: # src: 'template/{{ infra__type }}/infra_{{ infra__type }}_storage.tf.j2' - # dest: "{{ infra__terraform_tmp_dir }}/infra/infra_storage.tf" + # dest: "{{ infra__terraform_template_dir }}/infra/infra_storage.tf" # no_log: false # # ...compute resources # - name: Generating Terraform infra file for compute resources # template: # src: 'template/{{ infra__type }}/infra_{{ infra__type }}_compute.tf.j2' - # dest: "{{ infra__terraform_tmp_dir }}/infra/infra_compute.tf" + # dest: "{{ infra__terraform_template_dir }}/infra/infra_compute.tf" # no_log: false - name: Prompt added by jenright pause: - prompt: "Terraform infra files for Teardown created in {{ infra__terraform_tmp_dir }}/infra" \ No newline at end of file + prompt: "Terraform infra files for Teardown created in {{ infra__terraform_template_dir }}/infra" + when: debug_terraform | default(false) | bool \ No newline at end of file diff --git a/roles/infrastructure/tasks/setup_terraform.yml b/roles/infrastructure/tasks/setup_terraform.yml index bf0076e4..7ff27427 100644 --- a/roles/infrastructure/tasks/setup_terraform.yml +++ b/roles/infrastructure/tasks/setup_terraform.yml @@ -34,7 +34,7 @@ - name: Ensure the workspace directory exists copy: - src: "{{ infra__terraform_tmp_dir }}/infra/" + src: "{{ infra__terraform_template_dir }}/infra/" # TODO: Fix workspace_dir_path # dest: "{{ infra__terraform_workspace_dir }}/{{ workspace_dir_path }}" dest: "{{ infra__terraform_workspace_dir }}/workspace/infra" @@ -43,6 +43,7 @@ - name: Prompt added by jenright pause: prompt: "Ready to do Terraform apply on infra files in {{ infra__terraform_workspace_dir }}/workspace/infra" + when: debug_terraform | default(false) | bool - name: Applying terraform community.general.terraform: @@ -59,3 +60,9 @@ - name: Prompt added by jenright pause: prompt: "Terraform apply on infra files complete. Check AWS Console." + when: debug_terraform | default(false) | bool + + - name: Remove the terraform template directory + file: + path: "{{ infra__terraform_template_dir }}/infra" + state: absent \ No newline at end of file diff --git a/roles/infrastructure/tasks/teardown_terraform.yml b/roles/infrastructure/tasks/teardown_terraform.yml index c5e42adb..69d301e2 100644 --- a/roles/infrastructure/tasks/teardown_terraform.yml +++ b/roles/infrastructure/tasks/teardown_terraform.yml @@ -34,7 +34,7 @@ - name: Ensure the workspace directory exists copy: - src: "{{ infra__terraform_tmp_dir }}/infra/" + src: "{{ infra__terraform_template_dir }}/infra/" # TODO: Fix workspace_dir_path # dest: "{{ infra__terraform_workspace_dir }}/{{ workspace_dir_path }}" dest: "{{ infra__terraform_workspace_dir }}/workspace/infra" @@ -43,6 +43,7 @@ - name: Prompt added by jenright pause: prompt: "Ready to do Terraform destroy on infra files in {{ infra__terraform_workspace_dir }}/workspace/infra" + when: debug_terraform | default(false) | bool - name: Destroy terraform infra resources community.general.terraform: @@ -59,3 +60,9 @@ - name: Prompt added by jenright pause: prompt: "Terraform destroy on infra files complete. Check AWS Console." + when: debug_terraform | default(false) | bool + + - name: Remove the terraform template directory + file: + path: "{{ infra__terraform_template_dir }}/infra" + state: absent \ No newline at end of file diff --git a/roles/platform/defaults/main.yml b/roles/platform/defaults/main.yml index 1b81a70e..479da09f 100644 --- a/roles/platform/defaults/main.yml +++ b/roles/platform/defaults/main.yml @@ -23,7 +23,7 @@ # Deployment type plat__infra_deployment_engine: "{{ common__infra_deployment_engine }}" # Location of output from template module which creates Terraform -plat__terraform_tmp_dir: "{{ common__terraform_tmp_dir | default('./jenright_tmp_terraform_code') }}" +plat__terraform_template_dir: "{{ common__terraform_template_dir | default('./terraform_processed_template_code') }}" plat__terraform_workspace_dir: "{{ common__terraform_workspace_dir | default( playbook_dir + '/.namespaces') }}" plat__infra_type: "{{ common__infra_type }}" diff --git a/roles/platform/tasks/initialize_aws_terraform.yml b/roles/platform/tasks/initialize_aws_terraform.yml index 5e01c1be..d77c065d 100644 --- a/roles/platform/tasks/initialize_aws_terraform.yml +++ b/roles/platform/tasks/initialize_aws_terraform.yml @@ -15,26 +15,27 @@ # limitations under the License. - name: Create terraform template .tf files - when: plat__terraform_tmp_dir is defined # TODO: Is this needed? + when: plat__terraform_template_dir is defined # TODO: Is this needed? block: - name: Create terraform template dir file: - path: "{{ plat__terraform_tmp_dir }}/plat" + path: "{{ plat__terraform_template_dir }}/plat" state: directory # Apply template for Terraform provider - name: Generate Terraform Provider template: src: 'template/{{ plat__infra_type }}/provider.tf.j2' - dest: "{{ plat__terraform_tmp_dir }}/plat/provider.tf" + dest: "{{ plat__terraform_template_dir }}/plat/provider.tf" # Apply template for Terraform variables - name: Generate Terraform Variables template: src: 'template/{{ plat__infra_type }}/terraform_variables.tf.j2' - dest: "{{ plat__terraform_tmp_dir }}/plat/variables.tf" + dest: "{{ plat__terraform_template_dir }}/plat/variables.tf" no_log: false - name: Prompt added by jenright pause: - prompt: "PART 1 - Terraform role & policy files created in {{ plat__terraform_tmp_dir }}/plat" + prompt: "PART 1 - Terraform role & policy files created in {{ plat__terraform_template_dir }}/plat" + when: debug_terraform | default(false) | bool diff --git a/roles/platform/tasks/initialize_teardown_aws_terraform.yml b/roles/platform/tasks/initialize_teardown_aws_terraform.yml index 1f3f73fa..3a988d32 100644 --- a/roles/platform/tasks/initialize_teardown_aws_terraform.yml +++ b/roles/platform/tasks/initialize_teardown_aws_terraform.yml @@ -13,24 +13,24 @@ # limitations under the License. - name: Create terraform template .tf files - when: plat__terraform_tmp_dir is defined # TODO: Is this needed? + when: plat__terraform_template_dir is defined # TODO: Is this needed? block: - name: Create terraform template dir file: - path: "{{ plat__terraform_tmp_dir }}/plat" + path: "{{ plat__terraform_template_dir }}/plat" state: directory # Apply template for Terraform provider - name: Generate Terraform Provider template: src: 'template/{{ plat__infra_type }}/provider.tf.j2' - dest: "{{ plat__terraform_tmp_dir }}/plat/provider.tf" + dest: "{{ plat__terraform_template_dir }}/plat/provider.tf" # Apply template for Terraform variables - name: Generate Terraform Variables template: src: 'template/{{ plat__infra_type }}/terraform_variables.tf.j2' - dest: "{{ plat__terraform_tmp_dir }}/plat/variables.tf" + dest: "{{ plat__terraform_template_dir }}/plat/variables.tf" no_log: false - name: Create a temporary directory for policy documents @@ -59,7 +59,12 @@ - name: Copy AWS policy documents to Terraform workspace_dir_path copy: src: "{{ __aws_policy_tmpdir.path }}/" - dest: "{{ plat__terraform_tmp_dir }}/plat/policy_docs/" + dest: "{{ plat__terraform_template_dir }}/plat/policy_docs/" + +- name: Remove temporary directory for policy documents + ansible.builtin.file: + path: "{{ __aws_policy_tmpdir.path }}" + state: absent # NOTE: These don't work because not all variables are defined during teardown # # Apply template for Terraform auth resources.... @@ -67,16 +72,17 @@ # - name: Generate Terraform authz file for policies # template: # src: 'template/{{ plat__infra_type }}/plat_{{ plat__infra_type }}_authz_policies.tf.j2' -# dest: "{{ plat__terraform_tmp_dir }}/plat/plat_authz_policies.tf" +# dest: "{{ plat__terraform_template_dir }}/plat/plat_authz_policies.tf" # no_log: false # # ...roles # - name: Generate Terraform authz file for roles # template: # src: 'template/{{ plat__infra_type }}/plat_{{ plat__infra_type }}_authz_roles.tf.j2' -# dest: "{{ plat__terraform_tmp_dir }}/plat/plat_authz_roles.tf" +# dest: "{{ plat__terraform_template_dir }}/plat/plat_authz_roles.tf" # no_log: false - name: Prompt added by jenright pause: - prompt: "Terraform role & policy files for Teardown created in {{ plat__terraform_tmp_dir }}/plat" + prompt: "Terraform role & policy files for Teardown created in {{ plat__terraform_template_dir }}/plat" + when: debug_terraform | default(false) | bool diff --git a/roles/platform/tasks/setup_aws_terraform_authz.yml b/roles/platform/tasks/setup_aws_terraform_authz.yml index 410d9f7f..87038a32 100644 --- a/roles/platform/tasks/setup_aws_terraform_authz.yml +++ b/roles/platform/tasks/setup_aws_terraform_authz.yml @@ -50,24 +50,32 @@ # ***************** TERRAFORM TEMPLATE PART 2 *********************** # Needed here because the policy documents are only available after above tasks # QUESTION: HOW CAN WE REARRANGE THIS? + +# Copy the AWS policy documents +- name: Copy AWS policy documents to Terraform workspace_dir_path + copy: + src: "{{ __aws_policy_tmpdir.path }}/" + dest: "{{ plat__terraform_template_dir }}/plat/policy_docs/" + # Apply template for Terraform auth resources.... # ...policies - name: Generate Terraform authz file for policies template: src: 'template/{{ plat__infra_type }}/plat_{{ plat__infra_type }}_authz_policies.tf.j2' - dest: "{{ plat__terraform_tmp_dir }}/plat/plat_authz_policies.tf" + dest: "{{ plat__terraform_template_dir }}/plat/plat_authz_policies.tf" no_log: false # ...roles - name: Generate Terraform authz file for roles template: src: 'template/{{ plat__infra_type }}/plat_{{ plat__infra_type }}_authz_roles.tf.j2' - dest: "{{ plat__terraform_tmp_dir }}/plat/plat_authz_roles.tf" + dest: "{{ plat__terraform_template_dir }}/plat/plat_authz_roles.tf" no_log: false - name: Prompt added by jenright pause: - prompt: "PART 2 - Terraform role & policy files created in {{ plat__terraform_tmp_dir }}/plat" + prompt: "PART 2 - Terraform role & policy files created in {{ plat__terraform_template_dir }}/plat" + when: debug_terraform | default(false) | bool # ***************** END TERRAFORM TEMPLATE PART 2 *********************** # ***************** TERRAFORM APPLY *********************** @@ -82,7 +90,7 @@ - name: Ensure the workspace directory exists copy: - src: "{{ plat__terraform_tmp_dir }}/plat/" + src: "{{ plat__terraform_template_dir }}/plat/" # TODO: Fix workspace_dir_path # dest: "{{ plat__terraform_workspace_dir }}/{{ workspace_dir_path }}/plat" dest: "{{ plat__terraform_workspace_dir }}/workspace/plat" @@ -91,6 +99,7 @@ - name: Prompt added by jenright pause: prompt: "Ready to do Terraform apply on role files in {{ plat__terraform_workspace_dir }}/workspace/plat" + when: debug_terraform | default(false) | bool - name: Applying terraform community.general.terraform: @@ -107,6 +116,12 @@ - name: Prompt added by jenright pause: prompt: "Terraform apply on role files complete. Check AWS Console." + when: debug_terraform | default(false) | bool + + - name: Remove the terraform template directory + file: + path: "{{ plat__terraform_template_dir }}/plat/" + state: absent # ***************** END TERRAFORM APPLY *********************** @@ -132,8 +147,7 @@ role: "{{ __aws_xaccount_role_info.iam_roles[0].arn }}" state: present -# TODO: Need to figure out how to handle this with Terraform -# - name: Remove temporary directory for policy documents -# ansible.builtin.file: -# path: "{{ __aws_policy_tmpdir.path }}" -# state: absent +- name: Remove temporary directory for policy documents + ansible.builtin.file: + path: "{{ __aws_policy_tmpdir.path }}" + state: absent diff --git a/roles/platform/tasks/teardown_aws_terraform_authz.yml b/roles/platform/tasks/teardown_aws_terraform_authz.yml index f1a799cd..27b55173 100644 --- a/roles/platform/tasks/teardown_aws_terraform_authz.yml +++ b/roles/platform/tasks/teardown_aws_terraform_authz.yml @@ -35,12 +35,12 @@ - name: Check if workspace directory exists # TODO: Fix workspace_dir_path # stat: path={{ infra__terraform_workspace_dir }}/workspace_dir_path/plat - stat: path={{ plat__terraform_tmp_dir }}/workspace/plat + stat: path={{ plat__terraform_template_dir }}/workspace/plat register: workdir - name: Ensure the workspace directory exists copy: - src: "{{ plat__terraform_tmp_dir }}/plat/" + src: "{{ plat__terraform_template_dir }}/plat/" # TODO: Fix workspace_dir_path # dest: "{{ plat__terraform_workspace_dir }}/{{ workspace_dir_path }}/plat" dest: "{{ plat__terraform_workspace_dir }}/workspace/plat" @@ -49,6 +49,7 @@ - name: Prompt added by jenright pause: prompt: "Ready to do Terraform destroy on role files in {{ plat__terraform_workspace_dir }}/workspace/plat" + when: debug_terraform | default(false) | bool - name: Destroy terraform authz resources community.general.terraform: @@ -65,7 +66,12 @@ - name: Prompt added by jenright pause: prompt: "Terraform destroy on role files complete. Check AWS Console." + when: debug_terraform | default(false) | bool + - name: Remove the terraform template directory + file: + path: "{{ plat__terraform_template_dir }}/plat/" + state: absent # TODO: Figure out how to handle below conditional with Terraform # - name: Tear down AWS Cross Acount diff --git a/roles/platform/template/aws/plat_aws_authz_policies.tf.j2 b/roles/platform/template/aws/plat_aws_authz_policies.tf.j2 index f4a178c1..6df307fd 100644 --- a/roles/platform/template/aws/plat_aws_authz_policies.tf.j2 +++ b/roles/platform/template/aws/plat_aws_authz_policies.tf.j2 @@ -41,7 +41,7 @@ resource "aws_iam_policy" "{{ plat__aws_log_location_policy_name }}" { tags = merge(var.env_tags,{Name = "{{ plat__aws_log_location_policy_name }}"}) - policy = file("{{ __aws_policy_documents | json_query("results[?__policy_url_item.key==`log`].dest | [0]") }}") + policy = file("{{ "./policy_docs/" ~ (__aws_policy_documents | json_query("results[?__policy_url_item.key==`log`].dest | [0]") | basename) }}") } # ------- CDP Data Access Policies - ranger_audit_s3 ------- @@ -51,7 +51,7 @@ resource "aws_iam_policy" "{{ plat__aws_ranger_audit_s3_policy_name }}" { tags = merge(var.env_tags,{Name = "{{ plat__aws_ranger_audit_s3_policy_name }}"}) - policy = file("{{ __aws_policy_documents | json_query("results[?__policy_url_item.key==`ranger_audit_s3`].dest | [0]") }}") + policy = file("{{ "./policy_docs/" ~ (__aws_policy_documents | json_query("results[?__policy_url_item.key==`ranger_audit_s3`].dest | [0]") | basename) }}") } # ------- CDP Data Access Policies - datalake_admin_s3 ------- @@ -61,7 +61,7 @@ resource "aws_iam_policy" "{{ plat__aws_datalake_admin_s3_policy_name }}" { tags = merge(var.env_tags,{Name = "{{ plat__aws_datalake_admin_s3_policy_name }}"}) - policy = file("{{ __aws_policy_documents | json_query("results[?__policy_url_item.key==`datalake_admin_s3`].dest | [0]") }}") + policy = file("{{ "./policy_docs/" ~ (__aws_policy_documents | json_query("results[?__policy_url_item.key==`datalake_admin_s3`].dest | [0]") | basename) }}") } # ------- CDP Data Access Policies - datalake_admin_s3 ------- @@ -71,7 +71,7 @@ resource "aws_iam_policy" "{{ plat__aws_bucket_access_policy_name }}" { tags = merge(var.env_tags,{Name = "{{ plat__aws_bucket_access_policy_name }}"}) - policy = file("{{ __aws_policy_documents | json_query("results[?__policy_url_item.key==`bucket_access`].dest | [0]") }}") + policy = file("{{ "./policy_docs/" ~ (__aws_policy_documents | json_query("results[?__policy_url_item.key==`bucket_access`].dest | [0]") | basename) }}") } # ------- CDP Data Access Policies - dynamodb ------- @@ -81,5 +81,5 @@ resource "aws_iam_policy" "{{ plat__aws_dynamodb_policy_name }}" { tags = merge(var.env_tags,{Name = "{{ plat__aws_dynamodb_policy_name }}"}) - policy = file("{{ __aws_policy_documents | json_query("results[?__policy_url_item.key==`dynamodb`].dest | [0]") }}") + policy = file("{{ "./policy_docs/" ~ (__aws_policy_documents | json_query("results[?__policy_url_item.key==`dynamodb`].dest | [0]") | basename) }}") } From 3eb0cb72011ed2d41becbd054380bcb09836aa27 Mon Sep 17 00:00:00 2001 From: Jim Enright Date: Fri, 1 Oct 2021 09:54:31 +0100 Subject: [PATCH 09/33] Push Terraform template and workspace variables to common Signed-off-by: Jim Enright --- roles/common/defaults/main.yml | 3 +++ roles/infrastructure/defaults/main.yml | 4 ++-- roles/platform/defaults/main.yml | 4 ++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/roles/common/defaults/main.yml b/roles/common/defaults/main.yml index af0a0fff..debe41c2 100644 --- a/roles/common/defaults/main.yml +++ b/roles/common/defaults/main.yml @@ -67,6 +67,9 @@ common__public_key_text: "{{ globals.ssh.public_key_text | defa common__region: "{{ globals.region | default(common__region_default[common__infra_type]) }}" common__storage_name: "{{ infra.storage.name | default([common__namespace, common__unique_storage_name_suffix[::2] | replace('-','')] | join('-')) }}" +common__terraform_template_dir: "{{ globals.terraform_template_dir | default( playbook_dir + './terraform_processed_template_code') }}" +common__terraform_workspace_dir: "{{ globals.terraform_workspace_dir | default( playbook_dir + '/.namespaces') }}" + common__vpc_name: "{{ infra.vpc.name | default([common__namespace, common__vpc_name_suffix] | join('-')) }}" 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']) }}" 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']) }}" diff --git a/roles/infrastructure/defaults/main.yml b/roles/infrastructure/defaults/main.yml index 92075840..53332413 100644 --- a/roles/infrastructure/defaults/main.yml +++ b/roles/infrastructure/defaults/main.yml @@ -30,8 +30,8 @@ infra__vpc_public_subnets_suffix: "{{ common__vpc_public_subnets_suffix }}" # Deployment type infra__deployment_engine: "{{ common__infra_deployment_engine }}" # Location of output from template module which creates Terraform -infra__terraform_template_dir: "{{ common__terraform_template_dir | default('./terraform_processed_template_code') }}" -infra__terraform_workspace_dir: "{{ common__terraform_workspace_dir | default( playbook_dir + '/.namespaces') }}" +infra__terraform_template_dir: "{{ common__terraform_template_dir }}" +infra__terraform_workspace_dir: "{{ common__terraform_workspace_dir }}" # Infra infra__type: "{{ common__infra_type }}" diff --git a/roles/platform/defaults/main.yml b/roles/platform/defaults/main.yml index 479da09f..816d5c19 100644 --- a/roles/platform/defaults/main.yml +++ b/roles/platform/defaults/main.yml @@ -23,8 +23,8 @@ # Deployment type plat__infra_deployment_engine: "{{ common__infra_deployment_engine }}" # Location of output from template module which creates Terraform -plat__terraform_template_dir: "{{ common__terraform_template_dir | default('./terraform_processed_template_code') }}" -plat__terraform_workspace_dir: "{{ common__terraform_workspace_dir | default( playbook_dir + '/.namespaces') }}" +plat__terraform_template_dir: "{{ common__terraform_template_dir }}" +plat__terraform_workspace_dir: "{{ common__terraform_workspace_dir }}" plat__infra_type: "{{ common__infra_type }}" plat__region: "{{ common__region }}" From 8d6246b6e2ee7f454f20b8ba2633eb480315b8f8 Mon Sep 17 00:00:00 2001 From: Jim Enright Date: Fri, 1 Oct 2021 09:54:32 +0100 Subject: [PATCH 10/33] Add S3 remote state for Terraform and code cleanup Signed-off-by: Jim Enright --- roles/common/defaults/main.yml | 4 + roles/infrastructure/defaults/main.yml | 10 +- .../tasks/initialize_aws_terraform.yml | 6 ++ .../initialize_teardown_aws_terraform.yml | 7 ++ .../infrastructure/tasks/setup_terraform.yml | 99 +++++++++---------- .../tasks/teardown_terraform.yml | 86 ++++++++-------- .../template/aws/backend_state.tf.j2 | 16 +++ roles/platform/defaults/main.yml | 4 + .../tasks/initialize_aws_terraform.yml | 6 ++ .../initialize_teardown_aws_terraform.yml | 17 +++- .../tasks/setup_aws_terraform_authz.yml | 96 +++++++++--------- .../tasks/teardown_aws_terraform_authz.yml | 86 ++++++++-------- .../platform/template/aws/backend_state.tf.j2 | 17 ++++ 13 files changed, 254 insertions(+), 200 deletions(-) create mode 100644 roles/infrastructure/template/aws/backend_state.tf.j2 create mode 100644 roles/platform/template/aws/backend_state.tf.j2 diff --git a/roles/common/defaults/main.yml b/roles/common/defaults/main.yml index debe41c2..8b567a4d 100644 --- a/roles/common/defaults/main.yml +++ b/roles/common/defaults/main.yml @@ -70,6 +70,10 @@ common__storage_name: "{{ infra.storage.name | default([comm common__terraform_template_dir: "{{ globals.terraform_template_dir | default( playbook_dir + './terraform_processed_template_code') }}" common__terraform_workspace_dir: "{{ globals.terraform_workspace_dir | default( playbook_dir + '/.namespaces') }}" +common__terraform_state_storage: "{{ globals.terraform_state_storage | default('local') }}" +common__terraform_remote_state_bucket: "{{ globals.terraform_remote_state_bucket | default('') }}" +common__terraform_remote_state_lock_table: "{{ globals.terraform_remote_state_lock_table | default('') }}" + common__vpc_name: "{{ infra.vpc.name | default([common__namespace, common__vpc_name_suffix] | join('-')) }}" 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']) }}" 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']) }}" diff --git a/roles/infrastructure/defaults/main.yml b/roles/infrastructure/defaults/main.yml index 53332413..03480fbc 100644 --- a/roles/infrastructure/defaults/main.yml +++ b/roles/infrastructure/defaults/main.yml @@ -28,10 +28,14 @@ infra__vpc_public_subnets_suffix: "{{ common__vpc_public_subnets_suffix }}" # NOTE: Added by jenright for Terraform # Deployment type -infra__deployment_engine: "{{ common__infra_deployment_engine }}" +infra__deployment_engine: "{{ common__infra_deployment_engine }}" # Location of output from template module which creates Terraform -infra__terraform_template_dir: "{{ common__terraform_template_dir }}" -infra__terraform_workspace_dir: "{{ common__terraform_workspace_dir }}" +infra__terraform_template_dir: "{{ common__terraform_template_dir }}" +infra__terraform_workspace_dir: "{{ common__terraform_workspace_dir }}" + +infra__terraform_state_storage: "{{ common__terraform_state_storage }}" +infra__terraform_remote_state_bucket: "{{ common__terraform_remote_state_bucket }}" +infra__terraform_remote_state_lock_table: "{{ common__terraform_remote_state_lock_table }}" # Infra infra__type: "{{ common__infra_type }}" diff --git a/roles/infrastructure/tasks/initialize_aws_terraform.yml b/roles/infrastructure/tasks/initialize_aws_terraform.yml index a7847a12..06af8f3a 100644 --- a/roles/infrastructure/tasks/initialize_aws_terraform.yml +++ b/roles/infrastructure/tasks/initialize_aws_terraform.yml @@ -26,6 +26,12 @@ src: 'template/{{ infra__type }}/provider.tf.j2' dest: "{{ infra__terraform_template_dir }}/infra/provider.tf" + # Apply template for Terraform backend state + - name: Generate Terraform Backend State + template: + src: 'template/{{ infra__type }}/backend_state.tf.j2' + dest: "{{ infra__terraform_template_dir }}/infra/backend_state.tf" + # Apply template for Terraform variables - name: Generate Terraform Variables template: diff --git a/roles/infrastructure/tasks/initialize_teardown_aws_terraform.yml b/roles/infrastructure/tasks/initialize_teardown_aws_terraform.yml index 26add72a..34d91be2 100644 --- a/roles/infrastructure/tasks/initialize_teardown_aws_terraform.yml +++ b/roles/infrastructure/tasks/initialize_teardown_aws_terraform.yml @@ -26,6 +26,12 @@ src: 'template/{{ infra__type }}/provider.tf.j2' dest: "{{ infra__terraform_template_dir }}/infra/provider.tf" + # Apply template for Terraform backend state + - name: Generate Terraform Backend State + template: + src: 'template/{{ infra__type }}/backend_state.tf.j2' + dest: "{{ infra__terraform_template_dir }}/infra/backend_state.tf" + # Apply template for Terraform variables - name: Generate Terraform Variables template: @@ -34,6 +40,7 @@ no_log: false # NOTE: These don't work because not all variables are defined during teardown + # ......ALSO they are not needed because we are working off the state file # # Apply template for Terraform infra.... # # ...network resources # - name: Generate Terraform infra file for network resources diff --git a/roles/infrastructure/tasks/setup_terraform.yml b/roles/infrastructure/tasks/setup_terraform.yml index 7ff27427..da8a53de 100644 --- a/roles/infrastructure/tasks/setup_terraform.yml +++ b/roles/infrastructure/tasks/setup_terraform.yml @@ -14,55 +14,50 @@ # See the License for the specific language governing permissions and # limitations under the License. -- name: Deploy terraform infrastructure - block: - - - name: Confirm I got to setup_aws_terraform - ansible.builtin.debug: - msg: - - "I'm here doing to terraform apply" - - "Here's the workspace: {{ infra__terraform_workspace_dir }}" - - - name: Terraform local state - # when: terraform_state == "local" # TODO: Handle state - block: - - name: Check if workspace directory exists - # TODO: Fix workspace_dir_path - # stat: path={{ infra__terraform_workspace_dir }}/workspace_dir_path - stat: path={{ infra__terraform_workspace_dir }}/workspace/infra - register: workdir - - - name: Ensure the workspace directory exists - copy: - src: "{{ infra__terraform_template_dir }}/infra/" - # TODO: Fix workspace_dir_path - # dest: "{{ infra__terraform_workspace_dir }}/{{ workspace_dir_path }}" - dest: "{{ infra__terraform_workspace_dir }}/workspace/infra" - # when: not workdir.stat.exists # TODO: This won't override if any changes to .tf are made. Good or Bad? - - - name: Prompt added by jenright - pause: - prompt: "Ready to do Terraform apply on infra files in {{ infra__terraform_workspace_dir }}/workspace/infra" - when: debug_terraform | default(false) | bool - - - name: Applying terraform - community.general.terraform: - # TODO: Fix workspace_dir_path - # project_path: "{{ infra__terraform_workspace_dir }}/{{ workspace_dir_path }}" - project_path: "{{ infra__terraform_workspace_dir }}/workspace/infra" - state: "present" - force_init: yes - register: tf_result - retries: 3 - delay: 10 - until: tf_result is succeeded - - - name: Prompt added by jenright - pause: - prompt: "Terraform apply on infra files complete. Check AWS Console." - when: debug_terraform | default(false) | bool - - - name: Remove the terraform template directory - file: - path: "{{ infra__terraform_template_dir }}/infra" - state: absent \ No newline at end of file +- name: Confirm I got to setup_aws_terraform + ansible.builtin.debug: + msg: + - "I'm here doing to terraform apply" + - "Here's the workspace: {{ infra__terraform_workspace_dir }}" + +- name: Check if Terraform workspace directory exists + ansible.builtin.stat: + path: "{{ infra__terraform_workspace_dir }}/workspace/infra" + register: workdir + +- name: Ensure the Terraform workspace directory exists + ansible.builtin.copy: + src: "{{ infra__terraform_template_dir }}/infra/" + dest: "{{ infra__terraform_workspace_dir }}/workspace/infra" + # when: not workdir.stat.exists # TODO: This won't override if any changes to .tf are made. Good or Bad? + +- name: Prompt added by jenright + ansible.builtin.pause: + prompt: "Ready to do Terraform apply on infra files in {{ infra__terraform_workspace_dir }}/workspace/infra" + when: debug_terraform | default(false) | bool + +- name: Applying Terraform + community.general.terraform: + project_path: "{{ infra__terraform_workspace_dir }}/workspace/infra" + state: "present" + force_init: yes + register: tf_result + retries: 3 + delay: 10 + until: tf_result is succeeded + +- name: Prompt added by jenright + pause: + prompt: "Terraform apply on infra files complete. Check AWS Console." + when: debug_terraform | default(false) | bool + +- name: Remove the Terraform template directory + ansible.builtin.file: + path: "{{ infra__terraform_template_dir }}/infra" + state: absent + +- name: Remove the Terraform workspace directory when using remote state + ansible.builtin.file: + path: "{{ infra__terraform_workspace_dir }}/workspace/infra" + state: absent + when: infra__terraform_state_storage in ['remote_s3'] \ No newline at end of file diff --git a/roles/infrastructure/tasks/teardown_terraform.yml b/roles/infrastructure/tasks/teardown_terraform.yml index 69d301e2..0b1a6ba5 100644 --- a/roles/infrastructure/tasks/teardown_terraform.yml +++ b/roles/infrastructure/tasks/teardown_terraform.yml @@ -14,55 +14,51 @@ # See the License for the specific language governing permissions and # limitations under the License. -- name: Destroy terraform infrastructure - block: +- name: Confirm I got to teardown_terraform + ansible.builtin.debug: + msg: + - "I'm here doing to terraform destroy" + - "Here's the workspace: {{ infra__terraform_workspace_dir }}" - - name: Confirm I got to teardown_terraform - ansible.builtin.debug: - msg: - - "I'm here doing to terraform destroy" - - "Here's the workspace: {{ infra__terraform_workspace_dir }}" +- name: Check if Terraform workspace directory exists + ansible.builtin.stat: + path: "{{ infra__terraform_workspace_dir }}/workspace/infra" + register: workdir - - name: Terraform local state - # when: terraform_state == "local" # TODO: Handle state - block: - - name: Check if workspace directory exists - # TODO: Fix workspace_dir_path - # stat: path={{ infra__terraform_workspace_dir }}/workspace_dir_path - stat: path={{ infra__terraform_workspace_dir }}/workspace/infra - register: workdir +- name: Ensure the Terraform workspace directory exists + ansible.builtin.copy: + src: "{{ infra__terraform_template_dir }}/infra/" + dest: "{{ infra__terraform_workspace_dir }}/workspace/infra" + # when: not workdir.stat.exists # TODO: This won't override if any changes to .tf are made. Good or Bad? - - name: Ensure the workspace directory exists - copy: - src: "{{ infra__terraform_template_dir }}/infra/" - # TODO: Fix workspace_dir_path - # dest: "{{ infra__terraform_workspace_dir }}/{{ workspace_dir_path }}" - dest: "{{ infra__terraform_workspace_dir }}/workspace/infra" - # when: not workdir.stat.exists # TODO: This won't override if any changes to .tf are made. Good or Bad? +- name: Prompt added by jenright + ansible.builtin.pause: + prompt: "Ready to do Terraform destroy on infra files in {{ infra__terraform_workspace_dir }}/workspace/infra" + when: debug_terraform | default(false) | bool - - name: Prompt added by jenright - pause: - prompt: "Ready to do Terraform destroy on infra files in {{ infra__terraform_workspace_dir }}/workspace/infra" - when: debug_terraform | default(false) | bool +- name: Destroy Terraform infra resources + community.general.terraform: + # TODO: Fix workspace_dir_path + # project_path: "{{ infra__terraform_workspace_dir }}/{{ workspace_dir_path }}" + project_path: "{{ infra__terraform_workspace_dir }}/workspace/infra" + state: "absent" + force_init: yes + register: tf_result + retries: 3 + delay: 10 + until: tf_result is succeeded - - name: Destroy terraform infra resources - community.general.terraform: - # TODO: Fix workspace_dir_path - # project_path: "{{ infra__terraform_workspace_dir }}/{{ workspace_dir_path }}" - project_path: "{{ infra__terraform_workspace_dir }}/workspace/infra" - state: "absent" - force_init: yes - register: tf_result - retries: 3 - delay: 10 - until: tf_result is succeeded +- name: Prompt added by jenright + ansible.builtin.pause: + prompt: "Terraform destroy on infra files complete. Check AWS Console." + when: debug_terraform | default(false) | bool - - name: Prompt added by jenright - pause: - prompt: "Terraform destroy on infra files complete. Check AWS Console." - when: debug_terraform | default(false) | bool +- name: Remove the Terraform template directory + ansible.builtin.file: + path: "{{ infra__terraform_template_dir }}/infra" + state: absent - - name: Remove the terraform template directory - file: - path: "{{ infra__terraform_template_dir }}/infra" - state: absent \ No newline at end of file +- name: Remove the Terraform workspace directory + ansible.builtin.file: + path: "{{ infra__terraform_workspace_dir }}/workspace/infra" + state: absent \ No newline at end of file diff --git a/roles/infrastructure/template/aws/backend_state.tf.j2 b/roles/infrastructure/template/aws/backend_state.tf.j2 new file mode 100644 index 00000000..13bdb940 --- /dev/null +++ b/roles/infrastructure/template/aws/backend_state.tf.j2 @@ -0,0 +1,16 @@ +{% if infra__terraform_state_storage == "local" %} +# Terraform state is stored locally at {{ infra__terraform_workspace_dir }}/workspace/infra +{% endif %} + +{% if infra__terraform_state_storage == "remote_s3" %} +terraform { + backend "s3" { + region = "{{ infra__region }}" + bucket = "{{ infra__terraform_remote_state_bucket }}" + key = "workspace/{{infra__namespace}}/infra/terraform.tfstate" + dynamodb_table = "{{ infra__terraform_remote_state_lock_table }}" + # workspace_key_prefix = " terraform_workspace_key_prefix " + # encrypt = true + } +} +{% endif %} diff --git a/roles/platform/defaults/main.yml b/roles/platform/defaults/main.yml index 816d5c19..30188325 100644 --- a/roles/platform/defaults/main.yml +++ b/roles/platform/defaults/main.yml @@ -26,6 +26,10 @@ plat__infra_deployment_engine: "{{ common__infra_deployment_engin plat__terraform_template_dir: "{{ common__terraform_template_dir }}" plat__terraform_workspace_dir: "{{ common__terraform_workspace_dir }}" +plat__terraform_state_storage: "{{ common__terraform_state_storage }}" +plat__terraform_remote_state_bucket: "{{ common__terraform_remote_state_bucket }}" +plat__terraform_remote_state_lock_table: "{{ common__terraform_remote_state_lock_table }}" + plat__infra_type: "{{ common__infra_type }}" plat__region: "{{ common__region }}" plat__namespace: "{{ common__namespace }}" diff --git a/roles/platform/tasks/initialize_aws_terraform.yml b/roles/platform/tasks/initialize_aws_terraform.yml index d77c065d..5c28183a 100644 --- a/roles/platform/tasks/initialize_aws_terraform.yml +++ b/roles/platform/tasks/initialize_aws_terraform.yml @@ -28,6 +28,12 @@ src: 'template/{{ plat__infra_type }}/provider.tf.j2' dest: "{{ plat__terraform_template_dir }}/plat/provider.tf" + # Apply template for Terraform backend state + - name: Generate Terraform Backend State + template: + src: 'template/{{ plat__infra_type }}/backend_state.tf.j2' + dest: "{{ plat__terraform_template_dir }}/plat/backend_state.tf" + # Apply template for Terraform variables - name: Generate Terraform Variables template: diff --git a/roles/platform/tasks/initialize_teardown_aws_terraform.yml b/roles/platform/tasks/initialize_teardown_aws_terraform.yml index 3a988d32..7418bacd 100644 --- a/roles/platform/tasks/initialize_teardown_aws_terraform.yml +++ b/roles/platform/tasks/initialize_teardown_aws_terraform.yml @@ -16,19 +16,25 @@ when: plat__terraform_template_dir is defined # TODO: Is this needed? block: - name: Create terraform template dir - file: + ansible.builtin.file: path: "{{ plat__terraform_template_dir }}/plat" state: directory # Apply template for Terraform provider - name: Generate Terraform Provider - template: + ansible.builtin.template: src: 'template/{{ plat__infra_type }}/provider.tf.j2' dest: "{{ plat__terraform_template_dir }}/plat/provider.tf" + # Apply template for Terraform backend state + - name: Generate Terraform Backend State + ansible.builtin.template: + src: 'template/{{ plat__infra_type }}/backend_state.tf.j2' + dest: "{{ plat__terraform_template_dir }}/plat/backend_state.tf" + # Apply template for Terraform variables - name: Generate Terraform Variables - template: + ansible.builtin.template: src: 'template/{{ plat__infra_type }}/terraform_variables.tf.j2' dest: "{{ plat__terraform_template_dir }}/plat/variables.tf" no_log: false @@ -57,7 +63,7 @@ label: "{{ __aws_policy_document_item.__policy_url_item.key }}" - name: Copy AWS policy documents to Terraform workspace_dir_path - copy: + ansible.builtin.copy: src: "{{ __aws_policy_tmpdir.path }}/" dest: "{{ plat__terraform_template_dir }}/plat/policy_docs/" @@ -67,6 +73,7 @@ state: absent # NOTE: These don't work because not all variables are defined during teardown +# ......ALSO they are not needed because we are working off the state file # # Apply template for Terraform auth resources.... # # ...policies # - name: Generate Terraform authz file for policies @@ -83,6 +90,6 @@ # no_log: false - name: Prompt added by jenright - pause: + ansible.builtin.pause: prompt: "Terraform role & policy files for Teardown created in {{ plat__terraform_template_dir }}/plat" when: debug_terraform | default(false) | bool diff --git a/roles/platform/tasks/setup_aws_terraform_authz.yml b/roles/platform/tasks/setup_aws_terraform_authz.yml index 87038a32..9407fa00 100644 --- a/roles/platform/tasks/setup_aws_terraform_authz.yml +++ b/roles/platform/tasks/setup_aws_terraform_authz.yml @@ -42,7 +42,7 @@ label: "{{ __aws_policy_document_item.__policy_url_item.key }}" - name: Some variables for creation of IAM - debug: + ansible.builtin.debug: msg: - plat__aws_xaccount_account_policy = {{ plat__aws_xaccount_account_policy }} - plat__aws_xaccount_policy_name = {{ plat__aws_xaccount_policy_name }} @@ -52,76 +52,74 @@ # QUESTION: HOW CAN WE REARRANGE THIS? # Copy the AWS policy documents -- name: Copy AWS policy documents to Terraform workspace_dir_path - copy: +- name: Copy AWS policy documents to Terraform template directory + ansible.builtin.copy: src: "{{ __aws_policy_tmpdir.path }}/" dest: "{{ plat__terraform_template_dir }}/plat/policy_docs/" # Apply template for Terraform auth resources.... # ...policies - name: Generate Terraform authz file for policies - template: + ansible.builtin.template: src: 'template/{{ plat__infra_type }}/plat_{{ plat__infra_type }}_authz_policies.tf.j2' dest: "{{ plat__terraform_template_dir }}/plat/plat_authz_policies.tf" no_log: false # ...roles - name: Generate Terraform authz file for roles - template: + ansible.builtin.template: src: 'template/{{ plat__infra_type }}/plat_{{ plat__infra_type }}_authz_roles.tf.j2' dest: "{{ plat__terraform_template_dir }}/plat/plat_authz_roles.tf" no_log: false - name: Prompt added by jenright - pause: + ansible.builtin.pause: prompt: "PART 2 - Terraform role & policy files created in {{ plat__terraform_template_dir }}/plat" when: debug_terraform | default(false) | bool # ***************** END TERRAFORM TEMPLATE PART 2 *********************** # ***************** TERRAFORM APPLY *********************** -- name: Terraform local state - # when: terraform_state == "local" # TODO: Handle state - block: - - name: Check if workspace directory exists - # TODO: Fix workspace_dir_path - # stat: path={{ plat__terraform_workspace_dir }}/workspace_dir_path/plat - stat: path={{ plat__terraform_workspace_dir }}/workspace/plat - register: workdir - - - name: Ensure the workspace directory exists - copy: - src: "{{ plat__terraform_template_dir }}/plat/" - # TODO: Fix workspace_dir_path - # dest: "{{ plat__terraform_workspace_dir }}/{{ workspace_dir_path }}/plat" - dest: "{{ plat__terraform_workspace_dir }}/workspace/plat" - # when: not workdir.stat.exists # TODO: This won't override if any changes to .tf are made. Good or Bad? - - - name: Prompt added by jenright - pause: - prompt: "Ready to do Terraform apply on role files in {{ plat__terraform_workspace_dir }}/workspace/plat" - when: debug_terraform | default(false) | bool - - - name: Applying terraform - community.general.terraform: - # TODO: Fix workspace_dir_path - # project_path: "{{ plat__terraform_workspace_dir }}/{{ workspace_dir_path }}/plat" - project_path: "{{ plat__terraform_workspace_dir }}/workspace/plat" - state: "present" - force_init: yes - register: tf_result - retries: 3 - delay: 10 - until: tf_result is succeeded - - - name: Prompt added by jenright - pause: - prompt: "Terraform apply on role files complete. Check AWS Console." - when: debug_terraform | default(false) | bool - - - name: Remove the terraform template directory - file: - path: "{{ plat__terraform_template_dir }}/plat/" - state: absent +- name: Check if Terraform workspace directory exists + ansible.builtin.stat: + path: "{{ plat__terraform_workspace_dir }}/workspace/plat" + register: workdir + +- name: Ensure the Terraform workspace directory exists + ansible.builtin.copy: + src: "{{ plat__terraform_template_dir }}/plat/" + dest: "{{ plat__terraform_workspace_dir }}/workspace/plat" + # when: not workdir.stat.exists # TODO: This won't override if any changes to .tf are made. Good or Bad? + +- name: Prompt added by jenright + ansible.builtin.pause: + prompt: "Ready to do Terraform apply on role files in {{ plat__terraform_workspace_dir }}/workspace/plat" + when: debug_terraform | default(false) | bool + +- name: Applying Terraform + community.general.terraform: + project_path: "{{ plat__terraform_workspace_dir }}/workspace/plat" + state: "present" + force_init: yes + register: tf_result + retries: 3 + delay: 10 + until: tf_result is succeeded + +- name: Prompt added by jenright + ansible.builtin.pause: + prompt: "Terraform apply on role files complete. Check AWS Console." + when: debug_terraform | default(false) | bool + +- name: Remove the Terraform template directory + ansible.builtin.file: + path: "{{ plat__terraform_template_dir }}/plat/" + state: absent + +- name: Remove the Terraform workspace directory when using remote state + ansible.builtin.file: + path: "{{ plat__terraform_workspace_dir }}/workspace/plat" + state: absent + when: plat__terraform_state_storage in ['remote_s3'] # ***************** END TERRAFORM APPLY *********************** diff --git a/roles/platform/tasks/teardown_aws_terraform_authz.yml b/roles/platform/tasks/teardown_aws_terraform_authz.yml index 27b55173..711bde5a 100644 --- a/roles/platform/tasks/teardown_aws_terraform_authz.yml +++ b/roles/platform/tasks/teardown_aws_terraform_authz.yml @@ -20,59 +20,53 @@ name: "{{ plat__xacccount_credential_name }}" # TODO: Make specific to AWS Teardown as credentials can be for multiple environments state: absent -- name: Destroy terraform infrastructure - block: +- name: Confirm I got to setup_aws_terraform + ansible.builtin.debug: + msg: + - "I'm here doing to terraform destroy" + - "Here's the workspace: {{ plat__terraform_workspace_dir }}" - - name: Confirm I got to setup_aws_terraform - ansible.builtin.debug: - msg: - - "I'm here doing to terraform destroy" - - "Here's the workspace: {{ plat__terraform_workspace_dir }}" +- name: Check if Terraform workspace directory exists + ansible.builtin.stat: + path: "{{ plat__terraform_template_dir }}/workspace/plat" + register: workdir - - name: Terraform local state - # when: terraform_state == "local" # TODO: Handle state - block: - - name: Check if workspace directory exists - # TODO: Fix workspace_dir_path - # stat: path={{ infra__terraform_workspace_dir }}/workspace_dir_path/plat - stat: path={{ plat__terraform_template_dir }}/workspace/plat - register: workdir +- name: Ensure the Terraform workspace directory exists + ansible.builtin.copy: + src: "{{ plat__terraform_template_dir }}/plat/" + dest: "{{ plat__terraform_workspace_dir }}/workspace/plat" + # when: not workdir.stat.exists # TODO: This won't override if any changes to .tf are made. Good or Bad? - - name: Ensure the workspace directory exists - copy: - src: "{{ plat__terraform_template_dir }}/plat/" - # TODO: Fix workspace_dir_path - # dest: "{{ plat__terraform_workspace_dir }}/{{ workspace_dir_path }}/plat" - dest: "{{ plat__terraform_workspace_dir }}/workspace/plat" - # when: not workdir.stat.exists # TODO: This won't override if any changes to .tf are made. Good or Bad? +- name: Prompt added by jenright + ansible.builtin.pause: + prompt: "Ready to do Terraform destroy on role files in {{ plat__terraform_workspace_dir }}/workspace/plat" + when: debug_terraform | default(false) | bool - - name: Prompt added by jenright - pause: - prompt: "Ready to do Terraform destroy on role files in {{ plat__terraform_workspace_dir }}/workspace/plat" - when: debug_terraform | default(false) | bool +- name: Destroy Terraform authz resources + community.general.terraform: + project_path: "{{ plat__terraform_workspace_dir }}/workspace/plat" + state: "absent" + force_init: yes + register: tf_result + retries: 3 + delay: 10 + until: tf_result is succeeded - - name: Destroy terraform authz resources - community.general.terraform: - # TODO: Fix workspace_dir_path - # project_path: "{{ plat__terraform_workspace_dir }}/{{ workspace_dir_path }}/plat" - project_path: "{{ plat__terraform_workspace_dir }}/workspace/plat" - state: "absent" - force_init: yes - register: tf_result - retries: 3 - delay: 10 - until: tf_result is succeeded +- name: Prompt added by jenright + ansible.builtin.pause: + prompt: "Terraform destroy on role files complete. Check AWS Console." + when: debug_terraform | default(false) | bool - - name: Prompt added by jenright - pause: - prompt: "Terraform destroy on role files complete. Check AWS Console." - when: debug_terraform | default(false) | bool - - - name: Remove the terraform template directory - file: - path: "{{ plat__terraform_template_dir }}/plat/" - state: absent +- name: Remove the Terraform template directory + ansible.builtin.file: + path: "{{ plat__terraform_template_dir }}/plat/" + state: absent +- name: Remove the Terraform workspace directory + ansible.builtin.file: + path: "{{ plat__terraform_workspace_dir }}/workspace/plat" + state: absent + # TODO: Figure out how to handle below conditional with Terraform # - name: Tear down AWS Cross Acount # when: plat__teardown_deletes_xaccount diff --git a/roles/platform/template/aws/backend_state.tf.j2 b/roles/platform/template/aws/backend_state.tf.j2 new file mode 100644 index 00000000..a24d6aa4 --- /dev/null +++ b/roles/platform/template/aws/backend_state.tf.j2 @@ -0,0 +1,17 @@ +{% if plat__terraform_state_storage == "local" %} +# Terraform state is stored locally at {{ plat__terraform_workspace_dir }}/workspace/plat +{% endif %} + + +{% if plat__terraform_state_storage == "remote_s3" %} +terraform { + backend "s3" { + region = "{{ plat__region }}" + bucket = "{{ plat__terraform_remote_state_bucket }}" + key = "workspace/{{ plat__namespace }}/plat/terraform.tfstate" + dynamodb_table = "{{ plat__terraform_remote_state_lock_table }}" + # workspace_key_prefix = " terraform_workspace_key_prefix " + # encrypt = true + } +} +{% endif %} From ccbd1c8792194d6b9ffaa4e74738489a490db7f7 Mon Sep 17 00:00:00 2001 From: Jim Enright Date: Fri, 1 Oct 2021 09:54:33 +0100 Subject: [PATCH 11/33] Cleanup of Terraform tasks and variables Signed-off-by: Jim Enright --- roles/platform/template/aws/plat_aws_authz_policies.tf.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/platform/template/aws/plat_aws_authz_policies.tf.j2 b/roles/platform/template/aws/plat_aws_authz_policies.tf.j2 index 6df307fd..24e1b3a2 100644 --- a/roles/platform/template/aws/plat_aws_authz_policies.tf.j2 +++ b/roles/platform/template/aws/plat_aws_authz_policies.tf.j2 @@ -64,7 +64,7 @@ resource "aws_iam_policy" "{{ plat__aws_datalake_admin_s3_policy_name }}" { policy = file("{{ "./policy_docs/" ~ (__aws_policy_documents | json_query("results[?__policy_url_item.key==`datalake_admin_s3`].dest | [0]") | basename) }}") } -# ------- CDP Data Access Policies - datalake_admin_s3 ------- +# ------- CDP Data Access Policies - bucket_access ------- resource "aws_iam_policy" "{{ plat__aws_bucket_access_policy_name }}" { name = "{{ plat__aws_bucket_access_policy_name }}" description = "CDP Bucket S3 Access policy for {{ plat__namespace }}" From 45c4d391cef228cca1d7e641c44bedb1c2e0a1b9 Mon Sep 17 00:00:00 2001 From: Jim Enright Date: Fri, 1 Oct 2021 09:54:33 +0100 Subject: [PATCH 12/33] Create timestamped artefact of the generated Terraform files Signed-off-by: Jim Enright --- roles/common/defaults/main.yml | 6 +++++- roles/infrastructure/defaults/main.yml | 1 + .../tasks/initialize_aws_terraform.yml | 14 ++++++++++++-- roles/infrastructure/tasks/setup_terraform.yml | 5 +++++ roles/platform/defaults/main.yml | 1 + roles/platform/tasks/initialize_aws_terraform.yml | 14 ++++++++++++-- roles/platform/tasks/setup_aws_terraform_authz.yml | 5 +++++ 7 files changed, 41 insertions(+), 5 deletions(-) diff --git a/roles/common/defaults/main.yml b/roles/common/defaults/main.yml index 8b567a4d..14989d37 100644 --- a/roles/common/defaults/main.yml +++ b/roles/common/defaults/main.yml @@ -67,7 +67,11 @@ common__public_key_text: "{{ globals.ssh.public_key_text | defa common__region: "{{ globals.region | default(common__region_default[common__infra_type]) }}" common__storage_name: "{{ infra.storage.name | default([common__namespace, common__unique_storage_name_suffix[::2] | replace('-','')] | join('-')) }}" -common__terraform_template_dir: "{{ globals.terraform_template_dir | default( playbook_dir + './terraform_processed_template_code') }}" +# The processed Jinja template files for Terraform are placed in common__terraform_template_dir +common__terraform_template_dir: "{{ globals.terraform_template_dir | default( playbook_dir , './terraform_processed_template_code') | path_join }}" +# A timestamped artefact directory storing a copy of the Terraform code from each run +common__terraform_artefact_dir: "{{ [ common__terraform_template_dir , ('snapshot_' + ansible_date_time.iso8601 ) ] | path_join | regex_replace(':','_')}}" + common__terraform_workspace_dir: "{{ globals.terraform_workspace_dir | default( playbook_dir + '/.namespaces') }}" common__terraform_state_storage: "{{ globals.terraform_state_storage | default('local') }}" diff --git a/roles/infrastructure/defaults/main.yml b/roles/infrastructure/defaults/main.yml index 03480fbc..e1d8c371 100644 --- a/roles/infrastructure/defaults/main.yml +++ b/roles/infrastructure/defaults/main.yml @@ -31,6 +31,7 @@ infra__vpc_public_subnets_suffix: "{{ common__vpc_public_subnets_suffix }}" infra__deployment_engine: "{{ common__infra_deployment_engine }}" # Location of output from template module which creates Terraform infra__terraform_template_dir: "{{ common__terraform_template_dir }}" +infra__terraform_artefact_dir: "{{ common__terraform_artefact_dir }}" infra__terraform_workspace_dir: "{{ common__terraform_workspace_dir }}" infra__terraform_state_storage: "{{ common__terraform_state_storage }}" diff --git a/roles/infrastructure/tasks/initialize_aws_terraform.yml b/roles/infrastructure/tasks/initialize_aws_terraform.yml index 06af8f3a..3c081e4c 100644 --- a/roles/infrastructure/tasks/initialize_aws_terraform.yml +++ b/roles/infrastructure/tasks/initialize_aws_terraform.yml @@ -13,13 +13,23 @@ # limitations under the License. - name: Create terraform template .tf files - when: infra__terraform_template_dir is defined # TODO: Is this needed? + when: infra__terraform_template_dir is defined # TODO: Move this to validation block: - - name: Create terraform template dir + - name: Create Terraform template dir file: path: "{{ infra__terraform_template_dir }}/infra" state: directory + - name: Create artefact directory for Terraform infra code + file: + path: "{{ infra__terraform_artefact_dir }}/infra" + state: directory + + - name: Prompt added by jenright + pause: + prompt: "Created an artefact directory at {{ infra__terraform_artefact_dir }}/infra" + when: debug_terraform | default(false) | bool + # Apply template for Terraform provider - name: Generate Terraform Provider template: diff --git a/roles/infrastructure/tasks/setup_terraform.yml b/roles/infrastructure/tasks/setup_terraform.yml index da8a53de..2fdac2e8 100644 --- a/roles/infrastructure/tasks/setup_terraform.yml +++ b/roles/infrastructure/tasks/setup_terraform.yml @@ -31,6 +31,11 @@ dest: "{{ infra__terraform_workspace_dir }}/workspace/infra" # when: not workdir.stat.exists # TODO: This won't override if any changes to .tf are made. Good or Bad? +- name: Copy Terraform infra code to the artefact directory + ansible.builtin.copy: + src: "{{ infra__terraform_template_dir }}/infra/" + dest: "{{ infra__terraform_artefact_dir }}/infra" + - name: Prompt added by jenright ansible.builtin.pause: prompt: "Ready to do Terraform apply on infra files in {{ infra__terraform_workspace_dir }}/workspace/infra" diff --git a/roles/platform/defaults/main.yml b/roles/platform/defaults/main.yml index 30188325..d7595962 100644 --- a/roles/platform/defaults/main.yml +++ b/roles/platform/defaults/main.yml @@ -24,6 +24,7 @@ plat__infra_deployment_engine: "{{ common__infra_deployment_engine }}" # Location of output from template module which creates Terraform plat__terraform_template_dir: "{{ common__terraform_template_dir }}" +plat__terraform_artefact_dir: "{{ common__terraform_artefact_dir }}" plat__terraform_workspace_dir: "{{ common__terraform_workspace_dir }}" plat__terraform_state_storage: "{{ common__terraform_state_storage }}" diff --git a/roles/platform/tasks/initialize_aws_terraform.yml b/roles/platform/tasks/initialize_aws_terraform.yml index 5c28183a..80a9f9be 100644 --- a/roles/platform/tasks/initialize_aws_terraform.yml +++ b/roles/platform/tasks/initialize_aws_terraform.yml @@ -15,13 +15,23 @@ # limitations under the License. - name: Create terraform template .tf files - when: plat__terraform_template_dir is defined # TODO: Is this needed? + when: plat__terraform_template_dir is defined # TODO: Move this to validation block: - - name: Create terraform template dir + - name: Create Terraform template dir file: path: "{{ plat__terraform_template_dir }}/plat" state: directory + - name: Create artefact directory for Terraform infra code + file: + path: "{{ plat__terraform_artefact_dir }}/plat" + state: directory + + - name: Prompt added by jenright + pause: + prompt: "Created an artefact directory at {{ plat__terraform_artefact_dir }}/plat" + when: debug_terraform | default(false) | bool + # Apply template for Terraform provider - name: Generate Terraform Provider template: diff --git a/roles/platform/tasks/setup_aws_terraform_authz.yml b/roles/platform/tasks/setup_aws_terraform_authz.yml index 9407fa00..65fcee87 100644 --- a/roles/platform/tasks/setup_aws_terraform_authz.yml +++ b/roles/platform/tasks/setup_aws_terraform_authz.yml @@ -90,6 +90,11 @@ dest: "{{ plat__terraform_workspace_dir }}/workspace/plat" # when: not workdir.stat.exists # TODO: This won't override if any changes to .tf are made. Good or Bad? +- name: Copy Terraform plat code to the artefact directory + ansible.builtin.copy: + src: "{{ plat__terraform_template_dir }}/plat/" + dest: "{{ plat__terraform_artefact_dir }}/plat" + - name: Prompt added by jenright ansible.builtin.pause: prompt: "Ready to do Terraform apply on role files in {{ plat__terraform_workspace_dir }}/workspace/plat" From 1304e199c324c406bbdbe9e2cea10ac48008767f Mon Sep 17 00:00:00 2001 From: Jim Enright Date: Fri, 1 Oct 2021 09:54:34 +0100 Subject: [PATCH 13/33] Refactor download of AWS policy docs to initialize Signed-off-by: Jim Enright --- .../tasks/initialize_aws_terraform.yml | 58 ++++++++++++++-- .../tasks/setup_aws_terraform_authz.yml | 67 ------------------- 2 files changed, 54 insertions(+), 71 deletions(-) diff --git a/roles/platform/tasks/initialize_aws_terraform.yml b/roles/platform/tasks/initialize_aws_terraform.yml index 80a9f9be..724c7b89 100644 --- a/roles/platform/tasks/initialize_aws_terraform.yml +++ b/roles/platform/tasks/initialize_aws_terraform.yml @@ -27,10 +27,45 @@ path: "{{ plat__terraform_artefact_dir }}/plat" state: directory - - name: Prompt added by jenright - pause: - prompt: "Created an artefact directory at {{ plat__terraform_artefact_dir }}/plat" - when: debug_terraform | default(false) | bool + # Create and process the AWS Policy documents + - name: Create a temporary directory for policy documents + ansible.builtin.tempfile: + prefix: "aws-policy-" + state: directory + register: __aws_policy_tmpdir + + - name: Download AWS default policy documents + ansible.builtin.get_url: + dest: "{{ __aws_policy_tmpdir.path }}" + url: "{{ __policy_url_item.value }}" + loop_control: + loop_var: __policy_url_item + label: "{{ __policy_url_item.key }}" + loop: "{{ plat__aws_policy_urls | dict2items }}" + register: __aws_policy_documents + + - name: JE Debug Print __aws_policy_tmpdir + ansible.builtin.debug: + var: __aws_policy_tmpdir + + - name: Process AWS default policy documents + ansible.builtin.include_tasks: aws_policy_regex.yml + loop: "{{ __aws_policy_documents.results }}" + loop_control: + loop_var: __aws_policy_document_item + label: "{{ __aws_policy_document_item.__policy_url_item.key }}" + + - name: Some variables for creation of IAM + ansible.builtin.debug: + msg: + - plat__aws_xaccount_account_policy = {{ plat__aws_xaccount_account_policy }} + - plat__aws_xaccount_policy_name = {{ plat__aws_xaccount_policy_name }} + + # Copy the AWS policy documents to plat__terraform_template_dir + - name: Copy AWS policy documents to Terraform template directory + ansible.builtin.copy: + src: "{{ __aws_policy_tmpdir.path }}/" + dest: "{{ plat__terraform_template_dir }}/plat/policy_docs/" # Apply template for Terraform provider - name: Generate Terraform Provider @@ -51,6 +86,21 @@ dest: "{{ plat__terraform_template_dir }}/plat/variables.tf" no_log: false + # Apply template for Terraform auth resources.... + # ...policies + - name: Generate Terraform authz file for policies + ansible.builtin.template: + src: 'template/{{ plat__infra_type }}/plat_{{ plat__infra_type }}_authz_policies.tf.j2' + dest: "{{ plat__terraform_template_dir }}/plat/plat_authz_policies.tf" + no_log: false + + # ...roles + - name: Generate Terraform authz file for roles + ansible.builtin.template: + src: 'template/{{ plat__infra_type }}/plat_{{ plat__infra_type }}_authz_roles.tf.j2' + dest: "{{ plat__terraform_template_dir }}/plat/plat_authz_roles.tf" + no_log: false + - name: Prompt added by jenright pause: prompt: "PART 1 - Terraform role & policy files created in {{ plat__terraform_template_dir }}/plat" diff --git a/roles/platform/tasks/setup_aws_terraform_authz.yml b/roles/platform/tasks/setup_aws_terraform_authz.yml index 65fcee87..5ed2b499 100644 --- a/roles/platform/tasks/setup_aws_terraform_authz.yml +++ b/roles/platform/tasks/setup_aws_terraform_authz.yml @@ -14,71 +14,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -- name: Create a temporary directory for policy documents - ansible.builtin.tempfile: - prefix: "aws-policy-" - state: directory - register: __aws_policy_tmpdir - -- name: Download AWS default policy documents - ansible.builtin.get_url: - dest: "{{ __aws_policy_tmpdir.path }}" - url: "{{ __policy_url_item.value }}" - loop_control: - loop_var: __policy_url_item - label: "{{ __policy_url_item.key }}" - loop: "{{ plat__aws_policy_urls | dict2items }}" - register: __aws_policy_documents - -- name: JE Debug Print __aws_policy_tmpdir - ansible.builtin.debug: - var: __aws_policy_tmpdir - -- name: Process AWS default policy documents - ansible.builtin.include_tasks: aws_policy_regex.yml - loop: "{{ __aws_policy_documents.results }}" - loop_control: - loop_var: __aws_policy_document_item - label: "{{ __aws_policy_document_item.__policy_url_item.key }}" - -- name: Some variables for creation of IAM - ansible.builtin.debug: - msg: - - plat__aws_xaccount_account_policy = {{ plat__aws_xaccount_account_policy }} - - plat__aws_xaccount_policy_name = {{ plat__aws_xaccount_policy_name }} - -# ***************** TERRAFORM TEMPLATE PART 2 *********************** -# Needed here because the policy documents are only available after above tasks -# QUESTION: HOW CAN WE REARRANGE THIS? - -# Copy the AWS policy documents -- name: Copy AWS policy documents to Terraform template directory - ansible.builtin.copy: - src: "{{ __aws_policy_tmpdir.path }}/" - dest: "{{ plat__terraform_template_dir }}/plat/policy_docs/" - -# Apply template for Terraform auth resources.... -# ...policies -- name: Generate Terraform authz file for policies - ansible.builtin.template: - src: 'template/{{ plat__infra_type }}/plat_{{ plat__infra_type }}_authz_policies.tf.j2' - dest: "{{ plat__terraform_template_dir }}/plat/plat_authz_policies.tf" - no_log: false - -# ...roles -- name: Generate Terraform authz file for roles - ansible.builtin.template: - src: 'template/{{ plat__infra_type }}/plat_{{ plat__infra_type }}_authz_roles.tf.j2' - dest: "{{ plat__terraform_template_dir }}/plat/plat_authz_roles.tf" - no_log: false - -- name: Prompt added by jenright - ansible.builtin.pause: - prompt: "PART 2 - Terraform role & policy files created in {{ plat__terraform_template_dir }}/plat" - when: debug_terraform | default(false) | bool -# ***************** END TERRAFORM TEMPLATE PART 2 *********************** - -# ***************** TERRAFORM APPLY *********************** - name: Check if Terraform workspace directory exists ansible.builtin.stat: path: "{{ plat__terraform_workspace_dir }}/workspace/plat" @@ -126,8 +61,6 @@ state: absent when: plat__terraform_state_storage in ['remote_s3'] -# ***************** END TERRAFORM APPLY *********************** - # Now need to get create CDP Cross Account Credential # TODO: Is there a better place to put this? # First get the AWS Cross Account Role From ddfdd80524abf8f36d7bde2e3fdbfd9a308ac39a Mon Sep 17 00:00:00 2001 From: Jim Enright Date: Fri, 1 Oct 2021 09:54:34 +0100 Subject: [PATCH 14/33] Use tempdir for Terraform workspace when remote state Signed-off-by: Jim Enright --- .../infrastructure/tasks/setup_terraform.yml | 53 +++++++++++---- .../tasks/teardown_terraform.yml | 68 ++++++++++++++----- .../tasks/setup_aws_terraform_authz.yml | 53 +++++++++++---- .../tasks/teardown_aws_terraform_authz.yml | 62 +++++++++++++---- 4 files changed, 180 insertions(+), 56 deletions(-) diff --git a/roles/infrastructure/tasks/setup_terraform.yml b/roles/infrastructure/tasks/setup_terraform.yml index 2fdac2e8..4f566de2 100644 --- a/roles/infrastructure/tasks/setup_terraform.yml +++ b/roles/infrastructure/tasks/setup_terraform.yml @@ -20,30 +20,57 @@ - "I'm here doing to terraform apply" - "Here's the workspace: {{ infra__terraform_workspace_dir }}" -- name: Check if Terraform workspace directory exists - ansible.builtin.stat: - path: "{{ infra__terraform_workspace_dir }}/workspace/infra" - register: workdir +# When remote state use temp dir for terraform workspace +- name: Create Terraform workspace for remote state + when: infra__terraform_state_storage in ['remote_s3'] + block: + - name: Create a temporary directory for Terraform workspace + ansible.builtin.tempfile: + prefix: "tf_infra_workspace" + state: directory + register: __tf_infra_tmpdir -- name: Ensure the Terraform workspace directory exists - ansible.builtin.copy: - src: "{{ infra__terraform_template_dir }}/infra/" - dest: "{{ infra__terraform_workspace_dir }}/workspace/infra" - # when: not workdir.stat.exists # TODO: This won't override if any changes to .tf are made. Good or Bad? + - name: Copy the Terraform code to tf_infra_tmpdir + ansible.builtin.copy: + src: "{{ infra__terraform_template_dir }}/infra/" + dest: "{{ __tf_infra_tmpdir.path }}/" + +- name: Create Terraform workspace for local state + when: infra__terraform_state_storage == 'local' + block: + - name: Check if Terraform workspace directory exists + ansible.builtin.stat: + path: "{{ infra__terraform_workspace_dir }}/workspace/infra" + register: workdir + + - name: Ensure the Terraform workspace directory exists + ansible.builtin.copy: + src: "{{ infra__terraform_template_dir }}/infra/" + dest: "{{ infra__terraform_workspace_dir }}/workspace/infra" + # when: not workdir.stat.exists # TODO: This won't override if any changes to .tf are made. Good or Bad? - name: Copy Terraform infra code to the artefact directory ansible.builtin.copy: src: "{{ infra__terraform_template_dir }}/infra/" dest: "{{ infra__terraform_artefact_dir }}/infra" -- name: Prompt added by jenright +- name: Prompt added by jenright for local state ansible.builtin.pause: prompt: "Ready to do Terraform apply on infra files in {{ infra__terraform_workspace_dir }}/workspace/infra" - when: debug_terraform | default(false) | bool + when: + - infra__terraform_state_storage == 'local' + - debug_terraform | default(false) | bool + +- name: Prompt added by jenright for remote state + ansible.builtin.pause: + prompt: "Ready to do Terraform apply on infra files in {{ __tf_infra_tmpdir.path }}" + when: + - infra__terraform_state_storage in ['remote_s3'] + - debug_terraform | default(false) | bool - name: Applying Terraform community.general.terraform: - project_path: "{{ infra__terraform_workspace_dir }}/workspace/infra" + project_path: "{{ infra__terraform_workspace_dir +'/workspace/infra' if (infra__terraform_state_storage == 'local') else __tf_infra_tmpdir.path }}" state: "present" force_init: yes register: tf_result @@ -63,6 +90,6 @@ - name: Remove the Terraform workspace directory when using remote state ansible.builtin.file: - path: "{{ infra__terraform_workspace_dir }}/workspace/infra" + path: "{{ __tf_infra_tmpdir.path }}" state: absent when: infra__terraform_state_storage in ['remote_s3'] \ No newline at end of file diff --git a/roles/infrastructure/tasks/teardown_terraform.yml b/roles/infrastructure/tasks/teardown_terraform.yml index 0b1a6ba5..39d949e7 100644 --- a/roles/infrastructure/tasks/teardown_terraform.yml +++ b/roles/infrastructure/tasks/teardown_terraform.yml @@ -20,27 +20,56 @@ - "I'm here doing to terraform destroy" - "Here's the workspace: {{ infra__terraform_workspace_dir }}" -- name: Check if Terraform workspace directory exists - ansible.builtin.stat: - path: "{{ infra__terraform_workspace_dir }}/workspace/infra" - register: workdir +# When remote state use temp dir for terraform workspace +- name: Create Terraform workspace for remote state + when: infra__terraform_state_storage in ['remote_s3'] + block: + - name: Create a temporary directory for Terraform workspace + ansible.builtin.tempfile: + prefix: "tf_infra_workspace" + state: directory + register: __tf_infra_tmpdir -- name: Ensure the Terraform workspace directory exists - ansible.builtin.copy: - src: "{{ infra__terraform_template_dir }}/infra/" - dest: "{{ infra__terraform_workspace_dir }}/workspace/infra" - # when: not workdir.stat.exists # TODO: This won't override if any changes to .tf are made. Good or Bad? + - name: Copy the Terraform code to tf_infra_tmpdir + ansible.builtin.copy: + src: "{{ infra__terraform_template_dir }}/infra/" + dest: "{{ __tf_infra_tmpdir.path }}/" -- name: Prompt added by jenright +- name: Create Terraform workspace for local state + when: infra__terraform_state_storage == 'local' + block: + - name: Check if Terraform workspace directory exists + ansible.builtin.stat: + path: "{{ infra__terraform_workspace_dir }}/workspace/infra" + register: workdir + + - name: Ensure the Terraform workspace directory exists + ansible.builtin.copy: + src: "{{ infra__terraform_template_dir }}/infra/" + dest: "{{ infra__terraform_workspace_dir }}/workspace/infra" + # when: not workdir.stat.exists # TODO: This won't override if any changes to .tf are made. Good or Bad? + +- name: Print the values for remote or local state + debug: + msg: "{{ infra__terraform_state_storage == 'local' | ternary(infra__terraform_workspace_dir +'/workspace/infra', __tf_infra_tmpdir.path) }}" + +- name: Prompt added by jenright for local state ansible.builtin.pause: prompt: "Ready to do Terraform destroy on infra files in {{ infra__terraform_workspace_dir }}/workspace/infra" - when: debug_terraform | default(false) | bool + when: + - infra__terraform_state_storage == 'local' + - debug_terraform | default(false) | bool + +- name: Prompt added by jenright for remote state + ansible.builtin.pause: + prompt: "Ready to do Terraform apply on infra files in {{ __tf_infra_tmpdir.path }}" + when: + - infra__terraform_state_storage in ['remote_s3'] + - debug_terraform | default(false) | bool - name: Destroy Terraform infra resources community.general.terraform: - # TODO: Fix workspace_dir_path - # project_path: "{{ infra__terraform_workspace_dir }}/{{ workspace_dir_path }}" - project_path: "{{ infra__terraform_workspace_dir }}/workspace/infra" + project_path: "{{ infra__terraform_state_storage == 'local' | ternary(infra__terraform_workspace_dir +'/workspace/infra', __tf_infra_tmpdir.path) }}" state: "absent" force_init: yes register: tf_result @@ -58,7 +87,14 @@ path: "{{ infra__terraform_template_dir }}/infra" state: absent -- name: Remove the Terraform workspace directory +- name: Remove the Terraform workspace directory for local state ansible.builtin.file: path: "{{ infra__terraform_workspace_dir }}/workspace/infra" - state: absent \ No newline at end of file + state: absent + when: infra__terraform_state_storage == 'local' + +- name: Remove the Terraform workspace directory for remote state + ansible.builtin.file: + path: "{{ __tf_infra_tmpdir.path }}" + state: absent + when: infra__terraform_state_storage in ['remote_s3'] \ No newline at end of file diff --git a/roles/platform/tasks/setup_aws_terraform_authz.yml b/roles/platform/tasks/setup_aws_terraform_authz.yml index 5ed2b499..432ec694 100644 --- a/roles/platform/tasks/setup_aws_terraform_authz.yml +++ b/roles/platform/tasks/setup_aws_terraform_authz.yml @@ -14,30 +14,57 @@ # See the License for the specific language governing permissions and # limitations under the License. -- name: Check if Terraform workspace directory exists - ansible.builtin.stat: - path: "{{ plat__terraform_workspace_dir }}/workspace/plat" - register: workdir +# When remote state use temp dir for terraform workspace +- name: Create Terraform workspace for remote state + when: plat__terraform_state_storage in ['remote_s3'] + block: + - name: Create a temporary directory for Terraform workspace + ansible.builtin.tempfile: + prefix: "tf_plat_workspace" + state: directory + register: __tf_plat_tmpdir -- name: Ensure the Terraform workspace directory exists - ansible.builtin.copy: - src: "{{ plat__terraform_template_dir }}/plat/" - dest: "{{ plat__terraform_workspace_dir }}/workspace/plat" - # when: not workdir.stat.exists # TODO: This won't override if any changes to .tf are made. Good or Bad? + - name: Copy the Terraform code to __tf_plat_tmpdir + ansible.builtin.copy: + src: "{{ plat__terraform_template_dir }}/plat/" + dest: "{{ __tf_plat_tmpdir.path }}/" + +- name: Create Terraform workspace for local state + when: plat__terraform_state_storage == 'local' + block: + - name: Check if Terraform workspace directory exists + ansible.builtin.stat: + path: "{{ plat__terraform_workspace_dir }}/workspace/plat" + register: workdir + + - name: Ensure the Terraform workspace directory exists + ansible.builtin.copy: + src: "{{ plat__terraform_template_dir }}/plat/" + dest: "{{ plat__terraform_workspace_dir }}/workspace/plat" + # when: not workdir.stat.exists # TODO: This won't override if any changes to .tf are made. Good or Bad? - name: Copy Terraform plat code to the artefact directory ansible.builtin.copy: src: "{{ plat__terraform_template_dir }}/plat/" dest: "{{ plat__terraform_artefact_dir }}/plat" -- name: Prompt added by jenright +- name: Prompt added by jenright for local state ansible.builtin.pause: prompt: "Ready to do Terraform apply on role files in {{ plat__terraform_workspace_dir }}/workspace/plat" - when: debug_terraform | default(false) | bool + when: + - plat__terraform_state_storage == 'local' + - debug_terraform | default(false) | bool + +- name: Prompt added by jenright for remote state + ansible.builtin.pause: + prompt: "Ready to do Terraform apply on role files in {{ __tf_plat_tmpdir.path }}" + when: + - plat__terraform_state_storage in ['remote_s3'] + - debug_terraform | default(false) | bool - name: Applying Terraform community.general.terraform: - project_path: "{{ plat__terraform_workspace_dir }}/workspace/plat" + project_path: "{{ plat__terraform_workspace_dir +'/workspace/plat' if (plat__terraform_state_storage == 'local') else __tf_plat_tmpdir.path }}" state: "present" force_init: yes register: tf_result @@ -57,7 +84,7 @@ - name: Remove the Terraform workspace directory when using remote state ansible.builtin.file: - path: "{{ plat__terraform_workspace_dir }}/workspace/plat" + path: "{{ __tf_plat_tmpdir.path }}" state: absent when: plat__terraform_state_storage in ['remote_s3'] diff --git a/roles/platform/tasks/teardown_aws_terraform_authz.yml b/roles/platform/tasks/teardown_aws_terraform_authz.yml index 711bde5a..f95bb5a9 100644 --- a/roles/platform/tasks/teardown_aws_terraform_authz.yml +++ b/roles/platform/tasks/teardown_aws_terraform_authz.yml @@ -26,25 +26,52 @@ - "I'm here doing to terraform destroy" - "Here's the workspace: {{ plat__terraform_workspace_dir }}" -- name: Check if Terraform workspace directory exists - ansible.builtin.stat: - path: "{{ plat__terraform_template_dir }}/workspace/plat" - register: workdir +# When remote state use temp dir for terraform workspace +- name: Create Terraform workspace for remote state + when: plat__terraform_state_storage in ['remote_s3'] + block: + - name: Create a temporary directory for Terraform workspace + ansible.builtin.tempfile: + prefix: "tf_plat_workspace" + state: directory + register: __tf_plat_tmpdir -- name: Ensure the Terraform workspace directory exists - ansible.builtin.copy: - src: "{{ plat__terraform_template_dir }}/plat/" - dest: "{{ plat__terraform_workspace_dir }}/workspace/plat" - # when: not workdir.stat.exists # TODO: This won't override if any changes to .tf are made. Good or Bad? + - name: Copy the Terraform code to __tf_plat_tmpdir + ansible.builtin.copy: + src: "{{ plat__terraform_template_dir }}/plat/" + dest: "{{ __tf_plat_tmpdir.path }}/" -- name: Prompt added by jenright +- name: Create Terraform workspace for local state + when: plat__terraform_state_storage == 'local' + block: + - name: Check if Terraform workspace directory exists + ansible.builtin.stat: + path: "{{ plat__terraform_workspace_dir }}/workspace/plat" + register: workdir + + - name: Ensure the Terraform workspace directory exists + ansible.builtin.copy: + src: "{{ plat__terraform_template_dir }}/plat/" + dest: "{{ plat__terraform_workspace_dir }}/workspace/plat" + # when: not workdir.stat.exists # TODO: This won't override if any changes to .tf are made. Good or Bad? + +- name: Prompt added by jenright for local state ansible.builtin.pause: - prompt: "Ready to do Terraform destroy on role files in {{ plat__terraform_workspace_dir }}/workspace/plat" - when: debug_terraform | default(false) | bool + prompt: "Ready to do Terraform apply on role files in {{ plat__terraform_workspace_dir }}/workspace/plat" + when: + - plat__terraform_state_storage == 'local' + - debug_terraform | default(false) | bool + +- name: Prompt added by jenright for remote state + ansible.builtin.pause: + prompt: "Ready to do Terraform apply on role files in {{ __tf_plat_tmpdir.path }}" + when: + - plat__terraform_state_storage in ['remote_s3'] + - debug_terraform | default(false) | bool - name: Destroy Terraform authz resources community.general.terraform: - project_path: "{{ plat__terraform_workspace_dir }}/workspace/plat" + project_path: "{{ plat__terraform_workspace_dir +'/workspace/plat' if (plat__terraform_state_storage == 'local') else __tf_plat_tmpdir.path }}" state: "absent" force_init: yes register: tf_result @@ -62,10 +89,17 @@ path: "{{ plat__terraform_template_dir }}/plat/" state: absent -- name: Remove the Terraform workspace directory +- name: Remove the Terraform workspace directory for local state ansible.builtin.file: path: "{{ plat__terraform_workspace_dir }}/workspace/plat" state: absent + when: plat__terraform_state_storage == 'local' + +- name: Remove the Terraform workspace directory for remote state + ansible.builtin.file: + path: "{{ __tf_plat_tmpdir.path }}" + state: absent + when: plat__terraform_state_storage in ['remote_s3'] # TODO: Figure out how to handle below conditional with Terraform # - name: Tear down AWS Cross Acount From cdcaed200e77f7c5ff43da3c2116cf66ddc3029d Mon Sep 17 00:00:00 2001 From: Jim Enright Date: Fri, 1 Oct 2021 09:54:35 +0100 Subject: [PATCH 15/33] Revert "Use tempdir for Terraform workspace when remote state" This reverts commit 1360527a708fb37fbb1c331326a537a32304d7ee. Signed-off-by: Jim Enright --- .../infrastructure/tasks/setup_terraform.yml | 53 ++++----------- .../tasks/teardown_terraform.yml | 68 +++++-------------- .../tasks/setup_aws_terraform_authz.yml | 53 ++++----------- .../tasks/teardown_aws_terraform_authz.yml | 62 ++++------------- 4 files changed, 56 insertions(+), 180 deletions(-) diff --git a/roles/infrastructure/tasks/setup_terraform.yml b/roles/infrastructure/tasks/setup_terraform.yml index 4f566de2..2fdac2e8 100644 --- a/roles/infrastructure/tasks/setup_terraform.yml +++ b/roles/infrastructure/tasks/setup_terraform.yml @@ -20,57 +20,30 @@ - "I'm here doing to terraform apply" - "Here's the workspace: {{ infra__terraform_workspace_dir }}" -# When remote state use temp dir for terraform workspace -- name: Create Terraform workspace for remote state - when: infra__terraform_state_storage in ['remote_s3'] - block: - - name: Create a temporary directory for Terraform workspace - ansible.builtin.tempfile: - prefix: "tf_infra_workspace" - state: directory - register: __tf_infra_tmpdir +- name: Check if Terraform workspace directory exists + ansible.builtin.stat: + path: "{{ infra__terraform_workspace_dir }}/workspace/infra" + register: workdir - - name: Copy the Terraform code to tf_infra_tmpdir - ansible.builtin.copy: - src: "{{ infra__terraform_template_dir }}/infra/" - dest: "{{ __tf_infra_tmpdir.path }}/" - -- name: Create Terraform workspace for local state - when: infra__terraform_state_storage == 'local' - block: - - name: Check if Terraform workspace directory exists - ansible.builtin.stat: - path: "{{ infra__terraform_workspace_dir }}/workspace/infra" - register: workdir - - - name: Ensure the Terraform workspace directory exists - ansible.builtin.copy: - src: "{{ infra__terraform_template_dir }}/infra/" - dest: "{{ infra__terraform_workspace_dir }}/workspace/infra" - # when: not workdir.stat.exists # TODO: This won't override if any changes to .tf are made. Good or Bad? +- name: Ensure the Terraform workspace directory exists + ansible.builtin.copy: + src: "{{ infra__terraform_template_dir }}/infra/" + dest: "{{ infra__terraform_workspace_dir }}/workspace/infra" + # when: not workdir.stat.exists # TODO: This won't override if any changes to .tf are made. Good or Bad? - name: Copy Terraform infra code to the artefact directory ansible.builtin.copy: src: "{{ infra__terraform_template_dir }}/infra/" dest: "{{ infra__terraform_artefact_dir }}/infra" -- name: Prompt added by jenright for local state +- name: Prompt added by jenright ansible.builtin.pause: prompt: "Ready to do Terraform apply on infra files in {{ infra__terraform_workspace_dir }}/workspace/infra" - when: - - infra__terraform_state_storage == 'local' - - debug_terraform | default(false) | bool - -- name: Prompt added by jenright for remote state - ansible.builtin.pause: - prompt: "Ready to do Terraform apply on infra files in {{ __tf_infra_tmpdir.path }}" - when: - - infra__terraform_state_storage in ['remote_s3'] - - debug_terraform | default(false) | bool + when: debug_terraform | default(false) | bool - name: Applying Terraform community.general.terraform: - project_path: "{{ infra__terraform_workspace_dir +'/workspace/infra' if (infra__terraform_state_storage == 'local') else __tf_infra_tmpdir.path }}" + project_path: "{{ infra__terraform_workspace_dir }}/workspace/infra" state: "present" force_init: yes register: tf_result @@ -90,6 +63,6 @@ - name: Remove the Terraform workspace directory when using remote state ansible.builtin.file: - path: "{{ __tf_infra_tmpdir.path }}" + path: "{{ infra__terraform_workspace_dir }}/workspace/infra" state: absent when: infra__terraform_state_storage in ['remote_s3'] \ No newline at end of file diff --git a/roles/infrastructure/tasks/teardown_terraform.yml b/roles/infrastructure/tasks/teardown_terraform.yml index 39d949e7..0b1a6ba5 100644 --- a/roles/infrastructure/tasks/teardown_terraform.yml +++ b/roles/infrastructure/tasks/teardown_terraform.yml @@ -20,56 +20,27 @@ - "I'm here doing to terraform destroy" - "Here's the workspace: {{ infra__terraform_workspace_dir }}" -# When remote state use temp dir for terraform workspace -- name: Create Terraform workspace for remote state - when: infra__terraform_state_storage in ['remote_s3'] - block: - - name: Create a temporary directory for Terraform workspace - ansible.builtin.tempfile: - prefix: "tf_infra_workspace" - state: directory - register: __tf_infra_tmpdir - - - name: Copy the Terraform code to tf_infra_tmpdir - ansible.builtin.copy: - src: "{{ infra__terraform_template_dir }}/infra/" - dest: "{{ __tf_infra_tmpdir.path }}/" - -- name: Create Terraform workspace for local state - when: infra__terraform_state_storage == 'local' - block: - - name: Check if Terraform workspace directory exists - ansible.builtin.stat: - path: "{{ infra__terraform_workspace_dir }}/workspace/infra" - register: workdir - - - name: Ensure the Terraform workspace directory exists - ansible.builtin.copy: - src: "{{ infra__terraform_template_dir }}/infra/" - dest: "{{ infra__terraform_workspace_dir }}/workspace/infra" - # when: not workdir.stat.exists # TODO: This won't override if any changes to .tf are made. Good or Bad? +- name: Check if Terraform workspace directory exists + ansible.builtin.stat: + path: "{{ infra__terraform_workspace_dir }}/workspace/infra" + register: workdir -- name: Print the values for remote or local state - debug: - msg: "{{ infra__terraform_state_storage == 'local' | ternary(infra__terraform_workspace_dir +'/workspace/infra', __tf_infra_tmpdir.path) }}" +- name: Ensure the Terraform workspace directory exists + ansible.builtin.copy: + src: "{{ infra__terraform_template_dir }}/infra/" + dest: "{{ infra__terraform_workspace_dir }}/workspace/infra" + # when: not workdir.stat.exists # TODO: This won't override if any changes to .tf are made. Good or Bad? -- name: Prompt added by jenright for local state +- name: Prompt added by jenright ansible.builtin.pause: prompt: "Ready to do Terraform destroy on infra files in {{ infra__terraform_workspace_dir }}/workspace/infra" - when: - - infra__terraform_state_storage == 'local' - - debug_terraform | default(false) | bool - -- name: Prompt added by jenright for remote state - ansible.builtin.pause: - prompt: "Ready to do Terraform apply on infra files in {{ __tf_infra_tmpdir.path }}" - when: - - infra__terraform_state_storage in ['remote_s3'] - - debug_terraform | default(false) | bool + when: debug_terraform | default(false) | bool - name: Destroy Terraform infra resources community.general.terraform: - project_path: "{{ infra__terraform_state_storage == 'local' | ternary(infra__terraform_workspace_dir +'/workspace/infra', __tf_infra_tmpdir.path) }}" + # TODO: Fix workspace_dir_path + # project_path: "{{ infra__terraform_workspace_dir }}/{{ workspace_dir_path }}" + project_path: "{{ infra__terraform_workspace_dir }}/workspace/infra" state: "absent" force_init: yes register: tf_result @@ -87,14 +58,7 @@ path: "{{ infra__terraform_template_dir }}/infra" state: absent -- name: Remove the Terraform workspace directory for local state +- name: Remove the Terraform workspace directory ansible.builtin.file: path: "{{ infra__terraform_workspace_dir }}/workspace/infra" - state: absent - when: infra__terraform_state_storage == 'local' - -- name: Remove the Terraform workspace directory for remote state - ansible.builtin.file: - path: "{{ __tf_infra_tmpdir.path }}" - state: absent - when: infra__terraform_state_storage in ['remote_s3'] \ No newline at end of file + state: absent \ No newline at end of file diff --git a/roles/platform/tasks/setup_aws_terraform_authz.yml b/roles/platform/tasks/setup_aws_terraform_authz.yml index 432ec694..5ed2b499 100644 --- a/roles/platform/tasks/setup_aws_terraform_authz.yml +++ b/roles/platform/tasks/setup_aws_terraform_authz.yml @@ -14,57 +14,30 @@ # See the License for the specific language governing permissions and # limitations under the License. -# When remote state use temp dir for terraform workspace -- name: Create Terraform workspace for remote state - when: plat__terraform_state_storage in ['remote_s3'] - block: - - name: Create a temporary directory for Terraform workspace - ansible.builtin.tempfile: - prefix: "tf_plat_workspace" - state: directory - register: __tf_plat_tmpdir - - - name: Copy the Terraform code to __tf_plat_tmpdir - ansible.builtin.copy: - src: "{{ plat__terraform_template_dir }}/plat/" - dest: "{{ __tf_plat_tmpdir.path }}/" - -- name: Create Terraform workspace for local state - when: plat__terraform_state_storage == 'local' - block: - - name: Check if Terraform workspace directory exists - ansible.builtin.stat: - path: "{{ plat__terraform_workspace_dir }}/workspace/plat" - register: workdir +- name: Check if Terraform workspace directory exists + ansible.builtin.stat: + path: "{{ plat__terraform_workspace_dir }}/workspace/plat" + register: workdir - - name: Ensure the Terraform workspace directory exists - ansible.builtin.copy: - src: "{{ plat__terraform_template_dir }}/plat/" - dest: "{{ plat__terraform_workspace_dir }}/workspace/plat" - # when: not workdir.stat.exists # TODO: This won't override if any changes to .tf are made. Good or Bad? +- name: Ensure the Terraform workspace directory exists + ansible.builtin.copy: + src: "{{ plat__terraform_template_dir }}/plat/" + dest: "{{ plat__terraform_workspace_dir }}/workspace/plat" + # when: not workdir.stat.exists # TODO: This won't override if any changes to .tf are made. Good or Bad? - name: Copy Terraform plat code to the artefact directory ansible.builtin.copy: src: "{{ plat__terraform_template_dir }}/plat/" dest: "{{ plat__terraform_artefact_dir }}/plat" -- name: Prompt added by jenright for local state +- name: Prompt added by jenright ansible.builtin.pause: prompt: "Ready to do Terraform apply on role files in {{ plat__terraform_workspace_dir }}/workspace/plat" - when: - - plat__terraform_state_storage == 'local' - - debug_terraform | default(false) | bool - -- name: Prompt added by jenright for remote state - ansible.builtin.pause: - prompt: "Ready to do Terraform apply on role files in {{ __tf_plat_tmpdir.path }}" - when: - - plat__terraform_state_storage in ['remote_s3'] - - debug_terraform | default(false) | bool + when: debug_terraform | default(false) | bool - name: Applying Terraform community.general.terraform: - project_path: "{{ plat__terraform_workspace_dir +'/workspace/plat' if (plat__terraform_state_storage == 'local') else __tf_plat_tmpdir.path }}" + project_path: "{{ plat__terraform_workspace_dir }}/workspace/plat" state: "present" force_init: yes register: tf_result @@ -84,7 +57,7 @@ - name: Remove the Terraform workspace directory when using remote state ansible.builtin.file: - path: "{{ __tf_plat_tmpdir.path }}" + path: "{{ plat__terraform_workspace_dir }}/workspace/plat" state: absent when: plat__terraform_state_storage in ['remote_s3'] diff --git a/roles/platform/tasks/teardown_aws_terraform_authz.yml b/roles/platform/tasks/teardown_aws_terraform_authz.yml index f95bb5a9..711bde5a 100644 --- a/roles/platform/tasks/teardown_aws_terraform_authz.yml +++ b/roles/platform/tasks/teardown_aws_terraform_authz.yml @@ -26,52 +26,25 @@ - "I'm here doing to terraform destroy" - "Here's the workspace: {{ plat__terraform_workspace_dir }}" -# When remote state use temp dir for terraform workspace -- name: Create Terraform workspace for remote state - when: plat__terraform_state_storage in ['remote_s3'] - block: - - name: Create a temporary directory for Terraform workspace - ansible.builtin.tempfile: - prefix: "tf_plat_workspace" - state: directory - register: __tf_plat_tmpdir +- name: Check if Terraform workspace directory exists + ansible.builtin.stat: + path: "{{ plat__terraform_template_dir }}/workspace/plat" + register: workdir - - name: Copy the Terraform code to __tf_plat_tmpdir - ansible.builtin.copy: - src: "{{ plat__terraform_template_dir }}/plat/" - dest: "{{ __tf_plat_tmpdir.path }}/" +- name: Ensure the Terraform workspace directory exists + ansible.builtin.copy: + src: "{{ plat__terraform_template_dir }}/plat/" + dest: "{{ plat__terraform_workspace_dir }}/workspace/plat" + # when: not workdir.stat.exists # TODO: This won't override if any changes to .tf are made. Good or Bad? -- name: Create Terraform workspace for local state - when: plat__terraform_state_storage == 'local' - block: - - name: Check if Terraform workspace directory exists - ansible.builtin.stat: - path: "{{ plat__terraform_workspace_dir }}/workspace/plat" - register: workdir - - - name: Ensure the Terraform workspace directory exists - ansible.builtin.copy: - src: "{{ plat__terraform_template_dir }}/plat/" - dest: "{{ plat__terraform_workspace_dir }}/workspace/plat" - # when: not workdir.stat.exists # TODO: This won't override if any changes to .tf are made. Good or Bad? - -- name: Prompt added by jenright for local state - ansible.builtin.pause: - prompt: "Ready to do Terraform apply on role files in {{ plat__terraform_workspace_dir }}/workspace/plat" - when: - - plat__terraform_state_storage == 'local' - - debug_terraform | default(false) | bool - -- name: Prompt added by jenright for remote state +- name: Prompt added by jenright ansible.builtin.pause: - prompt: "Ready to do Terraform apply on role files in {{ __tf_plat_tmpdir.path }}" - when: - - plat__terraform_state_storage in ['remote_s3'] - - debug_terraform | default(false) | bool + prompt: "Ready to do Terraform destroy on role files in {{ plat__terraform_workspace_dir }}/workspace/plat" + when: debug_terraform | default(false) | bool - name: Destroy Terraform authz resources community.general.terraform: - project_path: "{{ plat__terraform_workspace_dir +'/workspace/plat' if (plat__terraform_state_storage == 'local') else __tf_plat_tmpdir.path }}" + project_path: "{{ plat__terraform_workspace_dir }}/workspace/plat" state: "absent" force_init: yes register: tf_result @@ -89,17 +62,10 @@ path: "{{ plat__terraform_template_dir }}/plat/" state: absent -- name: Remove the Terraform workspace directory for local state +- name: Remove the Terraform workspace directory ansible.builtin.file: path: "{{ plat__terraform_workspace_dir }}/workspace/plat" state: absent - when: plat__terraform_state_storage == 'local' - -- name: Remove the Terraform workspace directory for remote state - ansible.builtin.file: - path: "{{ __tf_plat_tmpdir.path }}" - state: absent - when: plat__terraform_state_storage in ['remote_s3'] # TODO: Figure out how to handle below conditional with Terraform # - name: Tear down AWS Cross Acount From 26ce3f08e0860258e14f49a34ff8d419a641cfc2 Mon Sep 17 00:00:00 2001 From: Jim Enright Date: Fri, 1 Oct 2021 09:54:36 +0100 Subject: [PATCH 16/33] Add validation of variables used for Terraform Signed-off-by: Jim Enright --- roles/common/defaults/main.yml | 8 ++++-- roles/infrastructure/defaults/main.yml | 1 + .../tasks/initialize_aws_terraform.yml | 6 ---- .../initialize_teardown_aws_terraform.yml | 1 - .../tasks/validate_aws_terraform.yml | 25 +++++++++++++++++ roles/platform/defaults/main.yml | 1 + .../tasks/initialize_aws_terraform.yml | 1 - .../initialize_teardown_aws_terraform.yml | 3 +- .../platform/tasks/validate_aws_terraform.yml | 28 +++++++++++++++++-- 9 files changed, 59 insertions(+), 15 deletions(-) diff --git a/roles/common/defaults/main.yml b/roles/common/defaults/main.yml index 14989d37..0b3d50cd 100644 --- a/roles/common/defaults/main.yml +++ b/roles/common/defaults/main.yml @@ -67,13 +67,15 @@ common__public_key_text: "{{ globals.ssh.public_key_text | defa common__region: "{{ globals.region | default(common__region_default[common__infra_type]) }}" common__storage_name: "{{ infra.storage.name | default([common__namespace, common__unique_storage_name_suffix[::2] | replace('-','')] | join('-')) }}" +# Terraform # The processed Jinja template files for Terraform are placed in common__terraform_template_dir -common__terraform_template_dir: "{{ globals.terraform_template_dir | default( playbook_dir , './terraform_processed_template_code') | path_join }}" +common__terraform_template_dir: "{{ globals.terraform_template_dir | default( playbook_dir , './terraform_processed_template_code') | path_join }}" # A timestamped artefact directory storing a copy of the Terraform code from each run -common__terraform_artefact_dir: "{{ [ common__terraform_template_dir , ('snapshot_' + ansible_date_time.iso8601 ) ] | path_join | regex_replace(':','_')}}" +common__terraform_artefact_dir: "{{ [ common__terraform_template_dir , ('tf_artefacts_' + ansible_date_time.iso8601 ) ] | path_join | regex_replace(':','_')}}" -common__terraform_workspace_dir: "{{ globals.terraform_workspace_dir | default( playbook_dir + '/.namespaces') }}" +common__terraform_workspace_dir: "{{ globals.terraform_workspace_dir | default( playbook_dir + '/.namespaces') }}" +common__terraform_allowed_state_storage: "['local', 'remote_s3']" common__terraform_state_storage: "{{ globals.terraform_state_storage | default('local') }}" common__terraform_remote_state_bucket: "{{ globals.terraform_remote_state_bucket | default('') }}" common__terraform_remote_state_lock_table: "{{ globals.terraform_remote_state_lock_table | default('') }}" diff --git a/roles/infrastructure/defaults/main.yml b/roles/infrastructure/defaults/main.yml index e1d8c371..504ecd82 100644 --- a/roles/infrastructure/defaults/main.yml +++ b/roles/infrastructure/defaults/main.yml @@ -34,6 +34,7 @@ infra__terraform_template_dir: "{{ common__terraform_template_dir }}" infra__terraform_artefact_dir: "{{ common__terraform_artefact_dir }}" infra__terraform_workspace_dir: "{{ common__terraform_workspace_dir }}" +infra__terraform_allowed_state_storage: "{{ common__terraform_allowed_state_storage }}" infra__terraform_state_storage: "{{ common__terraform_state_storage }}" infra__terraform_remote_state_bucket: "{{ common__terraform_remote_state_bucket }}" infra__terraform_remote_state_lock_table: "{{ common__terraform_remote_state_lock_table }}" diff --git a/roles/infrastructure/tasks/initialize_aws_terraform.yml b/roles/infrastructure/tasks/initialize_aws_terraform.yml index 3c081e4c..436e9027 100644 --- a/roles/infrastructure/tasks/initialize_aws_terraform.yml +++ b/roles/infrastructure/tasks/initialize_aws_terraform.yml @@ -13,7 +13,6 @@ # limitations under the License. - name: Create terraform template .tf files - when: infra__terraform_template_dir is defined # TODO: Move this to validation block: - name: Create Terraform template dir file: @@ -25,11 +24,6 @@ path: "{{ infra__terraform_artefact_dir }}/infra" state: directory - - name: Prompt added by jenright - pause: - prompt: "Created an artefact directory at {{ infra__terraform_artefact_dir }}/infra" - when: debug_terraform | default(false) | bool - # Apply template for Terraform provider - name: Generate Terraform Provider template: diff --git a/roles/infrastructure/tasks/initialize_teardown_aws_terraform.yml b/roles/infrastructure/tasks/initialize_teardown_aws_terraform.yml index 34d91be2..4fb052e3 100644 --- a/roles/infrastructure/tasks/initialize_teardown_aws_terraform.yml +++ b/roles/infrastructure/tasks/initialize_teardown_aws_terraform.yml @@ -13,7 +13,6 @@ # limitations under the License. - name: Create terraform template .tf files - when: infra__terraform_template_dir is defined # TODO: Is this needed? block: - name: Create terraform template dir file: diff --git a/roles/infrastructure/tasks/validate_aws_terraform.yml b/roles/infrastructure/tasks/validate_aws_terraform.yml index 28ec10d4..ddd238db 100644 --- a/roles/infrastructure/tasks/validate_aws_terraform.yml +++ b/roles/infrastructure/tasks/validate_aws_terraform.yml @@ -30,6 +30,31 @@ - name: Print AWS Profile to debug ansible.builtin.command: echo AWS_PROFILE is $AWS_PROFILE +- name: Confirm that required Terraform variables are defined + block: + - name: Check infra__terraform_template_dir + ansible.builtin.assert: + that: + - "infra__terraform_template_dir is defined" + fail_msg: "Required infra__terraform_template_dir variable for Terraform is not set." + quiet: yes + + - name: Check infra__terraform_workspace_dir + ansible.builtin.assert: + that: + - "infra__terraform_workspace_dir is defined" + fail_msg: "Required infra__terraform_workspace_dir variable for Terraform is not set." + quiet: yes + + - name: Check infra__terraform_state_storage + ansible.builtin.assert: + that: + - "infra__terraform_state_storage is defined" + - "infra__terraform_state_storage in infra__terraform_allowed_state_storage" + fail_msg: "Required infra__terraform_state_storage variable for Terraform needs to be \ + one of {{ infra__terraform_allowed_state_storage | join(', ') }}" + quiet: yes + - name: Print Executing Terraform message ansible.builtin.debug: msg: "Executing Terraform. Value of infra__deployment_engine = {{ infra__deployment_engine }}" \ No newline at end of file diff --git a/roles/platform/defaults/main.yml b/roles/platform/defaults/main.yml index d7595962..67d5a401 100644 --- a/roles/platform/defaults/main.yml +++ b/roles/platform/defaults/main.yml @@ -27,6 +27,7 @@ plat__terraform_template_dir: "{{ common__terraform_template_dir plat__terraform_artefact_dir: "{{ common__terraform_artefact_dir }}" plat__terraform_workspace_dir: "{{ common__terraform_workspace_dir }}" +plat__terraform_allowed_state_storage: "{{ common__terraform_allowed_state_storage }}" plat__terraform_state_storage: "{{ common__terraform_state_storage }}" plat__terraform_remote_state_bucket: "{{ common__terraform_remote_state_bucket }}" plat__terraform_remote_state_lock_table: "{{ common__terraform_remote_state_lock_table }}" diff --git a/roles/platform/tasks/initialize_aws_terraform.yml b/roles/platform/tasks/initialize_aws_terraform.yml index 724c7b89..11d48187 100644 --- a/roles/platform/tasks/initialize_aws_terraform.yml +++ b/roles/platform/tasks/initialize_aws_terraform.yml @@ -15,7 +15,6 @@ # limitations under the License. - name: Create terraform template .tf files - when: plat__terraform_template_dir is defined # TODO: Move this to validation block: - name: Create Terraform template dir file: diff --git a/roles/platform/tasks/initialize_teardown_aws_terraform.yml b/roles/platform/tasks/initialize_teardown_aws_terraform.yml index 7418bacd..3ca75ad2 100644 --- a/roles/platform/tasks/initialize_teardown_aws_terraform.yml +++ b/roles/platform/tasks/initialize_teardown_aws_terraform.yml @@ -13,7 +13,6 @@ # limitations under the License. - name: Create terraform template .tf files - when: plat__terraform_template_dir is defined # TODO: Is this needed? block: - name: Create terraform template dir ansible.builtin.file: @@ -72,7 +71,7 @@ path: "{{ __aws_policy_tmpdir.path }}" state: absent -# NOTE: These don't work because not all variables are defined during teardown +# NOTE: jenright These don't work because not all variables are defined during teardown # ......ALSO they are not needed because we are working off the state file # # Apply template for Terraform auth resources.... # # ...policies diff --git a/roles/platform/tasks/validate_aws_terraform.yml b/roles/platform/tasks/validate_aws_terraform.yml index fd3a70af..ae74f9a8 100644 --- a/roles/platform/tasks/validate_aws_terraform.yml +++ b/roles/platform/tasks/validate_aws_terraform.yml @@ -27,8 +27,32 @@ loop: - plat__public_key_id + +- name: Confirm that required Terraform variables are defined + block: + - name: Check plat__terraform_template_dir + ansible.builtin.assert: + that: + - "plat__terraform_template_dir is defined" + fail_msg: "Required plat__terraform_template_dir variable for Terraform is not set." + quiet: yes + + - name: Check plat__terraform_workspace_dir + ansible.builtin.assert: + that: + - "plat__terraform_workspace_dir is defined" + fail_msg: "Required plat__terraform_workspace_dir variable for Terraform is not set." + quiet: yes + + - name: Check infra__terraform_state_storage + ansible.builtin.assert: + that: + - "plat__terraform_state_storage is defined" + - "plat__terraform_state_storage in plat__terraform_allowed_state_storage" + fail_msg: "Required plat__terraform_state_storage variable for Terraform needs to be \ + one of {{ plat__terraform_allowed_state_storage | join(', ') }}" + quiet: yes + - name: Print Executing Terraform message ansible.builtin.debug: msg: "Executing Terraform. Value of plat__infra_deployment_engine = {{ plat__infra_deployment_engine }}" - -# TODO: Put any Terraform specific stuff here \ No newline at end of file From ca8f4e9ed1e6921ed4fd6f21c24d771173e55914 Mon Sep 17 00:00:00 2001 From: Jim Enright Date: Fri, 1 Oct 2021 09:54:36 +0100 Subject: [PATCH 17/33] Cleanup of Terraform tasks and variables Signed-off-by: Jim Enright --- .../tasks/initialize_aws_terraform.yml | 96 ++++++------ .../initialize_teardown_aws_terraform.yml | 92 ++++++----- .../infrastructure/tasks/setup_terraform.yml | 6 - .../tasks/teardown_terraform.yml | 8 - .../tasks/validate_aws_terraform.yml | 4 - .../tasks/initialize_aws_terraform.yml | 146 ++++++++---------- .../initialize_teardown_aws_terraform.yml | 42 +++-- .../tasks/setup_aws_terraform_authz.yml | 5 - .../tasks/teardown_aws_terraform_authz.yml | 6 - .../platform/tasks/validate_aws_terraform.yml | 4 - 10 files changed, 179 insertions(+), 230 deletions(-) diff --git a/roles/infrastructure/tasks/initialize_aws_terraform.yml b/roles/infrastructure/tasks/initialize_aws_terraform.yml index 436e9027..21ec97b9 100644 --- a/roles/infrastructure/tasks/initialize_aws_terraform.yml +++ b/roles/infrastructure/tasks/initialize_aws_terraform.yml @@ -12,60 +12,58 @@ # See the License for the specific language governing permissions and # limitations under the License. -- name: Create terraform template .tf files - block: - - name: Create Terraform template dir - file: - path: "{{ infra__terraform_template_dir }}/infra" - state: directory +- name: Create directory for processed Terraform template files + ansible.builtin.file: + path: "{{ infra__terraform_template_dir }}/infra" + state: directory - - name: Create artefact directory for Terraform infra code - file: - path: "{{ infra__terraform_artefact_dir }}/infra" - state: directory +- name: Create artefact directory for Terraform infra code + ansible.builtin.file: + path: "{{ infra__terraform_artefact_dir }}/infra" + state: directory - # Apply template for Terraform provider - - name: Generate Terraform Provider - template: - src: 'template/{{ infra__type }}/provider.tf.j2' - dest: "{{ infra__terraform_template_dir }}/infra/provider.tf" +# Apply template for Terraform provider +- name: Generate Terraform Provider + ansible.builtin.template: + src: 'template/{{ infra__type }}/provider.tf.j2' + dest: "{{ infra__terraform_template_dir }}/infra/provider.tf" - # Apply template for Terraform backend state - - name: Generate Terraform Backend State - template: - src: 'template/{{ infra__type }}/backend_state.tf.j2' - dest: "{{ infra__terraform_template_dir }}/infra/backend_state.tf" +# Apply template for Terraform backend state +- name: Generate Terraform Backend State + ansible.builtin.template: + src: 'template/{{ infra__type }}/backend_state.tf.j2' + dest: "{{ infra__terraform_template_dir }}/infra/backend_state.tf" - # Apply template for Terraform variables - - name: Generate Terraform Variables - template: - src: 'template/{{ infra__type }}/terraform_variables.tf.j2' - dest: "{{ infra__terraform_template_dir }}/infra/variables.tf" - no_log: false +# Apply template for Terraform variables +- name: Generate Terraform Variables + ansible.builtin.template: + src: 'template/{{ infra__type }}/terraform_variables.tf.j2' + dest: "{{ infra__terraform_template_dir }}/infra/variables.tf" + no_log: false - # Apply template for Terraform infra.... - # ...network resources - - name: Generate Terraform infra file for network resources - template: - src: 'template/{{ infra__type }}/infra_{{ infra__type }}_network.tf.j2' - dest: "{{ infra__terraform_template_dir }}/infra/infra_network.tf" - no_log: false +# Apply template for Terraform infra.... +# ...network resources +- name: Generate Terraform infra file for network resources + ansible.builtin.template: + src: 'template/{{ infra__type }}/infra_{{ infra__type }}_network.tf.j2' + dest: "{{ infra__terraform_template_dir }}/infra/infra_network.tf" + no_log: false - # ...storage resources - - name: Generating Terraform infra file for storage resources - template: - src: 'template/{{ infra__type }}/infra_{{ infra__type }}_storage.tf.j2' - dest: "{{ infra__terraform_template_dir }}/infra/infra_storage.tf" - no_log: false +# ...storage resources +- name: Generating Terraform infra file for storage resources + ansible.builtin.template: + src: 'template/{{ infra__type }}/infra_{{ infra__type }}_storage.tf.j2' + dest: "{{ infra__terraform_template_dir }}/infra/infra_storage.tf" + no_log: false - # ...compute resources - - name: Generating Terraform infra file for compute resources - template: - src: 'template/{{ infra__type }}/infra_{{ infra__type }}_compute.tf.j2' - dest: "{{ infra__terraform_template_dir }}/infra/infra_compute.tf" - no_log: false +# ...compute resources +- name: Generating Terraform infra file for compute resources + ansible.builtin.template: + src: 'template/{{ infra__type }}/infra_{{ infra__type }}_compute.tf.j2' + dest: "{{ infra__terraform_template_dir }}/infra/infra_compute.tf" + no_log: false - - name: Prompt added by jenright - pause: - prompt: "Terraform infra files created in {{ infra__terraform_template_dir }}/infra" - when: debug_terraform | default(false) | bool \ No newline at end of file +- name: Prompt added by jenright + ansible.builtin.pause: + prompt: "Terraform infra files created in {{ infra__terraform_template_dir }}/infra" + when: debug_terraform | default(false) | bool \ No newline at end of file diff --git a/roles/infrastructure/tasks/initialize_teardown_aws_terraform.yml b/roles/infrastructure/tasks/initialize_teardown_aws_terraform.yml index 4fb052e3..5c57f362 100644 --- a/roles/infrastructure/tasks/initialize_teardown_aws_terraform.yml +++ b/roles/infrastructure/tasks/initialize_teardown_aws_terraform.yml @@ -12,57 +12,55 @@ # See the License for the specific language governing permissions and # limitations under the License. -- name: Create terraform template .tf files - block: - - name: Create terraform template dir - file: - path: "{{ infra__terraform_template_dir }}/infra" - state: directory +- name: Create directory for processed Terraform template files + ansible.builtin.file: + path: "{{ infra__terraform_template_dir }}/infra" + state: directory - # Apply template for Terraform provider - - name: Generate Terraform Provider - template: - src: 'template/{{ infra__type }}/provider.tf.j2' - dest: "{{ infra__terraform_template_dir }}/infra/provider.tf" +# Apply template for Terraform provider +- name: Generate Terraform Provider + ansible.builtin.template: + src: 'template/{{ infra__type }}/provider.tf.j2' + dest: "{{ infra__terraform_template_dir }}/infra/provider.tf" - # Apply template for Terraform backend state - - name: Generate Terraform Backend State - template: - src: 'template/{{ infra__type }}/backend_state.tf.j2' - dest: "{{ infra__terraform_template_dir }}/infra/backend_state.tf" +# Apply template for Terraform backend state +- name: Generate Terraform Backend State + ansible.builtin.template: + src: 'template/{{ infra__type }}/backend_state.tf.j2' + dest: "{{ infra__terraform_template_dir }}/infra/backend_state.tf" - # Apply template for Terraform variables - - name: Generate Terraform Variables - template: - src: 'template/{{ infra__type }}/terraform_variables.tf.j2' - dest: "{{ infra__terraform_template_dir }}/infra/variables.tf" - no_log: false +# Apply template for Terraform variables +- name: Generate Terraform Variables + ansible.builtin.template: + src: 'template/{{ infra__type }}/terraform_variables.tf.j2' + dest: "{{ infra__terraform_template_dir }}/infra/variables.tf" + no_log: false - # NOTE: These don't work because not all variables are defined during teardown - # ......ALSO they are not needed because we are working off the state file - # # Apply template for Terraform infra.... - # # ...network resources - # - name: Generate Terraform infra file for network resources - # template: - # src: 'template/{{ infra__type }}/infra_{{ infra__type }}_network.tf.j2' - # dest: "{{ infra__terraform_template_dir }}/infra/infra_network.tf" - # no_log: false +# NOTE: These don't work because not all variables are defined during teardown +# ......ALSO they are not needed because we are working off the state file +# # Apply template for Terraform infra.... +# # ...network resources +# - name: Generate Terraform infra file for network resources +# template: +# src: 'template/{{ infra__type }}/infra_{{ infra__type }}_network.tf.j2' +# dest: "{{ infra__terraform_template_dir }}/infra/infra_network.tf" +# no_log: false - # # ...storage resources - # - name: Generating Terraform infra file for storage resources - # template: - # src: 'template/{{ infra__type }}/infra_{{ infra__type }}_storage.tf.j2' - # dest: "{{ infra__terraform_template_dir }}/infra/infra_storage.tf" - # no_log: false +# # ...storage resources +# - name: Generating Terraform infra file for storage resources +# template: +# src: 'template/{{ infra__type }}/infra_{{ infra__type }}_storage.tf.j2' +# dest: "{{ infra__terraform_template_dir }}/infra/infra_storage.tf" +# no_log: false - # # ...compute resources - # - name: Generating Terraform infra file for compute resources - # template: - # src: 'template/{{ infra__type }}/infra_{{ infra__type }}_compute.tf.j2' - # dest: "{{ infra__terraform_template_dir }}/infra/infra_compute.tf" - # no_log: false +# # ...compute resources +# - name: Generating Terraform infra file for compute resources +# template: +# src: 'template/{{ infra__type }}/infra_{{ infra__type }}_compute.tf.j2' +# dest: "{{ infra__terraform_template_dir }}/infra/infra_compute.tf" +# no_log: false - - name: Prompt added by jenright - pause: - prompt: "Terraform infra files for Teardown created in {{ infra__terraform_template_dir }}/infra" - when: debug_terraform | default(false) | bool \ No newline at end of file +- name: Prompt added by jenright + ansible.builtin.pause: + prompt: "Terraform infra files for Teardown created in {{ infra__terraform_template_dir }}/infra" + when: debug_terraform | default(false) | bool diff --git a/roles/infrastructure/tasks/setup_terraform.yml b/roles/infrastructure/tasks/setup_terraform.yml index 2fdac2e8..5582d245 100644 --- a/roles/infrastructure/tasks/setup_terraform.yml +++ b/roles/infrastructure/tasks/setup_terraform.yml @@ -14,12 +14,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -- name: Confirm I got to setup_aws_terraform - ansible.builtin.debug: - msg: - - "I'm here doing to terraform apply" - - "Here's the workspace: {{ infra__terraform_workspace_dir }}" - - name: Check if Terraform workspace directory exists ansible.builtin.stat: path: "{{ infra__terraform_workspace_dir }}/workspace/infra" diff --git a/roles/infrastructure/tasks/teardown_terraform.yml b/roles/infrastructure/tasks/teardown_terraform.yml index 0b1a6ba5..25cf0c13 100644 --- a/roles/infrastructure/tasks/teardown_terraform.yml +++ b/roles/infrastructure/tasks/teardown_terraform.yml @@ -14,12 +14,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -- name: Confirm I got to teardown_terraform - ansible.builtin.debug: - msg: - - "I'm here doing to terraform destroy" - - "Here's the workspace: {{ infra__terraform_workspace_dir }}" - - name: Check if Terraform workspace directory exists ansible.builtin.stat: path: "{{ infra__terraform_workspace_dir }}/workspace/infra" @@ -38,8 +32,6 @@ - name: Destroy Terraform infra resources community.general.terraform: - # TODO: Fix workspace_dir_path - # project_path: "{{ infra__terraform_workspace_dir }}/{{ workspace_dir_path }}" project_path: "{{ infra__terraform_workspace_dir }}/workspace/infra" state: "absent" force_init: yes diff --git a/roles/infrastructure/tasks/validate_aws_terraform.yml b/roles/infrastructure/tasks/validate_aws_terraform.yml index ddd238db..ce190b81 100644 --- a/roles/infrastructure/tasks/validate_aws_terraform.yml +++ b/roles/infrastructure/tasks/validate_aws_terraform.yml @@ -54,7 +54,3 @@ fail_msg: "Required infra__terraform_state_storage variable for Terraform needs to be \ one of {{ infra__terraform_allowed_state_storage | join(', ') }}" quiet: yes - -- name: Print Executing Terraform message - ansible.builtin.debug: - msg: "Executing Terraform. Value of infra__deployment_engine = {{ infra__deployment_engine }}" \ No newline at end of file diff --git a/roles/platform/tasks/initialize_aws_terraform.yml b/roles/platform/tasks/initialize_aws_terraform.yml index 11d48187..dfaee166 100644 --- a/roles/platform/tasks/initialize_aws_terraform.yml +++ b/roles/platform/tasks/initialize_aws_terraform.yml @@ -14,93 +14,81 @@ # See the License for the specific language governing permissions and # limitations under the License. -- name: Create terraform template .tf files - block: - - name: Create Terraform template dir - file: - path: "{{ plat__terraform_template_dir }}/plat" - state: directory +- name: Create directory for processed Terraform template files + ansible.builtin.file: + path: "{{ plat__terraform_template_dir }}/plat" + state: directory - - name: Create artefact directory for Terraform infra code - file: - path: "{{ plat__terraform_artefact_dir }}/plat" - state: directory +- name: Create artefact directory for Terraform infra code + ansible.builtin.file: + path: "{{ plat__terraform_artefact_dir }}/plat" + state: directory - # Create and process the AWS Policy documents - - name: Create a temporary directory for policy documents - ansible.builtin.tempfile: - prefix: "aws-policy-" - state: directory - register: __aws_policy_tmpdir +# Create and process the AWS Policy documents +- name: Create a temporary directory for policy documents + ansible.builtin.tempfile: + prefix: "aws-policy-" + state: directory + register: __aws_policy_tmpdir - - name: Download AWS default policy documents - ansible.builtin.get_url: - dest: "{{ __aws_policy_tmpdir.path }}" - url: "{{ __policy_url_item.value }}" - loop_control: - loop_var: __policy_url_item - label: "{{ __policy_url_item.key }}" - loop: "{{ plat__aws_policy_urls | dict2items }}" - register: __aws_policy_documents +- name: Download AWS default policy documents + ansible.builtin.get_url: + dest: "{{ __aws_policy_tmpdir.path }}" + url: "{{ __policy_url_item.value }}" + loop_control: + loop_var: __policy_url_item + label: "{{ __policy_url_item.key }}" + loop: "{{ plat__aws_policy_urls | dict2items }}" + register: __aws_policy_documents - - name: JE Debug Print __aws_policy_tmpdir - ansible.builtin.debug: - var: __aws_policy_tmpdir +- name: Process AWS default policy documents + ansible.builtin.include_tasks: aws_policy_regex.yml + loop: "{{ __aws_policy_documents.results }}" + loop_control: + loop_var: __aws_policy_document_item + label: "{{ __aws_policy_document_item.__policy_url_item.key }}" - - name: Process AWS default policy documents - ansible.builtin.include_tasks: aws_policy_regex.yml - loop: "{{ __aws_policy_documents.results }}" - loop_control: - loop_var: __aws_policy_document_item - label: "{{ __aws_policy_document_item.__policy_url_item.key }}" +# Copy the AWS policy documents to plat__terraform_template_dir +- name: Copy AWS policy documents to Terraform template directory + ansible.builtin.copy: + src: "{{ __aws_policy_tmpdir.path }}/" + dest: "{{ plat__terraform_template_dir }}/plat/policy_docs/" - - name: Some variables for creation of IAM - ansible.builtin.debug: - msg: - - plat__aws_xaccount_account_policy = {{ plat__aws_xaccount_account_policy }} - - plat__aws_xaccount_policy_name = {{ plat__aws_xaccount_policy_name }} +# Apply template for Terraform provider +- name: Generate Terraform Provider + ansible.builtin.template: + src: 'template/{{ plat__infra_type }}/provider.tf.j2' + dest: "{{ plat__terraform_template_dir }}/plat/provider.tf" - # Copy the AWS policy documents to plat__terraform_template_dir - - name: Copy AWS policy documents to Terraform template directory - ansible.builtin.copy: - src: "{{ __aws_policy_tmpdir.path }}/" - dest: "{{ plat__terraform_template_dir }}/plat/policy_docs/" +# Apply template for Terraform backend state +- name: Generate Terraform Backend State + ansible.builtin.template: + src: 'template/{{ plat__infra_type }}/backend_state.tf.j2' + dest: "{{ plat__terraform_template_dir }}/plat/backend_state.tf" - # Apply template for Terraform provider - - name: Generate Terraform Provider - template: - src: 'template/{{ plat__infra_type }}/provider.tf.j2' - dest: "{{ plat__terraform_template_dir }}/plat/provider.tf" +# Apply template for Terraform variables +- name: Generate Terraform Variables + ansible.builtin.template: + src: 'template/{{ plat__infra_type }}/terraform_variables.tf.j2' + dest: "{{ plat__terraform_template_dir }}/plat/variables.tf" + no_log: false - # Apply template for Terraform backend state - - name: Generate Terraform Backend State - template: - src: 'template/{{ plat__infra_type }}/backend_state.tf.j2' - dest: "{{ plat__terraform_template_dir }}/plat/backend_state.tf" +# Apply template for Terraform auth resources.... +# ...policies +- name: Generate Terraform authz file for policies + ansible.builtin.template: + src: 'template/{{ plat__infra_type }}/plat_{{ plat__infra_type }}_authz_policies.tf.j2' + dest: "{{ plat__terraform_template_dir }}/plat/plat_authz_policies.tf" + no_log: false - # Apply template for Terraform variables - - name: Generate Terraform Variables - template: - src: 'template/{{ plat__infra_type }}/terraform_variables.tf.j2' - dest: "{{ plat__terraform_template_dir }}/plat/variables.tf" - no_log: false +# ...roles +- name: Generate Terraform authz file for roles + ansible.builtin.template: + src: 'template/{{ plat__infra_type }}/plat_{{ plat__infra_type }}_authz_roles.tf.j2' + dest: "{{ plat__terraform_template_dir }}/plat/plat_authz_roles.tf" + no_log: false - # Apply template for Terraform auth resources.... - # ...policies - - name: Generate Terraform authz file for policies - ansible.builtin.template: - src: 'template/{{ plat__infra_type }}/plat_{{ plat__infra_type }}_authz_policies.tf.j2' - dest: "{{ plat__terraform_template_dir }}/plat/plat_authz_policies.tf" - no_log: false - - # ...roles - - name: Generate Terraform authz file for roles - ansible.builtin.template: - src: 'template/{{ plat__infra_type }}/plat_{{ plat__infra_type }}_authz_roles.tf.j2' - dest: "{{ plat__terraform_template_dir }}/plat/plat_authz_roles.tf" - no_log: false - - - name: Prompt added by jenright - pause: - prompt: "PART 1 - Terraform role & policy files created in {{ plat__terraform_template_dir }}/plat" - when: debug_terraform | default(false) | bool +- name: Prompt added by jenright + ansible.builtin.pause: + prompt: "PART 1 - Terraform role & policy files created in {{ plat__terraform_template_dir }}/plat" + when: debug_terraform | default(false) | bool diff --git a/roles/platform/tasks/initialize_teardown_aws_terraform.yml b/roles/platform/tasks/initialize_teardown_aws_terraform.yml index 3ca75ad2..f62badb0 100644 --- a/roles/platform/tasks/initialize_teardown_aws_terraform.yml +++ b/roles/platform/tasks/initialize_teardown_aws_terraform.yml @@ -12,31 +12,29 @@ # See the License for the specific language governing permissions and # limitations under the License. -- name: Create terraform template .tf files - block: - - name: Create terraform template dir - ansible.builtin.file: - path: "{{ plat__terraform_template_dir }}/plat" - state: directory +- name: Create directory for processed Terraform template files + ansible.builtin.file: + path: "{{ plat__terraform_template_dir }}/plat" + state: directory - # Apply template for Terraform provider - - name: Generate Terraform Provider - ansible.builtin.template: - src: 'template/{{ plat__infra_type }}/provider.tf.j2' - dest: "{{ plat__terraform_template_dir }}/plat/provider.tf" +# Apply template for Terraform provider +- name: Generate Terraform Provider + ansible.builtin.template: + src: 'template/{{ plat__infra_type }}/provider.tf.j2' + dest: "{{ plat__terraform_template_dir }}/plat/provider.tf" - # Apply template for Terraform backend state - - name: Generate Terraform Backend State - ansible.builtin.template: - src: 'template/{{ plat__infra_type }}/backend_state.tf.j2' - dest: "{{ plat__terraform_template_dir }}/plat/backend_state.tf" +# Apply template for Terraform backend state +- name: Generate Terraform Backend State + ansible.builtin.template: + src: 'template/{{ plat__infra_type }}/backend_state.tf.j2' + dest: "{{ plat__terraform_template_dir }}/plat/backend_state.tf" - # Apply template for Terraform variables - - name: Generate Terraform Variables - ansible.builtin.template: - src: 'template/{{ plat__infra_type }}/terraform_variables.tf.j2' - dest: "{{ plat__terraform_template_dir }}/plat/variables.tf" - no_log: false +# Apply template for Terraform variables +- name: Generate Terraform Variables + ansible.builtin.template: + src: 'template/{{ plat__infra_type }}/terraform_variables.tf.j2' + dest: "{{ plat__terraform_template_dir }}/plat/variables.tf" + no_log: false - name: Create a temporary directory for policy documents ansible.builtin.tempfile: diff --git a/roles/platform/tasks/setup_aws_terraform_authz.yml b/roles/platform/tasks/setup_aws_terraform_authz.yml index 5ed2b499..9cb17164 100644 --- a/roles/platform/tasks/setup_aws_terraform_authz.yml +++ b/roles/platform/tasks/setup_aws_terraform_authz.yml @@ -70,11 +70,6 @@ region: "{{ plat__region }}" register: __aws_xaccount_role_info -- name: Print details of AWS cross account role - debug: - msg: - - Cross account role "{{ __aws_xaccount_role_info }}" - - name: Create CDP Cross Account Credential for AWS when: plat__xacccount_credential_name not in plat__cdp_credentials_list cloudera.cloud.env_cred: diff --git a/roles/platform/tasks/teardown_aws_terraform_authz.yml b/roles/platform/tasks/teardown_aws_terraform_authz.yml index 711bde5a..d67e5169 100644 --- a/roles/platform/tasks/teardown_aws_terraform_authz.yml +++ b/roles/platform/tasks/teardown_aws_terraform_authz.yml @@ -20,12 +20,6 @@ name: "{{ plat__xacccount_credential_name }}" # TODO: Make specific to AWS Teardown as credentials can be for multiple environments state: absent -- name: Confirm I got to setup_aws_terraform - ansible.builtin.debug: - msg: - - "I'm here doing to terraform destroy" - - "Here's the workspace: {{ plat__terraform_workspace_dir }}" - - name: Check if Terraform workspace directory exists ansible.builtin.stat: path: "{{ plat__terraform_template_dir }}/workspace/plat" diff --git a/roles/platform/tasks/validate_aws_terraform.yml b/roles/platform/tasks/validate_aws_terraform.yml index ae74f9a8..3064b319 100644 --- a/roles/platform/tasks/validate_aws_terraform.yml +++ b/roles/platform/tasks/validate_aws_terraform.yml @@ -52,7 +52,3 @@ fail_msg: "Required plat__terraform_state_storage variable for Terraform needs to be \ one of {{ plat__terraform_allowed_state_storage | join(', ') }}" quiet: yes - -- name: Print Executing Terraform message - ansible.builtin.debug: - msg: "Executing Terraform. Value of plat__infra_deployment_engine = {{ plat__infra_deployment_engine }}" From 78c76fab18880c4886cae23b035c5d159fc4e156 Mon Sep 17 00:00:00 2001 From: Jim Enright Date: Fri, 1 Oct 2021 09:54:37 +0100 Subject: [PATCH 18/33] Update Terraform infra templates for L0, L1 and L2 changes Signed-off-by: Jim Enright --- roles/common/defaults/main.yml | 2 +- .../template/aws/infra_aws_network.tf.j2 | 106 +++++++++++++++--- 2 files changed, 91 insertions(+), 17 deletions(-) diff --git a/roles/common/defaults/main.yml b/roles/common/defaults/main.yml index 0b3d50cd..21ef8b86 100644 --- a/roles/common/defaults/main.yml +++ b/roles/common/defaults/main.yml @@ -69,7 +69,7 @@ common__storage_name: "{{ infra.storage.name | default([comm # Terraform # The processed Jinja template files for Terraform are placed in common__terraform_template_dir -common__terraform_template_dir: "{{ globals.terraform_template_dir | default( playbook_dir , './terraform_processed_template_code') | path_join }}" +common__terraform_template_dir: "{{ globals.terraform_template_dir | default( ( playbook_dir , 'terraform_processed_template_code') | path_join ) }}" # A timestamped artefact directory storing a copy of the Terraform code from each run common__terraform_artefact_dir: "{{ [ common__terraform_template_dir , ('tf_artefacts_' + ansible_date_time.iso8601 ) ] | path_join | regex_replace(':','_')}}" diff --git a/roles/infrastructure/template/aws/infra_aws_network.tf.j2 b/roles/infrastructure/template/aws/infra_aws_network.tf.j2 index e5880c01..0e442ca9 100644 --- a/roles/infrastructure/template/aws/infra_aws_network.tf.j2 +++ b/roles/infrastructure/template/aws/infra_aws_network.tf.j2 @@ -9,27 +9,28 @@ resource "aws_vpc" "{{ infra__vpc_name }}" { #enable_dns_hostnames = "aws.vpc.vpc_enable_dns_hostnames" } -# ------- Internet Gateway ------- -# NOTE: In EDU code there's a loop over internet_gateways +{# *** START Create AWS Public Network infrastructure ****#} +{% if infra__aws_subnet_ids is not defined %} +# ------- AWS Public Network infrastructure ------- +# Internet Gateway resource "aws_internet_gateway" "{{ infra__aws_igw_name }}" { vpc_id = aws_vpc.{{ infra__vpc_name }}.id tags = merge(var.env_tags,{Name = "{{ infra__aws_igw_name }}"}) } -# ------- VPC Subnets ------- -{% for __aws_subnet_cidr_item in infra__vpc_public_subnet_cidrs | union(infra__vpc_private_subnet_cidrs) %} -resource "aws_subnet" "{{ infra__namespace }}_subnet{{ loop.index }}" { +# AWS VPC Public Subnets +{% for __aws_public_subnet_item in infra__vpc_public_subnets_info %} +resource "aws_subnet" "{{ __aws_public_subnet_item.name }}" { vpc_id = aws_vpc.{{ infra__vpc_name }}.id - cidr_block = "{{ __aws_subnet_cidr_item }}" + cidr_block = "{{ __aws_public_subnet_item.cidr }}" map_public_ip_on_launch = true availability_zone = "{{ __aws_az_info.availability_zones[loop.index0 % infra__aws_vpc_az_count | int].zone_name }}" - tags = merge(var.env_tags,{Name = "{{ infra__namespace }}"}) + tags = merge(var.env_tags,{% for key, value in __aws_public_subnet_item.tags.items() %}{ "{{ key }}" = "{{ value }}" },{% endfor %}) } {% endfor %} -# ------- Route Table ------- -# NOTE: In EDU code a new route table is created; in Ansible main is reused & updated. -resource "aws_default_route_table" "{{ infra__aws_route_table_name }}" { +# Public Route Table +resource "aws_default_route_table" "{{ infra__aws_public_route_table_name }}" { default_route_table_id = aws_vpc.{{ infra__vpc_name }}.default_route_table_id route { @@ -37,18 +38,89 @@ resource "aws_default_route_table" "{{ infra__aws_route_table_name }}" { gateway_id = aws_internet_gateway.{{ infra__aws_igw_name }}.id } + tags = merge(var.env_tags,{Name = "{{ infra__aws_public_route_table_name }}"}) - tags = merge(var.env_tags,{Name = "{{ infra__aws_route_table_name }}"}) } -# Associate the Route Table with the Subnet -{% for subnet in infra__vpc_public_subnet_cidrs | union(infra__vpc_private_subnet_cidrs) %} -resource "aws_route_table_association" "{{ infra__namespace }}_subnet{{ loop.index }}-association" { - subnet_id = aws_subnet.{{ infra__namespace }}_subnet{{ loop.index }}.id +# Associate the Public Route Table with the Public Subnets +{% for __aws_public_subnet_item in infra__vpc_public_subnets_info %} +resource "aws_route_table_association" "{{ __aws_public_subnet_item.name }}-association" { + subnet_id = aws_subnet.{{ __aws_public_subnet_item.name }}.id route_table_id = aws_vpc.{{ infra__vpc_name }}.default_route_table_id } {% endfor %} +{% endif %} +{# *** END Create AWS Public Network infrastructure ****#} + + +{# *** START Create AWS Private Network infrastructure ****#} +{% if ( infra__tunnel ) and ( infra__aws_subnet_ids is not defined ) %} + +# ------- AWS Private Networking infrastructure ------- +# TODO: Conditional when: infra__tunnel and infra__aws_subnet_ids is undefined + +# AWS VPC Private Subnets +{% for __aws_private_subnet_item in infra__vpc_private_subnets_info %} +resource "aws_subnet" "{{ __aws_private_subnet_item.name }}" { + vpc_id = aws_vpc.{{ infra__vpc_name }}.id + cidr_block = "{{ __aws_private_subnet_item.cidr }}" + map_public_ip_on_launch = true + availability_zone = "{{ __aws_az_info.availability_zones[loop.index0 % infra__aws_vpc_az_count | int].zone_name }}" + tags = merge(var.env_tags,{% for key, value in __aws_private_subnet_item.tags.items() %}{ "{{ key }}" = "{{ value }}" },{% endfor %}) +} +{% endfor %} + +# Private Route Table for the AWS VPC +# - Not implemeted in Terraform because of "when: no" in Ansible + +# Elastic IP for each NAT gateway +{% for __aws_public_subnet_item in infra__vpc_public_subnets_info %} +resource "aws_eip" "{{ infra__aws_nat_gateway_name }}-eip-{{ loop.index0 }}" { + vpc = true + + tags = var.env_tags +} +{% endfor %} + +# Network Gateways (NAT) +{% for __aws_public_subnet_item in infra__vpc_public_subnets_info %} +resource "aws_nat_gateway" "{{ infra__aws_nat_gateway_name }}-{{ loop.index0 }}" { + + subnet_id = aws_subnet.{{ __aws_public_subnet_item.name }}.id + allocation_id = aws_eip.{{ infra__aws_nat_gateway_name }}-eip-{{ loop.index0 }}.id + connectivity_type = "public" + + tags = merge(var.env_tags,{Name = "{{ '-'.join([infra__aws_nat_gateway_name, loop.index0 | string ]) }}"}) +} +{% endfor %} + +# Private Route Tables +{% for __aws_private_subnet_item in infra__vpc_private_subnets_info %} +resource "aws_route_table" "{{ infra__aws_private_route_table_name }}-{{ loop.index0 }}" { + vpc_id = aws_vpc.{{ infra__vpc_name }}.id + + tags = merge(var.env_tags,{Name = "{{ '-'.join([infra__aws_private_route_table_name, loop.index0 | string ]) }}"}) + + route { + cidr_block = "0.0.0.0/0" + nat_gateway_id = aws_nat_gateway.{{ infra__aws_nat_gateway_name }}-{{ loop.index0 % infra__vpc_public_subnets_info | length }}.id + } + +} +{% endfor %} + +# Associate the Private Route Tables with the Private Subnets +{% for __aws_private_subnet_item in infra__vpc_private_subnets_info %} +resource "aws_route_table_association" "{{ infra__aws_private_route_table_name }}-{{ loop.index0 }}-association" { + subnet_id = aws_subnet.{{ __aws_private_subnet_item.name }}.id + route_table_id = aws_route_table.{{ infra__aws_private_route_table_name }}-{{ loop.index0 }}.id +} +{% endfor %} + +{% endif %} +{# *** END Create AWS PRIVATE Network infrastructure ****#} + # ------- Security Groups ------- {% set __security_group_names = [infra__security_group_knox_name, infra__security_group_default_name] %} @@ -56,6 +128,9 @@ resource "aws_route_table_association" "{{ infra__namespace }}_subnet{{ loop.ind resource "aws_security_group" "{{ __security_group_name_item }}" { vpc_id = aws_vpc.{{ infra__vpc_name }}.id name = "{{ __security_group_name_item }}" + description = "{{ __security_group_name_item }}" + + tags = merge(var.env_tags,{Name = "{{ __security_group_name_item }}"}) # Create self reference ingress rule to allow # communication among resources in the security group. @@ -158,6 +233,5 @@ resource "aws_security_group" "{{ __security_group_name_item }}" { protocol = "all" } - tags = merge(var.env_tags,{Name = "{{ __security_group_name_item }}"}) } {% endfor %} From a55260a47377edda6649545521f15350f7d51340 Mon Sep 17 00:00:00 2001 From: Jim Enright Date: Fri, 1 Oct 2021 09:54:37 +0100 Subject: [PATCH 19/33] Update Terraform infra templates for L0, L1 and L2 changes Signed-off-by: Jim Enright --- .../template/aws/infra_aws_compute.tf.j2 | 62 +++++++++---------- .../template/aws/infra_aws_storage.tf.j2 | 10 +-- 2 files changed, 36 insertions(+), 36 deletions(-) diff --git a/roles/infrastructure/template/aws/infra_aws_compute.tf.j2 b/roles/infrastructure/template/aws/infra_aws_compute.tf.j2 index dab875ae..9496a195 100644 --- a/roles/infrastructure/template/aws/infra_aws_compute.tf.j2 +++ b/roles/infrastructure/template/aws/infra_aws_compute.tf.j2 @@ -1,63 +1,63 @@ +{# *** Set the __aws_subnets to use for the aws_instance subnet_id parameter ****#} +{% if not infra__tunnel %} +{% set __aws_subnets = (__aws_subnets | default([])) | union(infra__vpc_public_subnets_info) %} +{% endif %} + +{% if ( infra__tunnel ) and ( infra__aws_subnet_ids is not defined ) %} +{% set __aws_subnets = (__aws_subnets | default([])) | union(infra__vpc_public_subnets_info) | union(infra__vpc_private_subnets_info)%} +{% endif %} + # ------- Dynamic Inventory VMs ------- {% for __infra_compute_instance_item in range(0, infra__dynamic_inventory_count | int ) | list %} resource "aws_instance" "{{ '-'.join([infra__namespace, infra__dynamic_inventory_vm_suffix, '%02d' | format(__infra_compute_instance_item)]) }}" { - # NOTE: Security group...taken directly from infra__security_group_default_name variable rather than infra__aws_security_group_default_id fact vpc_security_group_ids = [aws_security_group.{{ infra__security_group_default_name }}.id] - # DONE: key pair key_name = "{{ infra__public_key_id }}" - # DONE: instance type instance_type = "{{ infra__dynamic_inventory_vm_type_default[infra__type][infra__dynamic_inventory_vm_type] }}" - # DONE: image ami = "{{ __infra_aws_ami_info.image_id }}" - # DONE: EBS ebs_optimized ebs_optimized = true - # NOTE: VPC vpc_subnet_id....direct - # subnet_id = aws_subnet.{{ infra__vpc_public_subnet_cidrs | union(infra__vpc_private_subnet_cidrs) | first }}.id - subnet_id = aws_subnet.{{ infra__namespace }}_subnet1.id - # DONE: Public IP - associate_public_ip_address = true - # DONE: Tag - {# to_json is used to convert single quotes around IP to double #} - tags = merge({{ infra__dynamic_inventory_tags | to_json }},{Name = "{{ '-'.join([infra__namespace, infra__dynamic_inventory_vm_suffix, '%02d' | format(__infra_compute_instance_item)]) }}"}) - # TODO: Volume / root_block_device + + # Volume / root_block_device root_block_device { - # NOTE: Need to cast from string (yes) to bool, option 1 + # Need to cast from string (yes) to bool delete_on_termination = {{ infra__dynamic_inventory_delete_storage | bool | lower }} - # NOTE: Need to cast from string (yes) to bool, option 2 - # delete_on_termination = {{ true if infra__dynamic_inventory_delete_storage in ['yes', 1, "True", "true"] else false }} volume_size = "{{ infra__dynamic_inventory_storage_size }}" volume_type = "{{ infra__dynamic_inventory_storage_type_default[infra__type][infra__dynamic_inventory_storage_type] }}" } + + subnet_id = aws_subnet.{{ __aws_subnets | map(attribute='name') | first }}.id + + associate_public_ip_address = true + + {# to_json is used to convert single quotes around IP to double #} + tags = merge({{ infra__dynamic_inventory_tags | to_json }},{Name = "{{ '-'.join([infra__namespace, infra__dynamic_inventory_vm_suffix, '%02d' | format(__infra_compute_instance_item)]) }}"}) + } {% endfor %} {% if infra__create_utility_service %} # ------- Localised Utility VM Instance ------- resource "aws_instance" "{{ '-'.join([infra__namespace, infra__region, 'utility_vm' ]) }}" { - # NOTE: Security group...taken directly from infra__security_group_default_name variable rather than infra__aws_security_group_default_id fact vpc_security_group_ids = [aws_security_group.{{ infra__security_group_default_name }}.id] - # DONE: key pair key_name = "{{ infra__public_key_id }}" - # DONE: instance type instance_type = "{{ infra__dynamic_inventory_vm_type_default[infra__type]['sml'] }}" - # DONE: image ami = "{{ __infra_aws_ami_info.image_id }}" - # DONE: EBS ebs_optimized ebs_optimized = true - # NOTE: VPC vpc_subnet_id....direct - subnet_id = aws_subnet.{{ infra__namespace }}_subnet1.id - # DONE: Public IP - associate_public_ip_address = true - # DONE: Tag - {# to_json is used to convert single quotes around IP to double #} - tags = merge({{ infra__dynamic_inventory_tags | to_json }},{Name = "{{ '-'.join([infra__namespace, infra_region, 'utility_vm' ]) }}"}) - # TODO: Volume / root_block_device + # Volume / root_block_device root_block_device { - # NOTE: Need to cast from string (yes) to bool, option 1 + # Need to cast from string (yes) to bool delete_on_termination = {{ infra__dynamic_inventory_delete_storage | bool | lower }} volume_size = 100 volume_type = "{{ infra__dynamic_inventory_storage_type_default[infra__type]['std'] }}" } + + subnet_id = aws_subnet.{{ __aws_subnets | map(attribute='name') | first }}.id + + associate_public_ip_address = true + + {# to_json is used to convert single quotes around IP to double #} + tags = merge({{ infra__dynamic_inventory_tags | to_json }},{Name = "{{ '-'.join([infra__namespace, infra_region, 'utility_vm' ]) }}"}) } + +TODO: Need to add Utility Instance to host group {% endif %} \ No newline at end of file diff --git a/roles/infrastructure/template/aws/infra_aws_storage.tf.j2 b/roles/infrastructure/template/aws/infra_aws_storage.tf.j2 index 900977d5..a1318ed6 100644 --- a/roles/infrastructure/template/aws/infra_aws_storage.tf.j2 +++ b/roles/infrastructure/template/aws/infra_aws_storage.tf.j2 @@ -2,11 +2,11 @@ # Get unique list of buckets from infra__aws_storage_locations {% for __aws_storage_location_item in ( infra__aws_storage_locations | map(attribute='bucket') | list | unique ) %} resource "aws_s3_bucket" "{{ __aws_storage_location_item }}" { - bucket = "{{ __aws_storage_location_item }}" - acl = "private" + bucket = "{{ __aws_storage_location_item }}" + acl = "private" force_destroy = true - tags = merge(var.env_tags,{Name = "{{ __aws_storage_location_item }}"}) + tags = merge(var.env_tags,{Name = "{{ __aws_storage_location_item }}"}) } {% endfor %} @@ -15,8 +15,8 @@ resource "aws_s3_bucket" "{{ __aws_storage_location_item }}" { {# Terraform resources cannot have '/' so replace with '_' #} {% set __aws_storage_object_resource = __aws_storage_object_item.path |replace("/", "_") %} -resource "aws_s3_bucket_object" "{{ __aws_storage_object_resource}}" { - bucket = aws_s3_bucket.{{ __aws_storage_object_item.bucket}}.id +resource "aws_s3_bucket_object" "{{ __aws_storage_object_resource }}" { + bucket = aws_s3_bucket.{{ __aws_storage_object_item.bucket }}.id key = "{{ __aws_storage_object_item.path }}/" # Below may not be required once we have the '/' content_type = "application/x-directory" From 43f3809c42b31a590bf1a4f7cd08426756291ab5 Mon Sep 17 00:00:00 2001 From: Jim Enright Date: Fri, 1 Oct 2021 09:54:38 +0100 Subject: [PATCH 20/33] Remove AWS DynamoDB reference from Terraform templates Signed-off-by: Jim Enright --- .../aws/plat_aws_authz_policies.tf.j2 | 10 ------- .../template/aws/plat_aws_authz_roles.tf.j2 | 30 ++++--------------- 2 files changed, 6 insertions(+), 34 deletions(-) diff --git a/roles/platform/template/aws/plat_aws_authz_policies.tf.j2 b/roles/platform/template/aws/plat_aws_authz_policies.tf.j2 index 24e1b3a2..aa4df84f 100644 --- a/roles/platform/template/aws/plat_aws_authz_policies.tf.j2 +++ b/roles/platform/template/aws/plat_aws_authz_policies.tf.j2 @@ -73,13 +73,3 @@ resource "aws_iam_policy" "{{ plat__aws_bucket_access_policy_name }}" { policy = file("{{ "./policy_docs/" ~ (__aws_policy_documents | json_query("results[?__policy_url_item.key==`bucket_access`].dest | [0]") | basename) }}") } - -# ------- CDP Data Access Policies - dynamodb ------- -resource "aws_iam_policy" "{{ plat__aws_dynamodb_policy_name }}" { - name = "{{ plat__aws_dynamodb_policy_name }}" - description = "AWS DynamoDB Table Access policy for {{ plat__namespace }}" - - tags = merge(var.env_tags,{Name = "{{ plat__aws_dynamodb_policy_name }}"}) - - policy = file("{{ "./policy_docs/" ~ (__aws_policy_documents | json_query("results[?__policy_url_item.key==`dynamodb`].dest | [0]") | basename) }}") -} diff --git a/roles/platform/template/aws/plat_aws_authz_roles.tf.j2 b/roles/platform/template/aws/plat_aws_authz_roles.tf.j2 index 23b04804..0c54a351 100644 --- a/roles/platform/template/aws/plat_aws_authz_roles.tf.j2 +++ b/roles/platform/template/aws/plat_aws_authz_roles.tf.j2 @@ -107,22 +107,14 @@ resource "aws_iam_instance_profile" "{{ plat__aws_log_role_name }}-instance-prof role = aws_iam_role.{{ plat__aws_log_role_name }}.name } -# Attach CDP IDBroker Assume Policy to the Role -# resource "aws_iam_role_policy_attachment" "{{ plat__aws_log_role_name }}-attach" { - -# # Use for_each to create multiple resources -# for_each = toset( [aws_iam_policy.{{ plat__aws_log_location_policy_name }}.arn, aws_iam_policy.{{ plat__aws_bucket_access_policy_name }}.arn] ) - -# role = aws_iam_role.{{ plat__aws_log_role_name }}.name -# policy_arn = each.value -# } - +# Attach AWS Log Location Policy to the Role resource "aws_iam_role_policy_attachment" "{{ plat__aws_log_role_name }}-attach1" { role = aws_iam_role.{{ plat__aws_log_role_name }}.name policy_arn = aws_iam_policy.{{ plat__aws_log_location_policy_name }}.arn } +# Attach AWS Buckey Access Policy to the Role resource "aws_iam_role_policy_attachment" "{{ plat__aws_log_role_name }}-attach2" { role = aws_iam_role.{{ plat__aws_log_role_name }}.name @@ -161,25 +153,20 @@ resource "aws_iam_instance_profile" "{{ plat__aws_datalake_admin_role_name }}-in role = aws_iam_role.{{ plat__aws_datalake_admin_role_name }}.name } -# Attach CDP IDBroker Assume Policy to the Role +# Attach AWS Datalake Admin S3 Policy to the Role resource "aws_iam_role_policy_attachment" "{{ plat__aws_datalake_admin_role_name }}-attach1" { role = aws_iam_role.{{ plat__aws_datalake_admin_role_name }}.name policy_arn = aws_iam_policy.{{ plat__aws_datalake_admin_s3_policy_name }}.arn } +# Attach AWS Bucket Access Policy to the Role resource "aws_iam_role_policy_attachment" "{{ plat__aws_datalake_admin_role_name }}-attach2" { role = aws_iam_role.{{ plat__aws_datalake_admin_role_name }}.name policy_arn = aws_iam_policy.{{ plat__aws_bucket_access_policy_name }}.arn } -resource "aws_iam_role_policy_attachment" "{{ plat__aws_datalake_admin_role_name }}-attach3" { - - role = aws_iam_role.{{ plat__aws_datalake_admin_role_name }}.name - policy_arn = aws_iam_policy.{{ plat__aws_dynamodb_policy_name }}.arn -} - # ------- AWS Data Access Roles - CDP Ranger Audit ------- # First create the Assume role policy document data "aws_iam_policy_document" "{{ plat__aws_ranger_audit_role_name }}-policy-doc" { @@ -212,21 +199,16 @@ resource "aws_iam_instance_profile" "{{ plat__aws_ranger_audit_role_name }}-inst role = aws_iam_role.{{ plat__aws_ranger_audit_role_name }}.name } -# Attach CDP IDBroker Assume Policy to the Role +# Attach AWS Ranger Audit S3 Policy to the Role resource "aws_iam_role_policy_attachment" "{{ plat__aws_ranger_audit_role_name }}-attach1" { role = aws_iam_role.{{ plat__aws_ranger_audit_role_name }}.name policy_arn = aws_iam_policy.{{ plat__aws_ranger_audit_s3_policy_name }}.arn } +# Attach AWS Bucket Access Policy to the Role resource "aws_iam_role_policy_attachment" "{{ plat__aws_ranger_audit_role_name }}-attach2" { role = aws_iam_role.{{ plat__aws_ranger_audit_role_name }}.name policy_arn = aws_iam_policy.{{ plat__aws_bucket_access_policy_name }}.arn } - -resource "aws_iam_role_policy_attachment" "{{ plat__aws_ranger_audit_role_name }}-attach3" { - - role = aws_iam_role.{{ plat__aws_ranger_audit_role_name }}.name - policy_arn = aws_iam_policy.{{ plat__aws_dynamodb_policy_name }}.arn -} From 275ad9fa50e07bf44d19529b754dbc257ae28d9d Mon Sep 17 00:00:00 2001 From: Jim Enright Date: Fri, 1 Oct 2021 09:54:38 +0100 Subject: [PATCH 21/33] Correct AWS CDP IDBroker role's policy definitions for Terraform templates Signed-off-by: Jim Enright --- roles/platform/template/aws/plat_aws_authz_roles.tf.j2 | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/roles/platform/template/aws/plat_aws_authz_roles.tf.j2 b/roles/platform/template/aws/plat_aws_authz_roles.tf.j2 index 0c54a351..92de0aa6 100644 --- a/roles/platform/template/aws/plat_aws_authz_roles.tf.j2 +++ b/roles/platform/template/aws/plat_aws_authz_roles.tf.j2 @@ -70,11 +70,18 @@ resource "aws_iam_instance_profile" "{{ plat__aws_idbroker_role_name }}-instance } # Attach CDP IDBroker Assume Policy to the Role -resource "aws_iam_role_policy_attachment" "{{ plat__aws_idbroker_role_name }}-attach" { +resource "aws_iam_role_policy_attachment" "{{ plat__aws_idbroker_role_name }}-attach1" { role = aws_iam_role.{{ plat__aws_idbroker_role_name }}.name policy_arn = aws_iam_policy.{{ plat__aws_idbroker_policy_name }}.arn } +# Attach AWS Log Location Policy to the Role +resource "aws_iam_role_policy_attachment" "{{ plat__aws_idbroker_role_name }}-attach2" { + + role = aws_iam_role.{{ plat__aws_idbroker_role_name }}.name + policy_arn = aws_iam_policy.{{ plat__aws_log_location_policy_name }}.arn +} + # ------- AWS Service Roles - CDP Log ------- # First create the Assume role policy document data "aws_iam_policy_document" "{{ plat__aws_log_role_name }}-policy-doc" { From efc4739900d9fbfceb387de9872191f2c0d06ad4 Mon Sep 17 00:00:00 2001 From: Jim Enright Date: Fri, 1 Oct 2021 09:54:39 +0100 Subject: [PATCH 22/33] Update Terraform platform for L0, L1 and L2 changes Signed-off-by: Jim Enright --- roles/infrastructure/tasks/setup.yml | 3 +++ roles/platform/tasks/initialize_setup_aws.yml | 1 + 2 files changed, 4 insertions(+) diff --git a/roles/infrastructure/tasks/setup.yml b/roles/infrastructure/tasks/setup.yml index c97462f1..055caa41 100644 --- a/roles/infrastructure/tasks/setup.yml +++ b/roles/infrastructure/tasks/setup.yml @@ -16,6 +16,9 @@ # tasks file for setup +- name: Set up provider-specific Infrastructure artifacts + ansible.builtin.include_tasks: "setup_{{ infra__type | lower }}.yml" + - name: Set up for Ansible deployment engine when: infra__deployment_engine == 'ansible' block: diff --git a/roles/platform/tasks/initialize_setup_aws.yml b/roles/platform/tasks/initialize_setup_aws.yml index 9f4b6112..785e6a9a 100644 --- a/roles/platform/tasks/initialize_setup_aws.yml +++ b/roles/platform/tasks/initialize_setup_aws.yml @@ -78,6 +78,7 @@ - name: Handle AWS Public and Private VPC Subnets if not defined when: not plat__aws_public_subnet_ids or not plat__aws_private_subnet_ids block: + # Search using a wildcard on the subnet Name tag {{ plat__namespace }}* - name: Query AWS Subnets amazon.aws.ec2_vpc_subnet_info: region: "{{ plat__region }}" From 35cdc5d57f4b184835b321bd7d61b33efcb12d7b Mon Sep 17 00:00:00 2001 From: Jim Enright Date: Fri, 1 Oct 2021 09:54:39 +0100 Subject: [PATCH 23/33] Update Terraform platform for L0, L1 and L2 changes Signed-off-by: Jim Enright --- roles/platform/tasks/setup_aws_env.yml | 45 +++++++++++++++----------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/roles/platform/tasks/setup_aws_env.yml b/roles/platform/tasks/setup_aws_env.yml index 3727e7a1..d3ef83b8 100644 --- a/roles/platform/tasks/setup_aws_env.yml +++ b/roles/platform/tasks/setup_aws_env.yml @@ -14,24 +14,33 @@ # See the License for the specific language governing permissions and # limitations under the License. -# - name: Debug variables with Terraform -# debug: -# msg: -# - "name: {{ plat__env_name }}" -# - "state: started" -# - "credential: {{ plat__xacccount_credential_name }}" -# - "cloud: {{ plat__infra_type }}" -# - "region: {{ plat__region }}" -# - "default_sg: {{ plat__aws_security_group_default_id }}" -# - "knox_sg: {{ plat__aws_security_group_knox_id }}" -# - "log_location: {{ plat__aws_storage_location }}" -# - "log_identity: {{ plat__aws_log_instance_profile_arn }}" -# - "public_key_id: {{ plat__public_key_id }}" -# - "workload_analytics: {{ plat__workload_analytics }}" -# - "vpc_id: {{ plat__aws_vpc_id }}" -# - "subnet_ids: {{ plat__aws_subnet_ids }}" -# - "s3_guard_name: {{ plat__aws_dynamodb_table_name }}" -# - "tags: {{ plat__tags }}" +- name: Debug variables with Terraform + debug: + msg: + - "name: {{ plat__env_name }}" + - "state: started" + - "credential: {{ plat__xacccount_credential_name }}" + - "cloud: {{ plat__infra_type }}" + - "region: {{ plat__region }}" + - "default_sg: {{ plat__aws_security_group_default_id }}" + - "knox_sg: {{ plat__aws_security_group_knox_id }}" + - "log_location: {{ plat__aws_storage_location }}" + - "log_identity: {{ plat__aws_log_instance_profile_arn }}" + - "public_key_id: {{ plat__public_key_id }}" + - "workload_analytics: {{ plat__workload_analytics }}" + - "vpc_id: {{ plat__aws_vpc_id }}" + - "subnet_ids: {{ plat__aws_subnet_ids }}" + - "tags: {{ plat__tags }}" + - "tunnel: {{ plat__tunnel }}" + - "endpoint_access_scheme: {{ plat__endpoint_access_scheme | default(omit) }}" + - "endpoint_access_subnets: {{ plat__aws_public_subnet_ids | default(omit) }}" + - "freeipa instanceCountByGroup: {{ plat__env_freeipa }}" + +- name: Prompt added by jenright + pause: + prompt: "Ready to create CDP environment" + when: debug_terraform | default(false) | bool + - name: Set up CDP Environment Deployment on AWS cloudera.cloud.env: From e4d433821ee20d56feafe1d20375f96ce9893685 Mon Sep 17 00:00:00 2001 From: Jim Enright Date: Tue, 5 Oct 2021 17:07:39 +0100 Subject: [PATCH 24/33] Cleanup of Terraform tasks and variables Signed-off-by: Jim Enright --- .../infrastructure/tasks/setup_terraform.yml | 26 +++++++++++++++++-- .../template/aws/infra_aws_storage.tf.j2 | 9 +++++++ .../tasks/setup_aws_terraform_authz.yml | 2 +- 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/roles/infrastructure/tasks/setup_terraform.yml b/roles/infrastructure/tasks/setup_terraform.yml index 5582d245..1e488b1b 100644 --- a/roles/infrastructure/tasks/setup_terraform.yml +++ b/roles/infrastructure/tasks/setup_terraform.yml @@ -23,7 +23,7 @@ ansible.builtin.copy: src: "{{ infra__terraform_template_dir }}/infra/" dest: "{{ infra__terraform_workspace_dir }}/workspace/infra" - # when: not workdir.stat.exists # TODO: This won't override if any changes to .tf are made. Good or Bad? + # when: not workdir.stat.exists # NOTE: When uncommented won't override workspace dir if any changes to .tf are made. - name: Copy Terraform infra code to the artefact directory ansible.builtin.copy: @@ -59,4 +59,26 @@ ansible.builtin.file: path: "{{ infra__terraform_workspace_dir }}/workspace/infra" state: absent - when: infra__terraform_state_storage in ['remote_s3'] \ No newline at end of file + when: infra__terraform_state_storage in ['remote_s3'] + +# If created Utility Instance via Terraform then +# need to get it's info and add to an Ansible host group +- name: Add Utility Instance to host group + when: infra__create_utility_service + block: + - name: Discover the Utility Instance details + community.aws.ec2_instance_info: + region: "{{ infra__region }}" + filters: "{{ __filters | items2dict }}" + vars: + __filters: + - key: "tag:Name" + value: "{{ infra__namespace }}*" + register: __infra_utility_compute_discovered + + - name: Add discovered Utility Instance to host group + ansible.builtin.add_host: + hostname: "{{__infra_utility_compute_discovered.instances[0].public_ip_address}}" + ansible_user: "{{ infra__dynamic_inventory_images_default[infra__type][infra__dynamic_inventory_os].user }}" + ansible_ssh_private_key_file: "{{ (infra__private_key_file == '') | ternary(omit, infra__private_key_file) }}" + groupname: cldr_utility \ No newline at end of file diff --git a/roles/infrastructure/template/aws/infra_aws_storage.tf.j2 b/roles/infrastructure/template/aws/infra_aws_storage.tf.j2 index a1318ed6..0ab7f2f2 100644 --- a/roles/infrastructure/template/aws/infra_aws_storage.tf.j2 +++ b/roles/infrastructure/template/aws/infra_aws_storage.tf.j2 @@ -4,7 +4,16 @@ resource "aws_s3_bucket" "{{ __aws_storage_location_item }}" { bucket = "{{ __aws_storage_location_item }}" acl = "private" + +{% if infra__teardown_deletes_data %} force_destroy = true +{% else %} + {# TODO: How to skip teardown of this resource if infra__teardown_deletes_data is False #} + lifecycle { + # A Terraform destroy of this resource will result in an error message. + prevent_destroy = true + } +{% endif %} tags = merge(var.env_tags,{Name = "{{ __aws_storage_location_item }}"}) } diff --git a/roles/platform/tasks/setup_aws_terraform_authz.yml b/roles/platform/tasks/setup_aws_terraform_authz.yml index 9cb17164..13fcf185 100644 --- a/roles/platform/tasks/setup_aws_terraform_authz.yml +++ b/roles/platform/tasks/setup_aws_terraform_authz.yml @@ -23,7 +23,7 @@ ansible.builtin.copy: src: "{{ plat__terraform_template_dir }}/plat/" dest: "{{ plat__terraform_workspace_dir }}/workspace/plat" - # when: not workdir.stat.exists # TODO: This won't override if any changes to .tf are made. Good or Bad? + # when: not workdir.stat.exists # NOTE: When uncommented won't override workspace dir if any changes to .tf are made. - name: Copy Terraform plat code to the artefact directory ansible.builtin.copy: From ddac819969b61e606d55a854cf75a53ff0b2650a Mon Sep 17 00:00:00 2001 From: Jim Enright Date: Thu, 21 Oct 2021 14:37:42 +0100 Subject: [PATCH 25/33] Add DNS support to Terraform created VPC Signed-off-by: Jim Enright --- .../template/aws/infra_aws_network.tf.j2 | 47 +++++++++---------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/roles/infrastructure/template/aws/infra_aws_network.tf.j2 b/roles/infrastructure/template/aws/infra_aws_network.tf.j2 index 0e442ca9..d6aa1919 100644 --- a/roles/infrastructure/template/aws/infra_aws_network.tf.j2 +++ b/roles/infrastructure/template/aws/infra_aws_network.tf.j2 @@ -3,10 +3,10 @@ resource "aws_vpc" "{{ infra__vpc_name }}" { cidr_block = "{{ infra__vpc_cidr }}" tags = merge(var.env_tags,{Name = "{{ infra__vpc_name }}"}) - # NOTE: Below variables not available in cloudera.exe - #instance_tenancy = "aws.vpc.vpc_instanceTenancy" - #enable_dns_support = "aws.vpc.vpc_enable_dns_support" - #enable_dns_hostnames = "aws.vpc.vpc_enable_dns_hostnames" + + instance_tenancy = "default" + enable_dns_support = true + enable_dns_hostnames = true } {# *** START Create AWS Public Network infrastructure ****#} @@ -15,17 +15,17 @@ resource "aws_vpc" "{{ infra__vpc_name }}" { # Internet Gateway resource "aws_internet_gateway" "{{ infra__aws_igw_name }}" { vpc_id = aws_vpc.{{ infra__vpc_name }}.id - tags = merge(var.env_tags,{Name = "{{ infra__aws_igw_name }}"}) + tags = merge(var.env_tags,{Name = "{{ infra__aws_igw_name }}"}) } # AWS VPC Public Subnets {% for __aws_public_subnet_item in infra__vpc_public_subnets_info %} resource "aws_subnet" "{{ __aws_public_subnet_item.name }}" { - vpc_id = aws_vpc.{{ infra__vpc_name }}.id - cidr_block = "{{ __aws_public_subnet_item.cidr }}" + vpc_id = aws_vpc.{{ infra__vpc_name }}.id + cidr_block = "{{ __aws_public_subnet_item.cidr }}" map_public_ip_on_launch = true - availability_zone = "{{ __aws_az_info.availability_zones[loop.index0 % infra__aws_vpc_az_count | int].zone_name }}" - tags = merge(var.env_tags,{% for key, value in __aws_public_subnet_item.tags.items() %}{ "{{ key }}" = "{{ value }}" },{% endfor %}) + availability_zone = "{{ __aws_az_info.availability_zones[loop.index0 % infra__aws_vpc_az_count | int].zone_name }}" + tags = merge(var.env_tags,{% for key, value in __aws_public_subnet_item.tags.items() %}{ "{{ key }}" = "{{ value }}" },{% endfor %}) } {% endfor %} @@ -38,7 +38,7 @@ resource "aws_default_route_table" "{{ infra__aws_public_route_table_name }}" { gateway_id = aws_internet_gateway.{{ infra__aws_igw_name }}.id } - tags = merge(var.env_tags,{Name = "{{ infra__aws_public_route_table_name }}"}) + tags = merge(var.env_tags,{Name = "{{ infra__aws_public_route_table_name }}"}) } @@ -58,16 +58,15 @@ resource "aws_route_table_association" "{{ __aws_public_subnet_item.name }}-asso {% if ( infra__tunnel ) and ( infra__aws_subnet_ids is not defined ) %} # ------- AWS Private Networking infrastructure ------- -# TODO: Conditional when: infra__tunnel and infra__aws_subnet_ids is undefined # AWS VPC Private Subnets {% for __aws_private_subnet_item in infra__vpc_private_subnets_info %} resource "aws_subnet" "{{ __aws_private_subnet_item.name }}" { - vpc_id = aws_vpc.{{ infra__vpc_name }}.id - cidr_block = "{{ __aws_private_subnet_item.cidr }}" + vpc_id = aws_vpc.{{ infra__vpc_name }}.id + cidr_block = "{{ __aws_private_subnet_item.cidr }}" map_public_ip_on_launch = true - availability_zone = "{{ __aws_az_info.availability_zones[loop.index0 % infra__aws_vpc_az_count | int].zone_name }}" - tags = merge(var.env_tags,{% for key, value in __aws_private_subnet_item.tags.items() %}{ "{{ key }}" = "{{ value }}" },{% endfor %}) + availability_zone = "{{ __aws_az_info.availability_zones[loop.index0 % infra__aws_vpc_az_count | int].zone_name }}" + tags = merge(var.env_tags,{% for key, value in __aws_private_subnet_item.tags.items() %}{ "{{ key }}" = "{{ value }}" },{% endfor %}) } {% endfor %} @@ -77,7 +76,7 @@ resource "aws_subnet" "{{ __aws_private_subnet_item.name }}" { # Elastic IP for each NAT gateway {% for __aws_public_subnet_item in infra__vpc_public_subnets_info %} resource "aws_eip" "{{ infra__aws_nat_gateway_name }}-eip-{{ loop.index0 }}" { - vpc = true + vpc = true tags = var.env_tags } @@ -91,7 +90,7 @@ resource "aws_nat_gateway" "{{ infra__aws_nat_gateway_name }}-{{ loop.index0 }}" allocation_id = aws_eip.{{ infra__aws_nat_gateway_name }}-eip-{{ loop.index0 }}.id connectivity_type = "public" - tags = merge(var.env_tags,{Name = "{{ '-'.join([infra__aws_nat_gateway_name, loop.index0 | string ]) }}"}) + tags = merge(var.env_tags,{Name = "{{ '-'.join([infra__aws_nat_gateway_name, loop.index0 | string ]) }}"}) } {% endfor %} @@ -100,10 +99,10 @@ resource "aws_nat_gateway" "{{ infra__aws_nat_gateway_name }}-{{ loop.index0 }}" resource "aws_route_table" "{{ infra__aws_private_route_table_name }}-{{ loop.index0 }}" { vpc_id = aws_vpc.{{ infra__vpc_name }}.id - tags = merge(var.env_tags,{Name = "{{ '-'.join([infra__aws_private_route_table_name, loop.index0 | string ]) }}"}) + tags = merge(var.env_tags,{Name = "{{ '-'.join([infra__aws_private_route_table_name, loop.index0 | string ]) }}"}) route { - cidr_block = "0.0.0.0/0" + cidr_block = "0.0.0.0/0" nat_gateway_id = aws_nat_gateway.{{ infra__aws_nat_gateway_name }}-{{ loop.index0 % infra__vpc_public_subnets_info | length }}.id } @@ -130,15 +129,15 @@ resource "aws_security_group" "{{ __security_group_name_item }}" { name = "{{ __security_group_name_item }}" description = "{{ __security_group_name_item }}" - tags = merge(var.env_tags,{Name = "{{ __security_group_name_item }}"}) + tags = merge(var.env_tags,{Name = "{{ __security_group_name_item }}"}) # Create self reference ingress rule to allow # communication among resources in the security group. ingress { from_port = 0 - to_port = 0 - protocol = "all" - self = true + to_port = 0 + protocol = "all" + self = true } {# ******* NOTE: HERE COMES THE MESSY PART! *******#} @@ -158,7 +157,7 @@ resource "aws_security_group" "{{ __security_group_name_item }}" { {# **Loop over security group rule**#} {% for ingress in infra__aws_security_group_rules %} # ----- Raw Inputs ----- -# ports = {{ ingress.ports|pprint }} +# ports = {{ ingress.ports|pprint }} # cidr_blocks = {{ ingress.cidr_ip }} # protocol = {{ ingress.proto }} # ---------------------- From 09c08a1839748d696d2735768954f38c3f99e9fa Mon Sep 17 00:00:00 2001 From: Jim Enright Date: Thu, 2 Dec 2021 17:19:18 +0000 Subject: [PATCH 26/33] Remove public IP assignment from private subnets Signed-off-by: Jim Enright --- .../template/aws/infra_aws_network.tf.j2 | 2 +- .../template/aws/terraform_variables.tf.j2 | 14 ++------------ .../template/aws/terraform_variables.tf.j2 | 14 ++------------ 3 files changed, 5 insertions(+), 25 deletions(-) diff --git a/roles/infrastructure/template/aws/infra_aws_network.tf.j2 b/roles/infrastructure/template/aws/infra_aws_network.tf.j2 index d6aa1919..51a04310 100644 --- a/roles/infrastructure/template/aws/infra_aws_network.tf.j2 +++ b/roles/infrastructure/template/aws/infra_aws_network.tf.j2 @@ -64,7 +64,7 @@ resource "aws_route_table_association" "{{ __aws_public_subnet_item.name }}-asso resource "aws_subnet" "{{ __aws_private_subnet_item.name }}" { vpc_id = aws_vpc.{{ infra__vpc_name }}.id cidr_block = "{{ __aws_private_subnet_item.cidr }}" - map_public_ip_on_launch = true + map_public_ip_on_launch = false availability_zone = "{{ __aws_az_info.availability_zones[loop.index0 % infra__aws_vpc_az_count | int].zone_name }}" tags = merge(var.env_tags,{% for key, value in __aws_private_subnet_item.tags.items() %}{ "{{ key }}" = "{{ value }}" },{% endfor %}) } diff --git a/roles/infrastructure/template/aws/terraform_variables.tf.j2 b/roles/infrastructure/template/aws/terraform_variables.tf.j2 index 4dc1b669..8c5cc41e 100644 --- a/roles/infrastructure/template/aws/terraform_variables.tf.j2 +++ b/roles/infrastructure/template/aws/terraform_variables.tf.j2 @@ -1,16 +1,6 @@ -# NOTE: We no longer have access & secret key readily available -# variable "access_key" { -# default = " access_key " -# } -# variable "secret_key" { -# default = " secret_key " -# } - -# NOTE: Added by jenright because we have profile and not access & secret key variable "aws_profile" { - # TODO: How to make this default if blank - # default = "{{ infra__aws_profile | default('default') }}" - default = "default" + # Profile is default is plat__aws_profile is blank + default = "{{ (infra__aws_profile | length > 0) | ternary(infra__aws_profile, 'default') }}" } # Region diff --git a/roles/platform/template/aws/terraform_variables.tf.j2 b/roles/platform/template/aws/terraform_variables.tf.j2 index 7908dbe1..5164837d 100644 --- a/roles/platform/template/aws/terraform_variables.tf.j2 +++ b/roles/platform/template/aws/terraform_variables.tf.j2 @@ -1,16 +1,6 @@ -# NOTE: We no longer have access & secret key readily available -# variable "access_key" { -# default = " access_key " -# } -# variable "secret_key" { -# default = " secret_key " -# } - -# NOTE: Added by jenright because we have profile and not access & secret key variable "aws_profile" { - # TODO: How to make this default if blank - # default = "{{ infra__aws_profile | default('default') }}" - default = "default" + # Profile is default is plat__aws_profile is blank + default = "{{ (plat__aws_profile | length > 0) | ternary(plat__aws_profile, 'default') }}" } # Region From 992122be098a8397275d021d265c8a815e324a47 Mon Sep 17 00:00:00 2001 From: Jim Enright Date: Thu, 2 Dec 2021 21:14:26 +0000 Subject: [PATCH 27/33] Cleanup of Terraform tasks and variables Signed-off-by: Jim Enright --- roles/infrastructure/defaults/main.yml | 1 - .../tasks/initialize_aws_terraform.yml | 2 +- .../infrastructure/tasks/initialize_setup.yml | 2 - .../tasks/initialize_teardown.yml | 1 - .../initialize_teardown_aws_terraform.yml | 26 +--------- .../infrastructure/tasks/setup_terraform.yml | 4 +- .../tasks/teardown_terraform.yml | 4 +- .../template/aws/infra_aws_storage.tf.j2 | 2 +- roles/platform/defaults/main.yml | 4 +- .../tasks/initialize_aws_terraform.yml | 4 +- roles/platform/tasks/initialize_setup.yml | 2 - roles/platform/tasks/initialize_teardown.yml | 2 - .../initialize_teardown_aws_terraform.yml | 19 +------ roles/platform/tasks/setup.yml | 1 - roles/platform/tasks/setup_aws_env.yml | 49 ++++++++++--------- .../tasks/setup_aws_terraform_authz.yml | 4 +- .../tasks/teardown_aws_terraform_authz.yml | 4 +- 17 files changed, 41 insertions(+), 90 deletions(-) diff --git a/roles/infrastructure/defaults/main.yml b/roles/infrastructure/defaults/main.yml index 504ecd82..093173d9 100644 --- a/roles/infrastructure/defaults/main.yml +++ b/roles/infrastructure/defaults/main.yml @@ -26,7 +26,6 @@ infra__vpc_svcnet_suffix: "{{ common__vpc_svcnet_suffix }}" infra__vpc_private_subnets_suffix: "{{ common__vpc_private_subnets_suffix }}" infra__vpc_public_subnets_suffix: "{{ common__vpc_public_subnets_suffix }}" -# NOTE: Added by jenright for Terraform # Deployment type infra__deployment_engine: "{{ common__infra_deployment_engine }}" # Location of output from template module which creates Terraform diff --git a/roles/infrastructure/tasks/initialize_aws_terraform.yml b/roles/infrastructure/tasks/initialize_aws_terraform.yml index 21ec97b9..31531256 100644 --- a/roles/infrastructure/tasks/initialize_aws_terraform.yml +++ b/roles/infrastructure/tasks/initialize_aws_terraform.yml @@ -63,7 +63,7 @@ dest: "{{ infra__terraform_template_dir }}/infra/infra_compute.tf" no_log: false -- name: Prompt added by jenright +- name: Prompt to debug Terraform deployment ansible.builtin.pause: prompt: "Terraform infra files created in {{ infra__terraform_template_dir }}/infra" when: debug_terraform | default(false) | bool \ No newline at end of file diff --git a/roles/infrastructure/tasks/initialize_setup.yml b/roles/infrastructure/tasks/initialize_setup.yml index 8b4c9082..2aec045c 100644 --- a/roles/infrastructure/tasks/initialize_setup.yml +++ b/roles/infrastructure/tasks/initialize_setup.yml @@ -24,8 +24,6 @@ - name: Include tasks fpr provider-specific Infrastructure setup initialization ansible.builtin.include_tasks: "initialize_setup_{{ infra__type | lower }}.yml" -# NOTE: Added by jenright, Terraform -# QUESTION: Do we make this generic (i.e. no infra__type) - name: Include Terraform tasks for provider-specific Infrastructure initialization ansible.builtin.include_tasks: "initialize_{{ infra__type | lower }}_{{ infra__deployment_engine }}.yml" when: infra__deployment_engine == 'terraform' diff --git a/roles/infrastructure/tasks/initialize_teardown.yml b/roles/infrastructure/tasks/initialize_teardown.yml index 5e04dd8b..52fd8964 100644 --- a/roles/infrastructure/tasks/initialize_teardown.yml +++ b/roles/infrastructure/tasks/initialize_teardown.yml @@ -23,7 +23,6 @@ - name: Include tasks for provider-specific Infrastructure teardown initialization ansible.builtin.include_tasks: "initialize_teardown_{{ infra__type | lower }}.yml" -# NOTE: Added by jenright, Terraform - name: Include Terraform tasks for provider-specific Infrastructure teardown initialization ansible.builtin.include_tasks: "initialize_teardown_{{ infra__type | lower }}_{{ infra__deployment_engine }}.yml" when: infra__deployment_engine == 'terraform' \ No newline at end of file diff --git a/roles/infrastructure/tasks/initialize_teardown_aws_terraform.yml b/roles/infrastructure/tasks/initialize_teardown_aws_terraform.yml index 5c57f362..5f445df1 100644 --- a/roles/infrastructure/tasks/initialize_teardown_aws_terraform.yml +++ b/roles/infrastructure/tasks/initialize_teardown_aws_terraform.yml @@ -36,31 +36,7 @@ dest: "{{ infra__terraform_template_dir }}/infra/variables.tf" no_log: false -# NOTE: These don't work because not all variables are defined during teardown -# ......ALSO they are not needed because we are working off the state file -# # Apply template for Terraform infra.... -# # ...network resources -# - name: Generate Terraform infra file for network resources -# template: -# src: 'template/{{ infra__type }}/infra_{{ infra__type }}_network.tf.j2' -# dest: "{{ infra__terraform_template_dir }}/infra/infra_network.tf" -# no_log: false - -# # ...storage resources -# - name: Generating Terraform infra file for storage resources -# template: -# src: 'template/{{ infra__type }}/infra_{{ infra__type }}_storage.tf.j2' -# dest: "{{ infra__terraform_template_dir }}/infra/infra_storage.tf" -# no_log: false - -# # ...compute resources -# - name: Generating Terraform infra file for compute resources -# template: -# src: 'template/{{ infra__type }}/infra_{{ infra__type }}_compute.tf.j2' -# dest: "{{ infra__terraform_template_dir }}/infra/infra_compute.tf" -# no_log: false - -- name: Prompt added by jenright +- name: Prompt to debug Terraform deployment ansible.builtin.pause: prompt: "Terraform infra files for Teardown created in {{ infra__terraform_template_dir }}/infra" when: debug_terraform | default(false) | bool diff --git a/roles/infrastructure/tasks/setup_terraform.yml b/roles/infrastructure/tasks/setup_terraform.yml index 1e488b1b..95614279 100644 --- a/roles/infrastructure/tasks/setup_terraform.yml +++ b/roles/infrastructure/tasks/setup_terraform.yml @@ -30,7 +30,7 @@ src: "{{ infra__terraform_template_dir }}/infra/" dest: "{{ infra__terraform_artefact_dir }}/infra" -- name: Prompt added by jenright +- name: Prompt to debug Terraform deployment ansible.builtin.pause: prompt: "Ready to do Terraform apply on infra files in {{ infra__terraform_workspace_dir }}/workspace/infra" when: debug_terraform | default(false) | bool @@ -45,7 +45,7 @@ delay: 10 until: tf_result is succeeded -- name: Prompt added by jenright +- name: Prompt to debug Terraform deployment pause: prompt: "Terraform apply on infra files complete. Check AWS Console." when: debug_terraform | default(false) | bool diff --git a/roles/infrastructure/tasks/teardown_terraform.yml b/roles/infrastructure/tasks/teardown_terraform.yml index 25cf0c13..c6108bb4 100644 --- a/roles/infrastructure/tasks/teardown_terraform.yml +++ b/roles/infrastructure/tasks/teardown_terraform.yml @@ -25,7 +25,7 @@ dest: "{{ infra__terraform_workspace_dir }}/workspace/infra" # when: not workdir.stat.exists # TODO: This won't override if any changes to .tf are made. Good or Bad? -- name: Prompt added by jenright +- name: Prompt to debug Terraform deployment ansible.builtin.pause: prompt: "Ready to do Terraform destroy on infra files in {{ infra__terraform_workspace_dir }}/workspace/infra" when: debug_terraform | default(false) | bool @@ -40,7 +40,7 @@ delay: 10 until: tf_result is succeeded -- name: Prompt added by jenright +- name: Prompt to debug Terraform deployment ansible.builtin.pause: prompt: "Terraform destroy on infra files complete. Check AWS Console." when: debug_terraform | default(false) | bool diff --git a/roles/infrastructure/template/aws/infra_aws_storage.tf.j2 b/roles/infrastructure/template/aws/infra_aws_storage.tf.j2 index 0ab7f2f2..7d37ccb5 100644 --- a/roles/infrastructure/template/aws/infra_aws_storage.tf.j2 +++ b/roles/infrastructure/template/aws/infra_aws_storage.tf.j2 @@ -33,7 +33,7 @@ resource "aws_s3_bucket_object" "{{ __aws_storage_object_resource }}" { {% endfor %} # ------- Download Mirror Bucket ------- -# QUESTION: How to not fail if already exists from non-Terraform code. +# TODO: Don't fail if Mirror Bucket already exists from non-Terraform code. # resource "aws_s3_bucket" "{{ infra__utlity_bucket_name }}" { # bucket = "{{ infra__utlity_bucket_name }}" # acl = "private" diff --git a/roles/platform/defaults/main.yml b/roles/platform/defaults/main.yml index 67d5a401..2dcaad8a 100644 --- a/roles/platform/defaults/main.yml +++ b/roles/platform/defaults/main.yml @@ -19,8 +19,7 @@ # Role prefix is 'plat__' # Labels -# NOTE: Added by jenright for Terraform -# Deployment type +# Deployment type (Ansible or Terraform) plat__infra_deployment_engine: "{{ common__infra_deployment_engine }}" # Location of output from template module which creates Terraform plat__terraform_template_dir: "{{ common__terraform_template_dir }}" @@ -105,6 +104,7 @@ plat__cdp_xaccount_external_id: "{{ env.cdp.cross_account.external plat__cdp_xaccount_account_id: "{{ env.cdp.cross_account.account_id | default(False) }}" # AWS +plat__aws_profile: "{{ common__aws_profile }}" plat__aws_vpc_id: "{{ common__aws_vpc_id }}" plat__aws_public_subnet_ids: "{{ common__aws_public_subnet_ids }}" plat__aws_private_subnet_ids: "{{ common__aws_private_subnet_ids }}" diff --git a/roles/platform/tasks/initialize_aws_terraform.yml b/roles/platform/tasks/initialize_aws_terraform.yml index dfaee166..5420c5e4 100644 --- a/roles/platform/tasks/initialize_aws_terraform.yml +++ b/roles/platform/tasks/initialize_aws_terraform.yml @@ -88,7 +88,7 @@ dest: "{{ plat__terraform_template_dir }}/plat/plat_authz_roles.tf" no_log: false -- name: Prompt added by jenright +- name: Prompt to debug Terraform deployment ansible.builtin.pause: - prompt: "PART 1 - Terraform role & policy files created in {{ plat__terraform_template_dir }}/plat" + prompt: "Terraform role & policy files created in {{ plat__terraform_template_dir }}/plat" when: debug_terraform | default(false) | bool diff --git a/roles/platform/tasks/initialize_setup.yml b/roles/platform/tasks/initialize_setup.yml index 9f657c31..73803c57 100644 --- a/roles/platform/tasks/initialize_setup.yml +++ b/roles/platform/tasks/initialize_setup.yml @@ -23,8 +23,6 @@ - name: Include provider-specific initialization setup ansible.builtin.include_tasks: "initialize_setup_{{ plat__infra_type | lower }}.yml" -# NOTE: Added by jenright, Terraform -# QUESTION: Do we make this generic (i.e. no infra__type) - name: Include tasks for provider-specific Terraform initialization ansible.builtin.include_tasks: "initialize_{{ plat__infra_type | lower }}_{{ plat__infra_deployment_engine }}.yml" when: plat__infra_deployment_engine == 'terraform' \ No newline at end of file diff --git a/roles/platform/tasks/initialize_teardown.yml b/roles/platform/tasks/initialize_teardown.yml index a5d0ad4a..2f2bbe39 100644 --- a/roles/platform/tasks/initialize_teardown.yml +++ b/roles/platform/tasks/initialize_teardown.yml @@ -38,8 +38,6 @@ - name: Include provider-specific resources for CDP Public Environment teardown ansible.builtin.include_tasks: "initialize_teardown_{{ plat__infra_type | lower }}.yml" -# NOTE: Added by jenright, Terraform -# QUESTION: Do we make this generic (i.e. no infra__type) - name: Include tasks for provider-specific Terraform teardown ansible.builtin.include_tasks: "initialize_teardown_{{ plat__infra_type | lower }}_{{ plat__infra_deployment_engine }}.yml" when: plat__infra_deployment_engine == 'terraform' diff --git a/roles/platform/tasks/initialize_teardown_aws_terraform.yml b/roles/platform/tasks/initialize_teardown_aws_terraform.yml index f62badb0..5be3fe4d 100644 --- a/roles/platform/tasks/initialize_teardown_aws_terraform.yml +++ b/roles/platform/tasks/initialize_teardown_aws_terraform.yml @@ -69,24 +69,7 @@ path: "{{ __aws_policy_tmpdir.path }}" state: absent -# NOTE: jenright These don't work because not all variables are defined during teardown -# ......ALSO they are not needed because we are working off the state file -# # Apply template for Terraform auth resources.... -# # ...policies -# - name: Generate Terraform authz file for policies -# template: -# src: 'template/{{ plat__infra_type }}/plat_{{ plat__infra_type }}_authz_policies.tf.j2' -# dest: "{{ plat__terraform_template_dir }}/plat/plat_authz_policies.tf" -# no_log: false - -# # ...roles -# - name: Generate Terraform authz file for roles -# template: -# src: 'template/{{ plat__infra_type }}/plat_{{ plat__infra_type }}_authz_roles.tf.j2' -# dest: "{{ plat__terraform_template_dir }}/plat/plat_authz_roles.tf" -# no_log: false - -- name: Prompt added by jenright +- name: Prompt to debug Terraform deployment ansible.builtin.pause: prompt: "Terraform role & policy files for Teardown created in {{ plat__terraform_template_dir }}/plat" when: debug_terraform | default(false) | bool diff --git a/roles/platform/tasks/setup.yml b/roles/platform/tasks/setup.yml index f63649d6..0911ea29 100644 --- a/roles/platform/tasks/setup.yml +++ b/roles/platform/tasks/setup.yml @@ -18,7 +18,6 @@ ansible.builtin.include_tasks: "setup_{{ plat__infra_type | lower }}_authz.yml" when: plat__infra_deployment_engine == 'ansible' -# NOTE: Could make this generic if we didn't have the template and policy download - name: Include Terraform deployment engine provider-specific CDP Public Roles and Policies setup tasks ansible.builtin.include_tasks: "setup_{{ plat__infra_type | lower }}_{{ plat__infra_deployment_engine }}_authz.yml" when: plat__infra_deployment_engine == 'terraform' diff --git a/roles/platform/tasks/setup_aws_env.yml b/roles/platform/tasks/setup_aws_env.yml index d3ef83b8..4ae2f608 100644 --- a/roles/platform/tasks/setup_aws_env.yml +++ b/roles/platform/tasks/setup_aws_env.yml @@ -15,32 +15,33 @@ # limitations under the License. - name: Debug variables with Terraform - debug: - msg: - - "name: {{ plat__env_name }}" - - "state: started" - - "credential: {{ plat__xacccount_credential_name }}" - - "cloud: {{ plat__infra_type }}" - - "region: {{ plat__region }}" - - "default_sg: {{ plat__aws_security_group_default_id }}" - - "knox_sg: {{ plat__aws_security_group_knox_id }}" - - "log_location: {{ plat__aws_storage_location }}" - - "log_identity: {{ plat__aws_log_instance_profile_arn }}" - - "public_key_id: {{ plat__public_key_id }}" - - "workload_analytics: {{ plat__workload_analytics }}" - - "vpc_id: {{ plat__aws_vpc_id }}" - - "subnet_ids: {{ plat__aws_subnet_ids }}" - - "tags: {{ plat__tags }}" - - "tunnel: {{ plat__tunnel }}" - - "endpoint_access_scheme: {{ plat__endpoint_access_scheme | default(omit) }}" - - "endpoint_access_subnets: {{ plat__aws_public_subnet_ids | default(omit) }}" - - "freeipa instanceCountByGroup: {{ plat__env_freeipa }}" - -- name: Prompt added by jenright - pause: - prompt: "Ready to create CDP environment" when: debug_terraform | default(false) | bool + block: + - name: Print variables used in cloudera.cloud.env + ansible.builtin.debug: + msg: + - "name: {{ plat__env_name }}" + - "state: started" + - "credential: {{ plat__xacccount_credential_name }}" + - "cloud: {{ plat__infra_type }}" + - "region: {{ plat__region }}" + - "default_sg: {{ plat__aws_security_group_default_id }}" + - "knox_sg: {{ plat__aws_security_group_knox_id }}" + - "log_location: {{ plat__aws_storage_location }}" + - "log_identity: {{ plat__aws_log_instance_profile_arn }}" + - "public_key_id: {{ plat__public_key_id }}" + - "workload_analytics: {{ plat__workload_analytics }}" + - "vpc_id: {{ plat__aws_vpc_id }}" + - "subnet_ids: {{ plat__aws_subnet_ids }}" + - "tags: {{ plat__tags }}" + - "tunnel: {{ plat__tunnel }}" + - "endpoint_access_scheme: {{ plat__endpoint_access_scheme | default(omit) }}" + - "endpoint_access_subnets: {{ plat__aws_public_subnet_ids | default(omit) }}" + - "freeipa instanceCountByGroup: {{ plat__env_freeipa }}" + - name: Prompt to debug Terraform deployment + pause: + prompt: "Ready to create CDP environment. Check variables to be used in cloudera.cloud.env." - name: Set up CDP Environment Deployment on AWS cloudera.cloud.env: diff --git a/roles/platform/tasks/setup_aws_terraform_authz.yml b/roles/platform/tasks/setup_aws_terraform_authz.yml index 13fcf185..df69aac6 100644 --- a/roles/platform/tasks/setup_aws_terraform_authz.yml +++ b/roles/platform/tasks/setup_aws_terraform_authz.yml @@ -30,7 +30,7 @@ src: "{{ plat__terraform_template_dir }}/plat/" dest: "{{ plat__terraform_artefact_dir }}/plat" -- name: Prompt added by jenright +- name: Prompt to debug Terraform deployment ansible.builtin.pause: prompt: "Ready to do Terraform apply on role files in {{ plat__terraform_workspace_dir }}/workspace/plat" when: debug_terraform | default(false) | bool @@ -45,7 +45,7 @@ delay: 10 until: tf_result is succeeded -- name: Prompt added by jenright +- name: Prompt to debug Terraform deployment ansible.builtin.pause: prompt: "Terraform apply on role files complete. Check AWS Console." when: debug_terraform | default(false) | bool diff --git a/roles/platform/tasks/teardown_aws_terraform_authz.yml b/roles/platform/tasks/teardown_aws_terraform_authz.yml index d67e5169..074215d1 100644 --- a/roles/platform/tasks/teardown_aws_terraform_authz.yml +++ b/roles/platform/tasks/teardown_aws_terraform_authz.yml @@ -31,7 +31,7 @@ dest: "{{ plat__terraform_workspace_dir }}/workspace/plat" # when: not workdir.stat.exists # TODO: This won't override if any changes to .tf are made. Good or Bad? -- name: Prompt added by jenright +- name: Prompt to debug Terraform deployment ansible.builtin.pause: prompt: "Ready to do Terraform destroy on role files in {{ plat__terraform_workspace_dir }}/workspace/plat" when: debug_terraform | default(false) | bool @@ -46,7 +46,7 @@ delay: 10 until: tf_result is succeeded -- name: Prompt added by jenright +- name: Prompt to debug Terraform deployment ansible.builtin.pause: prompt: "Terraform destroy on role files complete. Check AWS Console." when: debug_terraform | default(false) | bool From 8b9c3409f237545bd3727a09739b87d604e61e2e Mon Sep 17 00:00:00 2001 From: Jim Enright Date: Mon, 13 Dec 2021 14:37:16 +0000 Subject: [PATCH 28/33] Update Terraform infra and plat following PR feedback Signed-off-by: Jim Enright --- roles/common/defaults/main.yml | 11 ++++--- .../infrastructure/tasks/setup_terraform.yml | 10 +++--- .../tasks/teardown_terraform.yml | 10 +++--- .../tasks/validate_aws_terraform.yml | 24 ++++++++++++-- .../template/aws/backend_state.tf.j2 | 6 ++-- .../template/aws/infra_aws_compute.tf.j2 | 1 - .../template/aws/infra_aws_network.tf.j2 | 2 +- roles/platform/tasks/aws_policy_download.yml | 33 +++++++++++++++++++ .../tasks/initialize_aws_terraform.yml | 20 +++-------- roles/platform/tasks/initialize_setup_aws.yml | 1 - .../initialize_teardown_aws_terraform.yml | 22 +++---------- roles/platform/tasks/setup_aws_authz.yml | 20 +++-------- .../tasks/setup_aws_terraform_authz.yml | 11 +++---- .../tasks/teardown_aws_terraform_authz.yml | 26 +++------------ .../platform/tasks/validate_aws_terraform.yml | 27 ++++++++++++--- .../platform/template/aws/backend_state.tf.j2 | 4 +-- 16 files changed, 121 insertions(+), 107 deletions(-) create mode 100644 roles/platform/tasks/aws_policy_download.yml diff --git a/roles/common/defaults/main.yml b/roles/common/defaults/main.yml index 21ef8b86..b34d506d 100644 --- a/roles/common/defaults/main.yml +++ b/roles/common/defaults/main.yml @@ -57,7 +57,7 @@ common__ngw_suffix: "{{ globals.labels.nat_gateway | defau common__unique_storage_name_suffix: "{{ globals.storage.name | default((common__region + common__aws_profile) if 'aws' in common__infra_type else common__region) }}" # Infra -common__infra_deployment_engine: "{{ globals.infra_deployment_engine | default() }}" +common__infra_deployment_engine: "{{ globals.infra_deployment_engine | default('ansible') }}" common__infra_type: "{{ globals.infra_type | default('aws') }}" common__public_key_file: "{{ globals.ssh.public_key_file | default('') }}" common__namespace_cdp: "{{ globals.namespace_cdp | default([common__namespace, common__namespace_unique_suffix] | join('-')) }}" @@ -68,12 +68,13 @@ common__region: "{{ globals.region | default(common__r common__storage_name: "{{ infra.storage.name | default([common__namespace, common__unique_storage_name_suffix[::2] | replace('-','')] | join('-')) }}" # Terraform +common__terraform_base_dir: "{{ globals.terraform_base_dir | default( [playbook_dir , 'terraform'] | path_join ) }}" # The processed Jinja template files for Terraform are placed in common__terraform_template_dir -common__terraform_template_dir: "{{ globals.terraform_template_dir | default( ( playbook_dir , 'terraform_processed_template_code') | path_join ) }}" +common__terraform_template_dir: "{{ [common__terraform_base_dir , 'processed_template_code'] | path_join }}" # A timestamped artefact directory storing a copy of the Terraform code from each run -common__terraform_artefact_dir: "{{ [ common__terraform_template_dir , ('tf_artefacts_' + ansible_date_time.iso8601 ) ] | path_join | regex_replace(':','_')}}" - -common__terraform_workspace_dir: "{{ globals.terraform_workspace_dir | default( playbook_dir + '/.namespaces') }}" +common__terraform_artefact_dir: "{{ [common__terraform_base_dir , ('tf_artefacts_' + ansible_date_time.iso8601 ) ] | path_join | regex_replace(':','_')}}" +# Terraform apply/destroy run from under this directory +common__terraform_workspace_dir: "{{ [common__terraform_base_dir, 'workspace'] | path_join }}" common__terraform_allowed_state_storage: "['local', 'remote_s3']" common__terraform_state_storage: "{{ globals.terraform_state_storage | default('local') }}" diff --git a/roles/infrastructure/tasks/setup_terraform.yml b/roles/infrastructure/tasks/setup_terraform.yml index 95614279..3abb05c1 100644 --- a/roles/infrastructure/tasks/setup_terraform.yml +++ b/roles/infrastructure/tasks/setup_terraform.yml @@ -16,13 +16,13 @@ - name: Check if Terraform workspace directory exists ansible.builtin.stat: - path: "{{ infra__terraform_workspace_dir }}/workspace/infra" + path: "{{ infra__terraform_workspace_dir }}/infra" register: workdir - name: Ensure the Terraform workspace directory exists ansible.builtin.copy: src: "{{ infra__terraform_template_dir }}/infra/" - dest: "{{ infra__terraform_workspace_dir }}/workspace/infra" + dest: "{{ infra__terraform_workspace_dir }}/infra" # when: not workdir.stat.exists # NOTE: When uncommented won't override workspace dir if any changes to .tf are made. - name: Copy Terraform infra code to the artefact directory @@ -32,12 +32,12 @@ - name: Prompt to debug Terraform deployment ansible.builtin.pause: - prompt: "Ready to do Terraform apply on infra files in {{ infra__terraform_workspace_dir }}/workspace/infra" + prompt: "Ready to do Terraform apply on infra files in {{ infra__terraform_workspace_dir }}/infra" when: debug_terraform | default(false) | bool - name: Applying Terraform community.general.terraform: - project_path: "{{ infra__terraform_workspace_dir }}/workspace/infra" + project_path: "{{ infra__terraform_workspace_dir }}/infra" state: "present" force_init: yes register: tf_result @@ -57,7 +57,7 @@ - name: Remove the Terraform workspace directory when using remote state ansible.builtin.file: - path: "{{ infra__terraform_workspace_dir }}/workspace/infra" + path: "{{ infra__terraform_workspace_dir }}/infra" state: absent when: infra__terraform_state_storage in ['remote_s3'] diff --git a/roles/infrastructure/tasks/teardown_terraform.yml b/roles/infrastructure/tasks/teardown_terraform.yml index c6108bb4..4684e5c9 100644 --- a/roles/infrastructure/tasks/teardown_terraform.yml +++ b/roles/infrastructure/tasks/teardown_terraform.yml @@ -16,23 +16,23 @@ - name: Check if Terraform workspace directory exists ansible.builtin.stat: - path: "{{ infra__terraform_workspace_dir }}/workspace/infra" + path: "{{ infra__terraform_workspace_dir }}/infra" register: workdir - name: Ensure the Terraform workspace directory exists ansible.builtin.copy: src: "{{ infra__terraform_template_dir }}/infra/" - dest: "{{ infra__terraform_workspace_dir }}/workspace/infra" + dest: "{{ infra__terraform_workspace_dir }}/infra" # when: not workdir.stat.exists # TODO: This won't override if any changes to .tf are made. Good or Bad? - name: Prompt to debug Terraform deployment ansible.builtin.pause: - prompt: "Ready to do Terraform destroy on infra files in {{ infra__terraform_workspace_dir }}/workspace/infra" + prompt: "Ready to do Terraform destroy on infra files in {{ infra__terraform_workspace_dir }}/infra" when: debug_terraform | default(false) | bool - name: Destroy Terraform infra resources community.general.terraform: - project_path: "{{ infra__terraform_workspace_dir }}/workspace/infra" + project_path: "{{ infra__terraform_workspace_dir }}/infra" state: "absent" force_init: yes register: tf_result @@ -52,5 +52,5 @@ - name: Remove the Terraform workspace directory ansible.builtin.file: - path: "{{ infra__terraform_workspace_dir }}/workspace/infra" + path: "{{ infra__terraform_workspace_dir }}/infra" state: absent \ No newline at end of file diff --git a/roles/infrastructure/tasks/validate_aws_terraform.yml b/roles/infrastructure/tasks/validate_aws_terraform.yml index ce190b81..a41cecfc 100644 --- a/roles/infrastructure/tasks/validate_aws_terraform.yml +++ b/roles/infrastructure/tasks/validate_aws_terraform.yml @@ -36,14 +36,24 @@ ansible.builtin.assert: that: - "infra__terraform_template_dir is defined" - fail_msg: "Required infra__terraform_template_dir variable for Terraform is not set." + - "infra__terraform_template_dir | length > 0" + fail_msg: "Required infra__terraform_template_dir variable for Terraform is not valid." quiet: yes - name: Check infra__terraform_workspace_dir ansible.builtin.assert: that: - "infra__terraform_workspace_dir is defined" - fail_msg: "Required infra__terraform_workspace_dir variable for Terraform is not set." + - "infra__terraform_workspace_dir | length > 0" + fail_msg: "Required infra__terraform_workspace_dir variable for Terraform is not valid." + quiet: yes + + - name: Check infra__terraform_artefact_dir + ansible.builtin.assert: + that: + - "infra__terraform_artefact_dir is defined" + - "infra__terraform_artefact_dir | length > 0" + fail_msg: "Required infra__terraform_artefact_dir variable for Terraform is not valid." quiet: yes - name: Check infra__terraform_state_storage @@ -54,3 +64,13 @@ fail_msg: "Required infra__terraform_state_storage variable for Terraform needs to be \ one of {{ infra__terraform_allowed_state_storage | join(', ') }}" quiet: yes + + - name: Check remote state variables are defined for remote_s3 + ansible.builtin.assert: + that: + - "infra__terraform_remote_state_bucket | length > 0" + - "infra__terraform_remote_state_lock_table | length > 0" + fail_msg: "Required infra__terraform_remote_state_bucket and infra__terraform_remote_state_lock_table variables \ + need to be defined for '{{ infra__terraform_state_storage }}' Terraform remote state" + quiet: yes + when: infra__terraform_state_storage == "remote_s3" \ No newline at end of file diff --git a/roles/infrastructure/template/aws/backend_state.tf.j2 b/roles/infrastructure/template/aws/backend_state.tf.j2 index 13bdb940..0b7f5d16 100644 --- a/roles/infrastructure/template/aws/backend_state.tf.j2 +++ b/roles/infrastructure/template/aws/backend_state.tf.j2 @@ -1,5 +1,5 @@ {% if infra__terraform_state_storage == "local" %} -# Terraform state is stored locally at {{ infra__terraform_workspace_dir }}/workspace/infra +# Terraform state is stored locally at {{ infra__terraform_workspace_dir }}/infra {% endif %} {% if infra__terraform_state_storage == "remote_s3" %} @@ -7,10 +7,8 @@ terraform { backend "s3" { region = "{{ infra__region }}" bucket = "{{ infra__terraform_remote_state_bucket }}" - key = "workspace/{{infra__namespace}}/infra/terraform.tfstate" + key = "{{infra__namespace}}/infra/terraform.tfstate" dynamodb_table = "{{ infra__terraform_remote_state_lock_table }}" - # workspace_key_prefix = " terraform_workspace_key_prefix " - # encrypt = true } } {% endif %} diff --git a/roles/infrastructure/template/aws/infra_aws_compute.tf.j2 b/roles/infrastructure/template/aws/infra_aws_compute.tf.j2 index 9496a195..e0a1a1bf 100644 --- a/roles/infrastructure/template/aws/infra_aws_compute.tf.j2 +++ b/roles/infrastructure/template/aws/infra_aws_compute.tf.j2 @@ -59,5 +59,4 @@ resource "aws_instance" "{{ '-'.join([infra__namespace, infra__region, 'utility_ tags = merge({{ infra__dynamic_inventory_tags | to_json }},{Name = "{{ '-'.join([infra__namespace, infra_region, 'utility_vm' ]) }}"}) } -TODO: Need to add Utility Instance to host group {% endif %} \ No newline at end of file diff --git a/roles/infrastructure/template/aws/infra_aws_network.tf.j2 b/roles/infrastructure/template/aws/infra_aws_network.tf.j2 index 51a04310..97d9bdc8 100644 --- a/roles/infrastructure/template/aws/infra_aws_network.tf.j2 +++ b/roles/infrastructure/template/aws/infra_aws_network.tf.j2 @@ -140,7 +140,7 @@ resource "aws_security_group" "{{ __security_group_name_item }}" { self = true } -{# ******* NOTE: HERE COMES THE MESSY PART! *******#} +{# ******* NOTE: HANDLING OF SECURITY GROUP RULES *******#} {# Need to loop over each security group rule:#} {# Need to Process & Translate *CIDR Block* according to following rules:#} {# * Can be empty in which case remove entry - DONE#} diff --git a/roles/platform/tasks/aws_policy_download.yml b/roles/platform/tasks/aws_policy_download.yml new file mode 100644 index 00000000..177556e4 --- /dev/null +++ b/roles/platform/tasks/aws_policy_download.yml @@ -0,0 +1,33 @@ +--- + +# Copyright 2021 Cloudera, Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Download AWS policy documents to __aws_policy_download_dir +- name: Download AWS default policy documents + ansible.builtin.get_url: + dest: "{{ __aws_policy_download_dir }}" + url: "{{ __policy_url_item.value }}" + loop_control: + loop_var: __policy_url_item + label: "{{ __policy_url_item.key }}" + loop: "{{ plat__aws_policy_urls | dict2items }}" + register: __aws_policy_documents + +- name: Process AWS default policy documents + ansible.builtin.include_tasks: aws_policy_regex.yml + loop: "{{ __aws_policy_documents.results }}" + loop_control: + loop_var: __aws_policy_document_item + label: "{{ __aws_policy_document_item.__policy_url_item.key }}" diff --git a/roles/platform/tasks/initialize_aws_terraform.yml b/roles/platform/tasks/initialize_aws_terraform.yml index 5420c5e4..91347aca 100644 --- a/roles/platform/tasks/initialize_aws_terraform.yml +++ b/roles/platform/tasks/initialize_aws_terraform.yml @@ -31,22 +31,10 @@ state: directory register: __aws_policy_tmpdir -- name: Download AWS default policy documents - ansible.builtin.get_url: - dest: "{{ __aws_policy_tmpdir.path }}" - url: "{{ __policy_url_item.value }}" - loop_control: - loop_var: __policy_url_item - label: "{{ __policy_url_item.key }}" - loop: "{{ plat__aws_policy_urls | dict2items }}" - register: __aws_policy_documents - -- name: Process AWS default policy documents - ansible.builtin.include_tasks: aws_policy_regex.yml - loop: "{{ __aws_policy_documents.results }}" - loop_control: - loop_var: __aws_policy_document_item - label: "{{ __aws_policy_document_item.__policy_url_item.key }}" +- name: Download and Process AWS default policy documents + ansible.builtin.include_tasks: aws_policy_download.yml + vars: + __aws_policy_download_dir: "{{ __aws_policy_tmpdir.path }}" # Copy the AWS policy documents to plat__terraform_template_dir - name: Copy AWS policy documents to Terraform template directory diff --git a/roles/platform/tasks/initialize_setup_aws.yml b/roles/platform/tasks/initialize_setup_aws.yml index 785e6a9a..9f4b6112 100644 --- a/roles/platform/tasks/initialize_setup_aws.yml +++ b/roles/platform/tasks/initialize_setup_aws.yml @@ -78,7 +78,6 @@ - name: Handle AWS Public and Private VPC Subnets if not defined when: not plat__aws_public_subnet_ids or not plat__aws_private_subnet_ids block: - # Search using a wildcard on the subnet Name tag {{ plat__namespace }}* - name: Query AWS Subnets amazon.aws.ec2_vpc_subnet_info: region: "{{ plat__region }}" diff --git a/roles/platform/tasks/initialize_teardown_aws_terraform.yml b/roles/platform/tasks/initialize_teardown_aws_terraform.yml index 5be3fe4d..dc195d8e 100644 --- a/roles/platform/tasks/initialize_teardown_aws_terraform.yml +++ b/roles/platform/tasks/initialize_teardown_aws_terraform.yml @@ -42,24 +42,12 @@ state: directory register: __aws_policy_tmpdir -- name: Download AWS default policy documents - ansible.builtin.get_url: - dest: "{{ __aws_policy_tmpdir.path }}" - url: "{{ __policy_url_item.value }}" - loop_control: - loop_var: __policy_url_item - label: "{{ __policy_url_item.key }}" - loop: "{{ plat__aws_policy_urls | dict2items }}" - register: __aws_policy_documents +- name: Download and Process AWS default policy documents + ansible.builtin.include_tasks: aws_policy_download.yml + vars: + __aws_policy_download_dir: "{{ __aws_policy_tmpdir.path }}" -- name: Process AWS default policy documents - ansible.builtin.include_tasks: aws_policy_regex.yml - loop: "{{ __aws_policy_documents.results }}" - loop_control: - loop_var: __aws_policy_document_item - label: "{{ __aws_policy_document_item.__policy_url_item.key }}" - -- name: Copy AWS policy documents to Terraform workspace_dir_path +- name: Copy AWS policy documents to Terraform template directory ansible.builtin.copy: src: "{{ __aws_policy_tmpdir.path }}/" dest: "{{ plat__terraform_template_dir }}/plat/policy_docs/" diff --git a/roles/platform/tasks/setup_aws_authz.yml b/roles/platform/tasks/setup_aws_authz.yml index 8d331bd4..3dac385b 100644 --- a/roles/platform/tasks/setup_aws_authz.yml +++ b/roles/platform/tasks/setup_aws_authz.yml @@ -20,22 +20,10 @@ state: directory register: __aws_policy_tmpdir -- name: Download AWS default policy documents - ansible.builtin.get_url: - dest: "{{ __aws_policy_tmpdir.path }}" - url: "{{ __policy_url_item.value }}" - loop_control: - loop_var: __policy_url_item - label: "{{ __policy_url_item.key }}" - loop: "{{ plat__aws_policy_urls | dict2items }}" - register: __aws_policy_documents - -- name: Process AWS default policy documents - ansible.builtin.include_tasks: aws_policy_regex.yml - loop: "{{ __aws_policy_documents.results }}" - loop_control: - loop_var: __aws_policy_document_item - label: "{{ __aws_policy_document_item.__policy_url_item.key }}" +- name: Download and Process AWS default policy documents + ansible.builtin.include_tasks: aws_policy_download.yml + vars: + __aws_policy_download_dir: "{{ __aws_policy_tmpdir.path }}" - name: Construct tags for AWS Policies ansible.builtin.set_fact: diff --git a/roles/platform/tasks/setup_aws_terraform_authz.yml b/roles/platform/tasks/setup_aws_terraform_authz.yml index df69aac6..54aef988 100644 --- a/roles/platform/tasks/setup_aws_terraform_authz.yml +++ b/roles/platform/tasks/setup_aws_terraform_authz.yml @@ -16,13 +16,13 @@ - name: Check if Terraform workspace directory exists ansible.builtin.stat: - path: "{{ plat__terraform_workspace_dir }}/workspace/plat" + path: "{{ plat__terraform_workspace_dir }}/plat" register: workdir - name: Ensure the Terraform workspace directory exists ansible.builtin.copy: src: "{{ plat__terraform_template_dir }}/plat/" - dest: "{{ plat__terraform_workspace_dir }}/workspace/plat" + dest: "{{ plat__terraform_workspace_dir }}/plat" # when: not workdir.stat.exists # NOTE: When uncommented won't override workspace dir if any changes to .tf are made. - name: Copy Terraform plat code to the artefact directory @@ -32,12 +32,12 @@ - name: Prompt to debug Terraform deployment ansible.builtin.pause: - prompt: "Ready to do Terraform apply on role files in {{ plat__terraform_workspace_dir }}/workspace/plat" + prompt: "Ready to do Terraform apply on role files in {{ plat__terraform_workspace_dir }}/plat" when: debug_terraform | default(false) | bool - name: Applying Terraform community.general.terraform: - project_path: "{{ plat__terraform_workspace_dir }}/workspace/plat" + project_path: "{{ plat__terraform_workspace_dir }}/plat" state: "present" force_init: yes register: tf_result @@ -57,12 +57,11 @@ - name: Remove the Terraform workspace directory when using remote state ansible.builtin.file: - path: "{{ plat__terraform_workspace_dir }}/workspace/plat" + path: "{{ plat__terraform_workspace_dir }}/plat" state: absent when: plat__terraform_state_storage in ['remote_s3'] # Now need to get create CDP Cross Account Credential -# TODO: Is there a better place to put this? # First get the AWS Cross Account Role - name: Query the AWS Cross Account Role community.aws.iam_role_info: diff --git a/roles/platform/tasks/teardown_aws_terraform_authz.yml b/roles/platform/tasks/teardown_aws_terraform_authz.yml index 074215d1..6c8cbabb 100644 --- a/roles/platform/tasks/teardown_aws_terraform_authz.yml +++ b/roles/platform/tasks/teardown_aws_terraform_authz.yml @@ -22,23 +22,23 @@ - name: Check if Terraform workspace directory exists ansible.builtin.stat: - path: "{{ plat__terraform_template_dir }}/workspace/plat" + path: "{{ plat__terraform_template_dir }}/plat" register: workdir - name: Ensure the Terraform workspace directory exists ansible.builtin.copy: src: "{{ plat__terraform_template_dir }}/plat/" - dest: "{{ plat__terraform_workspace_dir }}/workspace/plat" + dest: "{{ plat__terraform_workspace_dir }}/plat" # when: not workdir.stat.exists # TODO: This won't override if any changes to .tf are made. Good or Bad? - name: Prompt to debug Terraform deployment ansible.builtin.pause: - prompt: "Ready to do Terraform destroy on role files in {{ plat__terraform_workspace_dir }}/workspace/plat" + prompt: "Ready to do Terraform destroy on role files in {{ plat__terraform_workspace_dir }}/plat" when: debug_terraform | default(false) | bool - name: Destroy Terraform authz resources community.general.terraform: - project_path: "{{ plat__terraform_workspace_dir }}/workspace/plat" + project_path: "{{ plat__terraform_workspace_dir }}/plat" state: "absent" force_init: yes register: tf_result @@ -58,21 +58,5 @@ - name: Remove the Terraform workspace directory ansible.builtin.file: - path: "{{ plat__terraform_workspace_dir }}/workspace/plat" + path: "{{ plat__terraform_workspace_dir }}/plat" state: absent - -# TODO: Figure out how to handle below conditional with Terraform -# - name: Tear down AWS Cross Acount -# when: plat__teardown_deletes_xaccount -# block: -# - name: Remove AWS Cross Account Role -# community.aws.iam_role: -# name: "{{ plat__aws_xaccount_role_name }}" -# region: "{{ plat__region }}" -# state: absent - -# - name: Remove AWS Cross Account Policy -# community.aws.iam_managed_policy: -# region: "{{ plat__region }}" -# policy_name: "{{ plat__aws_xaccount_policy_name }}" -# state: absent \ No newline at end of file diff --git a/roles/platform/tasks/validate_aws_terraform.yml b/roles/platform/tasks/validate_aws_terraform.yml index 3064b319..970144a1 100644 --- a/roles/platform/tasks/validate_aws_terraform.yml +++ b/roles/platform/tasks/validate_aws_terraform.yml @@ -27,24 +27,33 @@ loop: - plat__public_key_id - - name: Confirm that required Terraform variables are defined block: - name: Check plat__terraform_template_dir ansible.builtin.assert: that: - "plat__terraform_template_dir is defined" - fail_msg: "Required plat__terraform_template_dir variable for Terraform is not set." + - "plat__terraform_template_dir | length > 0" + fail_msg: "Required plat__terraform_template_dir variable for Terraform is not valid." quiet: yes - name: Check plat__terraform_workspace_dir ansible.builtin.assert: that: - "plat__terraform_workspace_dir is defined" - fail_msg: "Required plat__terraform_workspace_dir variable for Terraform is not set." + - "plat__terraform_workspace_dir | length > 0" + fail_msg: "Required plat__terraform_workspace_dir variable for Terraform is not valid." + quiet: yes + + - name: Check plat__terraform_artefact_dir + ansible.builtin.assert: + that: + - "plat__terraform_artefact_dir is defined" + - "plat__terraform_artefact_dir | length > 0" + fail_msg: "Required plat__terraform_artefact_dir variable for Terraform is not valid." quiet: yes - - name: Check infra__terraform_state_storage + - name: Check plat__terraform_state_storage ansible.builtin.assert: that: - "plat__terraform_state_storage is defined" @@ -52,3 +61,13 @@ fail_msg: "Required plat__terraform_state_storage variable for Terraform needs to be \ one of {{ plat__terraform_allowed_state_storage | join(', ') }}" quiet: yes + + - name: Check remote state variables are defined for remote_s3 + ansible.builtin.assert: + that: + - "plat__terraform_remote_state_bucket | length > 0" + - "plat__terraform_remote_state_lock_table | length > 0" + fail_msg: "Required plat__terraform_remote_state_bucket and plat__terraform_remote_state_lock_table variables \ + need to be defined for '{{ plat__terraform_state_storage }}' Terraform remote state" + quiet: yes + when: plat__terraform_state_storage == "remote_s3" \ No newline at end of file diff --git a/roles/platform/template/aws/backend_state.tf.j2 b/roles/platform/template/aws/backend_state.tf.j2 index a24d6aa4..a6db6d18 100644 --- a/roles/platform/template/aws/backend_state.tf.j2 +++ b/roles/platform/template/aws/backend_state.tf.j2 @@ -8,10 +8,8 @@ terraform { backend "s3" { region = "{{ plat__region }}" bucket = "{{ plat__terraform_remote_state_bucket }}" - key = "workspace/{{ plat__namespace }}/plat/terraform.tfstate" + key = "{{ plat__namespace }}/plat/terraform.tfstate" dynamodb_table = "{{ plat__terraform_remote_state_lock_table }}" - # workspace_key_prefix = " terraform_workspace_key_prefix " - # encrypt = true } } {% endif %} From 128dac7094be3d12617b2159e0c1142502d72b2f Mon Sep 17 00:00:00 2001 From: Jim Enright Date: Fri, 21 Jan 2022 21:20:54 +0000 Subject: [PATCH 29/33] Populate dictionary for Static Inventory artefact during Terraform flow Signed-off-by: Jim Enright --- .../infrastructure/tasks/setup_terraform.yml | 20 +++++++++++++++++++ .../template/aws/infra_aws_compute.tf.j2 | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/roles/infrastructure/tasks/setup_terraform.yml b/roles/infrastructure/tasks/setup_terraform.yml index 3abb05c1..92d91c90 100644 --- a/roles/infrastructure/tasks/setup_terraform.yml +++ b/roles/infrastructure/tasks/setup_terraform.yml @@ -61,6 +61,26 @@ state: absent when: infra__terraform_state_storage in ['remote_s3'] +# Get information about Dynamic Inventory VMs if created via Terraform +- name: Fetch EC2 Instance info for Dynamic Inventory Nodes + register: __infra_dynamic_inventory_discovered + community.aws.ec2_instance_info: + region: "{{ infra__region }}" + filters: "{{ __filters | items2dict }}" + vars: + __filters: + - key: "tag:{{ infra__dynamic_inventory_tag_key }}" + value: "{{ infra__dynamic_inventory_tag_value }}*" + +- name: Create output Dictionary for producing Static Inventory artefact + ansible.builtin.set_fact: + infra__dynamic_inventory_host_entries: "{{ infra__dynamic_inventory_host_entries | default([]) | union([host_entry]) }}" + vars: + host_entry: "{{ [__infra_di_item.private_dns_name, 'ansible_host=' + __infra_di_item.public_ip_address, infra__dynamic_inventory_connectors] | join(' ') }}" + loop: "{{ __infra_dynamic_inventory_discovered.instances }}" + loop_control: + loop_var: __infra_di_item + # If created Utility Instance via Terraform then # need to get it's info and add to an Ansible host group - name: Add Utility Instance to host group diff --git a/roles/infrastructure/template/aws/infra_aws_compute.tf.j2 b/roles/infrastructure/template/aws/infra_aws_compute.tf.j2 index e0a1a1bf..f1eff746 100644 --- a/roles/infrastructure/template/aws/infra_aws_compute.tf.j2 +++ b/roles/infrastructure/template/aws/infra_aws_compute.tf.j2 @@ -29,7 +29,7 @@ resource "aws_instance" "{{ '-'.join([infra__namespace, infra__dynamic_inventory associate_public_ip_address = true {# to_json is used to convert single quotes around IP to double #} - tags = merge({{ infra__dynamic_inventory_tags | to_json }},{Name = "{{ '-'.join([infra__namespace, infra__dynamic_inventory_vm_suffix, '%02d' | format(__infra_compute_instance_item)]) }}"}) + tags = merge({{ infra__dynamic_inventory_tags | to_json }},{Name = "{{ '-'.join([infra__namespace, infra__dynamic_inventory_vm_suffix, infra__dynamic_inventory_os[::2], '%02d' | format(__infra_compute_instance_item)]) }}"}) } {% endfor %} From 14986d9187beafb3163b26abb214a54e424adcbb Mon Sep 17 00:00:00 2001 From: Jim Enright Date: Fri, 4 Feb 2022 13:44:33 +0000 Subject: [PATCH 30/33] Cleanup of Terraform tasks Signed-off-by: Jim Enright --- .../tasks/initialize_aws_terraform.yml | 5 ---- .../initialize_teardown_aws_terraform.yml | 5 ---- .../infrastructure/tasks/setup_terraform.yml | 11 ------- .../tasks/teardown_terraform.yml | 11 ------- .../tasks/initialize_aws_terraform.yml | 5 ---- .../initialize_teardown_aws_terraform.yml | 5 ---- roles/platform/tasks/setup_aws_env.yml | 29 ------------------- .../tasks/setup_aws_terraform_authz.yml | 11 ------- .../tasks/teardown_aws_terraform_authz.yml | 11 ------- 9 files changed, 93 deletions(-) diff --git a/roles/infrastructure/tasks/initialize_aws_terraform.yml b/roles/infrastructure/tasks/initialize_aws_terraform.yml index 31531256..6c02183a 100644 --- a/roles/infrastructure/tasks/initialize_aws_terraform.yml +++ b/roles/infrastructure/tasks/initialize_aws_terraform.yml @@ -62,8 +62,3 @@ src: 'template/{{ infra__type }}/infra_{{ infra__type }}_compute.tf.j2' dest: "{{ infra__terraform_template_dir }}/infra/infra_compute.tf" no_log: false - -- name: Prompt to debug Terraform deployment - ansible.builtin.pause: - prompt: "Terraform infra files created in {{ infra__terraform_template_dir }}/infra" - when: debug_terraform | default(false) | bool \ No newline at end of file diff --git a/roles/infrastructure/tasks/initialize_teardown_aws_terraform.yml b/roles/infrastructure/tasks/initialize_teardown_aws_terraform.yml index 5f445df1..5a0545a3 100644 --- a/roles/infrastructure/tasks/initialize_teardown_aws_terraform.yml +++ b/roles/infrastructure/tasks/initialize_teardown_aws_terraform.yml @@ -35,8 +35,3 @@ src: 'template/{{ infra__type }}/terraform_variables.tf.j2' dest: "{{ infra__terraform_template_dir }}/infra/variables.tf" no_log: false - -- name: Prompt to debug Terraform deployment - ansible.builtin.pause: - prompt: "Terraform infra files for Teardown created in {{ infra__terraform_template_dir }}/infra" - when: debug_terraform | default(false) | bool diff --git a/roles/infrastructure/tasks/setup_terraform.yml b/roles/infrastructure/tasks/setup_terraform.yml index 92d91c90..461157f5 100644 --- a/roles/infrastructure/tasks/setup_terraform.yml +++ b/roles/infrastructure/tasks/setup_terraform.yml @@ -23,18 +23,12 @@ ansible.builtin.copy: src: "{{ infra__terraform_template_dir }}/infra/" dest: "{{ infra__terraform_workspace_dir }}/infra" - # when: not workdir.stat.exists # NOTE: When uncommented won't override workspace dir if any changes to .tf are made. - name: Copy Terraform infra code to the artefact directory ansible.builtin.copy: src: "{{ infra__terraform_template_dir }}/infra/" dest: "{{ infra__terraform_artefact_dir }}/infra" -- name: Prompt to debug Terraform deployment - ansible.builtin.pause: - prompt: "Ready to do Terraform apply on infra files in {{ infra__terraform_workspace_dir }}/infra" - when: debug_terraform | default(false) | bool - - name: Applying Terraform community.general.terraform: project_path: "{{ infra__terraform_workspace_dir }}/infra" @@ -45,11 +39,6 @@ delay: 10 until: tf_result is succeeded -- name: Prompt to debug Terraform deployment - pause: - prompt: "Terraform apply on infra files complete. Check AWS Console." - when: debug_terraform | default(false) | bool - - name: Remove the Terraform template directory ansible.builtin.file: path: "{{ infra__terraform_template_dir }}/infra" diff --git a/roles/infrastructure/tasks/teardown_terraform.yml b/roles/infrastructure/tasks/teardown_terraform.yml index 4684e5c9..4781278d 100644 --- a/roles/infrastructure/tasks/teardown_terraform.yml +++ b/roles/infrastructure/tasks/teardown_terraform.yml @@ -23,12 +23,6 @@ ansible.builtin.copy: src: "{{ infra__terraform_template_dir }}/infra/" dest: "{{ infra__terraform_workspace_dir }}/infra" - # when: not workdir.stat.exists # TODO: This won't override if any changes to .tf are made. Good or Bad? - -- name: Prompt to debug Terraform deployment - ansible.builtin.pause: - prompt: "Ready to do Terraform destroy on infra files in {{ infra__terraform_workspace_dir }}/infra" - when: debug_terraform | default(false) | bool - name: Destroy Terraform infra resources community.general.terraform: @@ -40,11 +34,6 @@ delay: 10 until: tf_result is succeeded -- name: Prompt to debug Terraform deployment - ansible.builtin.pause: - prompt: "Terraform destroy on infra files complete. Check AWS Console." - when: debug_terraform | default(false) | bool - - name: Remove the Terraform template directory ansible.builtin.file: path: "{{ infra__terraform_template_dir }}/infra" diff --git a/roles/platform/tasks/initialize_aws_terraform.yml b/roles/platform/tasks/initialize_aws_terraform.yml index 91347aca..7dea4e7e 100644 --- a/roles/platform/tasks/initialize_aws_terraform.yml +++ b/roles/platform/tasks/initialize_aws_terraform.yml @@ -75,8 +75,3 @@ src: 'template/{{ plat__infra_type }}/plat_{{ plat__infra_type }}_authz_roles.tf.j2' dest: "{{ plat__terraform_template_dir }}/plat/plat_authz_roles.tf" no_log: false - -- name: Prompt to debug Terraform deployment - ansible.builtin.pause: - prompt: "Terraform role & policy files created in {{ plat__terraform_template_dir }}/plat" - when: debug_terraform | default(false) | bool diff --git a/roles/platform/tasks/initialize_teardown_aws_terraform.yml b/roles/platform/tasks/initialize_teardown_aws_terraform.yml index dc195d8e..f99c2524 100644 --- a/roles/platform/tasks/initialize_teardown_aws_terraform.yml +++ b/roles/platform/tasks/initialize_teardown_aws_terraform.yml @@ -56,8 +56,3 @@ ansible.builtin.file: path: "{{ __aws_policy_tmpdir.path }}" state: absent - -- name: Prompt to debug Terraform deployment - ansible.builtin.pause: - prompt: "Terraform role & policy files for Teardown created in {{ plat__terraform_template_dir }}/plat" - when: debug_terraform | default(false) | bool diff --git a/roles/platform/tasks/setup_aws_env.yml b/roles/platform/tasks/setup_aws_env.yml index 4ae2f608..61378d9a 100644 --- a/roles/platform/tasks/setup_aws_env.yml +++ b/roles/platform/tasks/setup_aws_env.yml @@ -14,35 +14,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -- name: Debug variables with Terraform - when: debug_terraform | default(false) | bool - block: - - name: Print variables used in cloudera.cloud.env - ansible.builtin.debug: - msg: - - "name: {{ plat__env_name }}" - - "state: started" - - "credential: {{ plat__xacccount_credential_name }}" - - "cloud: {{ plat__infra_type }}" - - "region: {{ plat__region }}" - - "default_sg: {{ plat__aws_security_group_default_id }}" - - "knox_sg: {{ plat__aws_security_group_knox_id }}" - - "log_location: {{ plat__aws_storage_location }}" - - "log_identity: {{ plat__aws_log_instance_profile_arn }}" - - "public_key_id: {{ plat__public_key_id }}" - - "workload_analytics: {{ plat__workload_analytics }}" - - "vpc_id: {{ plat__aws_vpc_id }}" - - "subnet_ids: {{ plat__aws_subnet_ids }}" - - "tags: {{ plat__tags }}" - - "tunnel: {{ plat__tunnel }}" - - "endpoint_access_scheme: {{ plat__endpoint_access_scheme | default(omit) }}" - - "endpoint_access_subnets: {{ plat__aws_public_subnet_ids | default(omit) }}" - - "freeipa instanceCountByGroup: {{ plat__env_freeipa }}" - - - name: Prompt to debug Terraform deployment - pause: - prompt: "Ready to create CDP environment. Check variables to be used in cloudera.cloud.env." - - name: Set up CDP Environment Deployment on AWS cloudera.cloud.env: name: "{{ plat__env_name }}" diff --git a/roles/platform/tasks/setup_aws_terraform_authz.yml b/roles/platform/tasks/setup_aws_terraform_authz.yml index 54aef988..8487cf83 100644 --- a/roles/platform/tasks/setup_aws_terraform_authz.yml +++ b/roles/platform/tasks/setup_aws_terraform_authz.yml @@ -23,18 +23,12 @@ ansible.builtin.copy: src: "{{ plat__terraform_template_dir }}/plat/" dest: "{{ plat__terraform_workspace_dir }}/plat" - # when: not workdir.stat.exists # NOTE: When uncommented won't override workspace dir if any changes to .tf are made. - name: Copy Terraform plat code to the artefact directory ansible.builtin.copy: src: "{{ plat__terraform_template_dir }}/plat/" dest: "{{ plat__terraform_artefact_dir }}/plat" -- name: Prompt to debug Terraform deployment - ansible.builtin.pause: - prompt: "Ready to do Terraform apply on role files in {{ plat__terraform_workspace_dir }}/plat" - when: debug_terraform | default(false) | bool - - name: Applying Terraform community.general.terraform: project_path: "{{ plat__terraform_workspace_dir }}/plat" @@ -45,11 +39,6 @@ delay: 10 until: tf_result is succeeded -- name: Prompt to debug Terraform deployment - ansible.builtin.pause: - prompt: "Terraform apply on role files complete. Check AWS Console." - when: debug_terraform | default(false) | bool - - name: Remove the Terraform template directory ansible.builtin.file: path: "{{ plat__terraform_template_dir }}/plat/" diff --git a/roles/platform/tasks/teardown_aws_terraform_authz.yml b/roles/platform/tasks/teardown_aws_terraform_authz.yml index 6c8cbabb..9846314e 100644 --- a/roles/platform/tasks/teardown_aws_terraform_authz.yml +++ b/roles/platform/tasks/teardown_aws_terraform_authz.yml @@ -29,12 +29,6 @@ ansible.builtin.copy: src: "{{ plat__terraform_template_dir }}/plat/" dest: "{{ plat__terraform_workspace_dir }}/plat" - # when: not workdir.stat.exists # TODO: This won't override if any changes to .tf are made. Good or Bad? - -- name: Prompt to debug Terraform deployment - ansible.builtin.pause: - prompt: "Ready to do Terraform destroy on role files in {{ plat__terraform_workspace_dir }}/plat" - when: debug_terraform | default(false) | bool - name: Destroy Terraform authz resources community.general.terraform: @@ -46,11 +40,6 @@ delay: 10 until: tf_result is succeeded -- name: Prompt to debug Terraform deployment - ansible.builtin.pause: - prompt: "Terraform destroy on role files complete. Check AWS Console." - when: debug_terraform | default(false) | bool - - name: Remove the Terraform template directory ansible.builtin.file: path: "{{ plat__terraform_template_dir }}/plat/" From 6a13b5250d5b039bf5ca1db2b8ed7fd64b48d1d0 Mon Sep 17 00:00:00 2001 From: Jim Enright Date: Tue, 15 Feb 2022 22:14:37 +0000 Subject: [PATCH 31/33] Update TF templates following AWS provider update Signed-off-by: Jim Enright --- .../template/aws/infra_aws_storage.tf.j2 | 9 +++++++-- roles/infrastructure/template/aws/provider.tf.j2 | 14 +++++++++++--- roles/platform/template/aws/provider.tf.j2 | 14 +++++++++++--- 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/roles/infrastructure/template/aws/infra_aws_storage.tf.j2 b/roles/infrastructure/template/aws/infra_aws_storage.tf.j2 index 7d37ccb5..1f0188a5 100644 --- a/roles/infrastructure/template/aws/infra_aws_storage.tf.j2 +++ b/roles/infrastructure/template/aws/infra_aws_storage.tf.j2 @@ -3,7 +3,6 @@ {% for __aws_storage_location_item in ( infra__aws_storage_locations | map(attribute='bucket') | list | unique ) %} resource "aws_s3_bucket" "{{ __aws_storage_location_item }}" { bucket = "{{ __aws_storage_location_item }}" - acl = "private" {% if infra__teardown_deletes_data %} force_destroy = true @@ -17,6 +16,12 @@ resource "aws_s3_bucket" "{{ __aws_storage_location_item }}" { tags = merge(var.env_tags,{Name = "{{ __aws_storage_location_item }}"}) } + +# Separate bucket acl resource definition +resource "aws_s3_bucket_acl" "{{ __aws_storage_location_item }}" { + bucket = aws_s3_bucket.{{ __aws_storage_location_item }}.id + acl = "private" +} {% endfor %} # ------- AWS Buckets directory structures ------- @@ -24,7 +29,7 @@ resource "aws_s3_bucket" "{{ __aws_storage_location_item }}" { {# Terraform resources cannot have '/' so replace with '_' #} {% set __aws_storage_object_resource = __aws_storage_object_item.path |replace("/", "_") %} -resource "aws_s3_bucket_object" "{{ __aws_storage_object_resource }}" { +resource "aws_s3_object" "{{ __aws_storage_object_resource }}" { bucket = aws_s3_bucket.{{ __aws_storage_object_item.bucket }}.id key = "{{ __aws_storage_object_item.path }}/" # Below may not be required once we have the '/' diff --git a/roles/infrastructure/template/aws/provider.tf.j2 b/roles/infrastructure/template/aws/provider.tf.j2 index 02557562..2d100d60 100644 --- a/roles/infrastructure/template/aws/provider.tf.j2 +++ b/roles/infrastructure/template/aws/provider.tf.j2 @@ -1,6 +1,14 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 4.0" + } + } +} + provider "aws" { - # access_key = var.access_key - # secret_key = var.secret_key + profile = var.aws_profile region = var.region -} +} \ No newline at end of file diff --git a/roles/platform/template/aws/provider.tf.j2 b/roles/platform/template/aws/provider.tf.j2 index 02557562..2d100d60 100644 --- a/roles/platform/template/aws/provider.tf.j2 +++ b/roles/platform/template/aws/provider.tf.j2 @@ -1,6 +1,14 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 4.0" + } + } +} + provider "aws" { - # access_key = var.access_key - # secret_key = var.secret_key + profile = var.aws_profile region = var.region -} +} \ No newline at end of file From 617d68c30954838b9e3c921de9e84d92dc594445 Mon Sep 17 00:00:00 2001 From: Jim Enright Date: Fri, 25 Feb 2022 14:40:13 +0000 Subject: [PATCH 32/33] Uncomment tasks in main.yml of infra role Signed-off-by: Jim Enright --- roles/infrastructure/tasks/main.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/roles/infrastructure/tasks/main.yml b/roles/infrastructure/tasks/main.yml index 9d096444..2e92466b 100644 --- a/roles/infrastructure/tasks/main.yml +++ b/roles/infrastructure/tasks/main.yml @@ -15,5 +15,5 @@ # limitations under the License. - include_tasks: validate.yml -# - include_tasks: initialize_setup.yml -# - include_tasks: setup.yml +- include_tasks: initialize_setup.yml +- include_tasks: setup.yml From 287c30da172a90c67a6964be6662b994fab66f1f Mon Sep 17 00:00:00 2001 From: Jim Enright Date: Fri, 25 Feb 2022 18:01:51 +0000 Subject: [PATCH 33/33] Cleanup of redundant tasks in Terraform flow Signed-off-by: Jim Enright --- roles/infrastructure/tasks/setup_terraform.yml | 5 ----- roles/infrastructure/tasks/teardown_terraform.yml | 5 ----- roles/platform/tasks/setup_aws_terraform_authz.yml | 5 ----- roles/platform/tasks/teardown_aws_terraform_authz.yml | 5 ----- 4 files changed, 20 deletions(-) diff --git a/roles/infrastructure/tasks/setup_terraform.yml b/roles/infrastructure/tasks/setup_terraform.yml index 461157f5..9dae3b9c 100644 --- a/roles/infrastructure/tasks/setup_terraform.yml +++ b/roles/infrastructure/tasks/setup_terraform.yml @@ -14,11 +14,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -- name: Check if Terraform workspace directory exists - ansible.builtin.stat: - path: "{{ infra__terraform_workspace_dir }}/infra" - register: workdir - - name: Ensure the Terraform workspace directory exists ansible.builtin.copy: src: "{{ infra__terraform_template_dir }}/infra/" diff --git a/roles/infrastructure/tasks/teardown_terraform.yml b/roles/infrastructure/tasks/teardown_terraform.yml index 4781278d..7c87cbbd 100644 --- a/roles/infrastructure/tasks/teardown_terraform.yml +++ b/roles/infrastructure/tasks/teardown_terraform.yml @@ -14,11 +14,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -- name: Check if Terraform workspace directory exists - ansible.builtin.stat: - path: "{{ infra__terraform_workspace_dir }}/infra" - register: workdir - - name: Ensure the Terraform workspace directory exists ansible.builtin.copy: src: "{{ infra__terraform_template_dir }}/infra/" diff --git a/roles/platform/tasks/setup_aws_terraform_authz.yml b/roles/platform/tasks/setup_aws_terraform_authz.yml index 8487cf83..a53ac868 100644 --- a/roles/platform/tasks/setup_aws_terraform_authz.yml +++ b/roles/platform/tasks/setup_aws_terraform_authz.yml @@ -14,11 +14,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -- name: Check if Terraform workspace directory exists - ansible.builtin.stat: - path: "{{ plat__terraform_workspace_dir }}/plat" - register: workdir - - name: Ensure the Terraform workspace directory exists ansible.builtin.copy: src: "{{ plat__terraform_template_dir }}/plat/" diff --git a/roles/platform/tasks/teardown_aws_terraform_authz.yml b/roles/platform/tasks/teardown_aws_terraform_authz.yml index 9846314e..a48e8feb 100644 --- a/roles/platform/tasks/teardown_aws_terraform_authz.yml +++ b/roles/platform/tasks/teardown_aws_terraform_authz.yml @@ -20,11 +20,6 @@ name: "{{ plat__xacccount_credential_name }}" # TODO: Make specific to AWS Teardown as credentials can be for multiple environments state: absent -- name: Check if Terraform workspace directory exists - ansible.builtin.stat: - path: "{{ plat__terraform_template_dir }}/plat" - register: workdir - - name: Ensure the Terraform workspace directory exists ansible.builtin.copy: src: "{{ plat__terraform_template_dir }}/plat/"