From a70a0031201660e20773225a8c6079a18757ef1a Mon Sep 17 00:00:00 2001 From: Charnjit Sohal <40811385+charnjitsohal1@users.noreply.github.com> Date: Thu, 11 Nov 2021 09:28:00 +0000 Subject: [PATCH] added Terraform Compliance checks (#75) * added Terraform Comliance checks * added staging and prod checks --- .circleci/config.yml | 140 ++++++++++++++++-- .../terraform-compliance/opensearch.feature | 25 ++++ .../terraform-compliance/ssm.feature | 9 ++ .../terraform-compliance/opensearch.feature | 25 ++++ .../terraform-compliance/ssm.feature | 9 ++ .../terraform-compliance/opensearch.feature | 25 ++++ .../staging/terraform-compliance/ssm.feature | 9 ++ 7 files changed, 227 insertions(+), 15 deletions(-) create mode 100644 terraform/development/terraform-compliance/opensearch.feature create mode 100644 terraform/development/terraform-compliance/ssm.feature create mode 100644 terraform/production/terraform-compliance/opensearch.feature create mode 100644 terraform/production/terraform-compliance/ssm.feature create mode 100644 terraform/staging/terraform-compliance/opensearch.feature create mode 100644 terraform/staging/terraform-compliance/ssm.feature diff --git a/.circleci/config.yml b/.circleci/config.yml index d3330a37..ccf4e90d 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -38,8 +38,8 @@ commands: root: *workspace_root paths: - .aws - terraform-init-then-apply: - description: "Initializes and applies terraform configuration" + terraform-init-then-plan: + description: "Initializes and run plan from terraform configuration" parameters: environment: type: string @@ -52,11 +52,55 @@ commands: terraform get -update=true terraform init name: get and init + - run: + name: plan + command: | + cd ./terraform/<>/ + terraform plan -out=plan.out + - persist_to_workspace: + root: *workspace_root + paths: + - .aws + - project/* + terraform-compliance: + description: "Run Terraform Compliance checks" + parameters: + environment: + type: string + steps: + - *attach_workspace + - checkout + - run: + command: | + cd ./terraform/<>/ + apk add --update --no-cache python3 && ln -sf python3 /usr/bin/python + apk add --update --no-cache g++ gcc libxslt-dev python3-dev + python3 -m ensurepip + pip3 install --no-cache --upgrade pip setuptools + pip install terraform-compliance + terraform-compliance -f terraform-compliance/ -p plan.out + name: terraform compliance + - persist_to_workspace: + root: *workspace_root + paths: + - .aws + terraform-apply: + description: "Runs Terraform Apply" + parameters: + environment: + type: string + steps: + - *attach_workspace + - checkout - run: name: apply command: | cd ./terraform/<>/ - terraform apply -auto-approve + terraform apply -auto-approve plan.out + - persist_to_workspace: + root: *workspace_root + paths: + - .aws deploy-lambda: description: "Deploys API via Serverless" parameters: @@ -123,20 +167,50 @@ jobs: steps: - assume-role-and-persist-workspace: aws-account: $AWS_ACCOUNT_PRODUCTION - terraform-init-and-apply-to-development: + terraform-init-and-plan-development: + executor: docker-terraform + steps: + - terraform-init-then-plan: + environment: "development" + terraform-compliance-development: + executor: docker-terraform + steps: + - terraform-compliance: + environment: "development" + terraform-apply-development: executor: docker-terraform steps: - - terraform-init-then-apply: + - terraform-apply: environment: "development" - terraform-init-and-apply-to-staging: + terraform-init-and-plan-staging: executor: docker-terraform steps: - - terraform-init-then-apply: + - terraform-init-then-plan: environment: "staging" - terraform-init-and-apply-to-production: + terraform-compliance-staging: executor: docker-terraform steps: - - terraform-init-then-apply: + - terraform-compliance: + environment: "staging" + terraform-apply-staging: + executor: docker-terraform + steps: + - terraform-apply: + environment: "staging" + terraform-init-and-plan-production: + executor: docker-terraform + steps: + - terraform-init-then-plan: + environment: "production" + terraform-compliance-production: + executor: docker-terraform + steps: + - terraform-compliance: + environment: "production" + terraform-apply-production: + executor: docker-terraform + steps: + - terraform-apply: environment: "production" deploy-to-development: executor: docker-dotnet @@ -166,15 +240,27 @@ workflows: filters: branches: only: master - - terraform-init-and-apply-to-development: + - terraform-init-and-plan-development: requires: - assume-role-development filters: branches: only: master + - terraform-compliance-development: + requires: + - terraform-init-and-plan-development + filters: + branches: + only: master + - terraform-apply-development: + requires: + - terraform-compliance-development + filters: + branches: + only: master - deploy-to-development: requires: - - terraform-init-and-apply-to-development + - terraform-apply-development filters: branches: only: master @@ -192,15 +278,27 @@ workflows: filters: branches: only: release - - terraform-init-and-apply-to-staging: + - terraform-init-and-plan-staging: requires: - assume-role-staging filters: branches: only: release + - terraform-compliance-staging: + requires: + - terraform-init-and-plan-staging + filters: + branches: + only: release + - terraform-apply-staging: + requires: + - terraform-compliance-staging + filters: + branches: + only: master - deploy-to-staging: requires: - - terraform-init-and-apply-to-staging + - terraform-apply-staging filters: branches: only: release @@ -215,16 +313,28 @@ workflows: filters: branches: only: release - - terraform-init-and-apply-to-production: + - terraform-init-and-plan-production: requires: - assume-role-production filters: branches: only: release + - terraform-compliance-production: + requires: + - terraform-init-and-plan-production + filters: + branches: + only: release + - terraform-apply-production: + requires: + - terraform-compliance-production + filters: + branches: + only: release - permit-production-release: type: approval requires: - - terraform-init-and-apply-to-production + - terraform-apply-production filters: branches: only: release diff --git a/terraform/development/terraform-compliance/opensearch.feature b/terraform/development/terraform-compliance/opensearch.feature new file mode 100644 index 00000000..38478bf6 --- /dev/null +++ b/terraform/development/terraform-compliance/opensearch.feature @@ -0,0 +1,25 @@ +Feature: OpenSearch is used to host the ElasticSearch clusters + In order to improve security + As engineers + We'll use ensure our OpenSearch clusters are configured correctly + + Scenario: Ensure OpenSearch clusters are encrypted at rest + Given I have aws_elasticsearch_domain defined + Then it must contain encrypt_at_rest + And it must contain true + + Scenario: Ensure it is in a VPC + Given I have aws_elasticsearch_domain defined + Then it must contain vpc_options + + Scenario: Ensure minimum instance count is 2 + Given I have aws_elasticsearch_domain defined + Then it must contain cluster_config + And it must contain instance_count + And its value must be greater and equal than 2 + + Scenario: Ensure instance type is t3.small.elasticsearch/t3.medium.elasticsearch + Given I have aws_elasticsearch_domain defined + Then it must contain cluster_config + And it must contain instance_type + And its value must be ^(t3.small.elasticsearch\|t3.medium.elasticsearch)$ diff --git a/terraform/development/terraform-compliance/ssm.feature b/terraform/development/terraform-compliance/ssm.feature new file mode 100644 index 00000000..af38b38a --- /dev/null +++ b/terraform/development/terraform-compliance/ssm.feature @@ -0,0 +1,9 @@ +#Feature: SSM Parameter store provides a secure way to store config variables for our applications +# In order to improve security +# As engineers +# We'll use AWS SSM Parameter store to store our secrets +# +# +# Scenario: Ensure all SSM Parameters are using the SecureString type +# Given I have aws_ssm_parameter defined +# Then its type must be SecureString diff --git a/terraform/production/terraform-compliance/opensearch.feature b/terraform/production/terraform-compliance/opensearch.feature new file mode 100644 index 00000000..38478bf6 --- /dev/null +++ b/terraform/production/terraform-compliance/opensearch.feature @@ -0,0 +1,25 @@ +Feature: OpenSearch is used to host the ElasticSearch clusters + In order to improve security + As engineers + We'll use ensure our OpenSearch clusters are configured correctly + + Scenario: Ensure OpenSearch clusters are encrypted at rest + Given I have aws_elasticsearch_domain defined + Then it must contain encrypt_at_rest + And it must contain true + + Scenario: Ensure it is in a VPC + Given I have aws_elasticsearch_domain defined + Then it must contain vpc_options + + Scenario: Ensure minimum instance count is 2 + Given I have aws_elasticsearch_domain defined + Then it must contain cluster_config + And it must contain instance_count + And its value must be greater and equal than 2 + + Scenario: Ensure instance type is t3.small.elasticsearch/t3.medium.elasticsearch + Given I have aws_elasticsearch_domain defined + Then it must contain cluster_config + And it must contain instance_type + And its value must be ^(t3.small.elasticsearch\|t3.medium.elasticsearch)$ diff --git a/terraform/production/terraform-compliance/ssm.feature b/terraform/production/terraform-compliance/ssm.feature new file mode 100644 index 00000000..af38b38a --- /dev/null +++ b/terraform/production/terraform-compliance/ssm.feature @@ -0,0 +1,9 @@ +#Feature: SSM Parameter store provides a secure way to store config variables for our applications +# In order to improve security +# As engineers +# We'll use AWS SSM Parameter store to store our secrets +# +# +# Scenario: Ensure all SSM Parameters are using the SecureString type +# Given I have aws_ssm_parameter defined +# Then its type must be SecureString diff --git a/terraform/staging/terraform-compliance/opensearch.feature b/terraform/staging/terraform-compliance/opensearch.feature new file mode 100644 index 00000000..38478bf6 --- /dev/null +++ b/terraform/staging/terraform-compliance/opensearch.feature @@ -0,0 +1,25 @@ +Feature: OpenSearch is used to host the ElasticSearch clusters + In order to improve security + As engineers + We'll use ensure our OpenSearch clusters are configured correctly + + Scenario: Ensure OpenSearch clusters are encrypted at rest + Given I have aws_elasticsearch_domain defined + Then it must contain encrypt_at_rest + And it must contain true + + Scenario: Ensure it is in a VPC + Given I have aws_elasticsearch_domain defined + Then it must contain vpc_options + + Scenario: Ensure minimum instance count is 2 + Given I have aws_elasticsearch_domain defined + Then it must contain cluster_config + And it must contain instance_count + And its value must be greater and equal than 2 + + Scenario: Ensure instance type is t3.small.elasticsearch/t3.medium.elasticsearch + Given I have aws_elasticsearch_domain defined + Then it must contain cluster_config + And it must contain instance_type + And its value must be ^(t3.small.elasticsearch\|t3.medium.elasticsearch)$ diff --git a/terraform/staging/terraform-compliance/ssm.feature b/terraform/staging/terraform-compliance/ssm.feature new file mode 100644 index 00000000..af38b38a --- /dev/null +++ b/terraform/staging/terraform-compliance/ssm.feature @@ -0,0 +1,9 @@ +#Feature: SSM Parameter store provides a secure way to store config variables for our applications +# In order to improve security +# As engineers +# We'll use AWS SSM Parameter store to store our secrets +# +# +# Scenario: Ensure all SSM Parameters are using the SecureString type +# Given I have aws_ssm_parameter defined +# Then its type must be SecureString