From 9e62fcba064d97bbb2c6b8cb00028481384b01e7 Mon Sep 17 00:00:00 2001
From: Steven Nemetz <snemetz@wiser.com>
Date: Mon, 23 Jul 2018 10:44:04 -0700
Subject: [PATCH] Prep for initial release

---
 .circleci/config.yml                          | 204 +++++++++++++-----
 README-json.md                                |  19 +-
 README.md                                     |  18 +-
 examples/service/run.sh                       |   1 +
 .../variables-generated-escalation-policy.tf  |  23 +-
 main.tf                                       |  24 +--
 scripts/find-module-in-cache.sh               |   2 +
 7 files changed, 202 insertions(+), 89 deletions(-)

diff --git a/.circleci/config.yml b/.circleci/config.yml
index d42f04d..29a6773 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -1,69 +1,175 @@
 version: 2
 
+# TODO: centralize full configuration. Figure out how
+#   ?? Each step as a separate script that is downloaded and run ??
+#   ?? CircleCI feature request to supoort include from remote sources
+# More Markdown terraform_testing
+# Python testing. Add doc and test that too
+# circleci/python: Both 2 and 3?
+# if src/requirements.txt get version from *.tf and test
+#   Style+: flake8 + hacking?, prospector?
+#   Security: bandit, RATS,
+
+# This file uses YAML anchors to deduplicate steps
+# see https://circleci.com/blog/circleci-hacks-reuse-yaml-in-your-circleci-config-with-yaml/
+# and https://learnxinyminutes.com/docs/yaml/
+
+.steps_template: &steps_terraform_static_analysis
+  steps:
+    - checkout
+    - run:
+        name: "Check: Validate tf files (terraform validate)"
+        command: |
+            find . -type f -name "*.tf" -exec dirname {} \;|sort -u | while read m; do (terraform validate -check-variables=false "$m" && echo "√ $m") || exit 1 ; done
+    - run:
+        name: "Check: Terraform formatting (terraform fmt)"
+        command: |
+            if [ `terraform fmt --list=true -diff=true -write=false | tee format-issues | wc -c` -ne 0 ]; then
+              echo "Some terraform files need be formatted, run 'terraform fmt' to fix"
+              echo "Formatting issues:"
+              cat format-issues
+              exit 1
+            fi
+    - run:
+        name: "Install: tflint"
+        command: |
+            apk update
+            apk add jq wget
+            # Get latest version of tflint (v0.7.0 test if still need to exclude modules. Any other changes)
+            pkg_arch=linux_amd64
+            dl_url=$(curl -s https://api.github.com/repos/wata727/tflint/releases/latest | jq -r ".assets[] | select(.name | test(\"${pkg_arch}\")) | .browser_download_url")
+            wget ${dl_url}
+            unzip tflint_linux_amd64.zip
+            mkdir -p /usr/local/tflint/bin
+            # Setup PATH for later run steps - ONLY for Bash and not in Bash
+            #echo 'export PATH=/usr/local/tflint/bin:$PATH' >> $BASH_ENV
+            echo "Installing tflint..."
+            install tflint /usr/local/tflint/bin
+            echo "Configuring tflint..."
+            tf_ver=$(terraform version | awk 'FNR <= 1' | cut -dv -f2)
+            echo -e "\tConfig for terraform version: ${tf_ver}"
+            if [ -f '.tflint.hcl' ]; then
+              sed -i "/terraform_version =/s/\".*\"/\"${tf_ver}\"/" .tflint.hcl
+            else
+              {
+              echo -e "config {\nterraform_version = \"${tf_ver}\"\ndeep_check = true\nignore_module = {"
+              for module in $(grep -h '[^a-zA-Z]source[ =]' *.tf | sed -r 's/.*=\s+//' | sort -u); do
+                # if not ^"../
+                echo "${module} = true"
+              done
+              echo -e "}\n}\n"
+              } > .tflint.hcl
+              fi
+            echo "tflint configuration:"
+            cat .tflint.hcl
+    - run:
+        # Not supporting modules from registry ?? v0.5.4
+        # For now, must ignore in config file
+        name: "Check: tflint"
+        command: |
+            #echo "Initializing terraform..."
+            #terraform init -input=false
+            echo "Running tflint..."
+            /usr/local/tflint/bin/tflint --version
+            /usr/local/tflint/bin/tflint
+
 jobs:
-  build:
+  ###
+  ### Documentation testing: Markdown
+  ###
+  # Markdown Lint https://github.com/DavidAnson/markdownlint
+  # CLI https://github.com/igorshubovych/markdownlint-cli
+  # https://hub.docker.com/r/circleci/node/tags/
+  markdown_lint_node:
     docker:
-      - image: hashicorp/terraform:0.11.3
-        entrypoint: /bin/sh
+      - image: circleci/node:10.5.0
     steps:
       - checkout
       - run:
-          name: "Validate tf files (terraform validate)"
+          name: "Install: markdown lint (node.js)"
           command: |
-              find . -type f -name "*.tf" -exec dirname {} \;|sort -u | while read m; do (terraform validate -check-variables=false "$m" && echo "√ $m") || exit 1 ; done
+              sudo npm install -g markdownlint-cli
       - run:
-          name: "Check: Terraform formatting (terraform fmt)"
+          name: "Check: markdown lint (node.js)"
           command: |
-              if [ `terraform fmt --list=true -diff=true -write=false | tee format-issues | wc -c` -ne 0 ]; then
-                echo "Some terraform files need be formatted, run 'terraform fmt' to fix"
-                echo "Formatting issues:"
-                cat format-issues
-                exit 1
-              fi
+              #markdownlint --help
+              echo -n "markdownlint version: "
+              markdownlint --version
+              markdownlint ./
+  # Markdown Lint https://github.com/markdownlint/markdownlint
+  # https://hub.docker.com/r/circleci/ruby/tags/
+  markdown_lint_ruby:
+    docker:
+      - image: circleci/ruby:2.5.1
+    steps:
+      - checkout
+      - run:
+          name: "Install: markdown lint (ruby)"
+          command: |
+              gem install mdl
+      - run:
+          name: "Check: markdown lint (ruby)"
+          command: |
+              #mdl --help
+              echo -n "mdl version: "
+              mdl --version
+              mdl .
+  markdown_proofer:
+    docker:
+      - image: circleci/golang:1.10
+        entrypoint: /bin/sh
+    steps:
+      - checkout
       - run:
-          name: "Install: tflint"
+          name: "Install: markdown proofer"
           command: |
-              apk add jq wget
-              # Get latest version of tflint
+              # Get latest version
               pkg_arch=linux_amd64
-              dl_url=$(curl -s https://api.github.com/repos/wata727/tflint/releases/latest | jq -r ".assets[] | select(.name | test(\"${pkg_arch}\")) | .browser_download_url")
+              # Prerelease, so latest doesn't work yet
+              #dl_url=$(curl -s https://api.github.com/repos/felicianotech/md-proofer/releases/latest | jq -r ".assets[] | select(.name | test(\"${pkg_arch}\")) | .browser_download_url")
+              dl_url='https://github.com/felicianotech/md-proofer/releases/download/v0.2.0/md-proofer--v0.2.0--linux-amd64.tar.gz'
               wget ${dl_url}
-              unzip tflint_linux_amd64.zip
-              mkdir -p /usr/local/tflint/bin
-              # Setup PATH for later run steps - ONLY for Bash and not in Bash
-              #echo 'export PATH=/usr/local/tflint/bin:$PATH' >> $BASH_ENV
-              echo "Installing tflint..."
-              install tflint /usr/local/tflint/bin
-              echo "Configuring tflint..."
-              tf_ver=$(terraform version | awk 'FNR <= 1' | cut -dv -f2)
-              echo -e "\tConfig for terraform version: ${tf_ver}"
-              if [ -f '.tflint.hcl' ]; then
-                sed -i "/terraform_version =/s/\".*\"/\"${tf_ver}\"/" .tflint.hcl
-              else
-                {
-                echo -e "config {\nterraform_version = \"${tf_ver}\"\ndeep_check = true\nignore_module = {"
-                for module in $(grep -h '[^a-zA-Z]source[ =]' *.tf | sed -r 's/.*=\s+//' | sort -u); do
-                  # if not ^"../
-                  echo "${module} = true"
-                done
-                echo "}}"
-                } > .tflint.hcl
-                fi
-              echo "tflint configuration:"
-              cat .tflint.hcl
+              tar xzf md-proofer--v0.2.0--linux-amd64.tar.gz
       - run:
-          # Not supporting modules from registry ?? v0.5.4
-          # For now, must ignore in config file
-          name: "Check: tflint"
+          name: "Check: markdown proofer"
           command: |
-              #echo "Initializing terraform..."
-              #terraform init -input=false
-              echo "Running tflint..."
-              /usr/local/tflint/bin/tflint --version
-              /usr/local/tflint/bin/tflint
+              ./md-proofer version
+              #./md-proofer lint --help
+              # Will this find all *.md in directory structure or need to run in each directory ?
+              if ./md-proofer lint ./; then
+                echo "md-proofer passed"
+              else
+                echo "md-proofer failed"
+              fi
+  ###
+  ### Terraform testing
+  ###
+  terraform_0_11_3:
+    docker:
+      - image: hashicorp/terraform:0.11.3
+        entrypoint: /bin/sh
+    <<: *steps_terraform_static_analysis
+
+  terraform_0_11_7:
+    docker:
+      - image: hashicorp/terraform:0.11.7
+        entrypoint: /bin/sh
+    <<: *steps_terraform_static_analysis
+
+  terraform_latest:
+    docker:
+      - image: hashicorp/terraform:latest
+        entrypoint: /bin/sh
+    <<: *steps_terraform_static_analysis
 
 workflows:
   version: 2
-  build:
+  terraform_testing:
     jobs:
-      - build
+      - markdown_lint_node
+      - markdown_lint_ruby
+      # Currently doesn't do anything that markdownlint node doesn't do
+      #- markdown_proofer
+      - terraform_0_11_3
+      - terraform_0_11_7
+      - terraform_latest
diff --git a/README-json.md b/README-json.md
index bb9a7c5..1ad84f8 100644
--- a/README-json.md
+++ b/README-json.md
@@ -1,12 +1,23 @@
 # escalation-policy.json
 
-Currently Terraform is not capable of dynamically created the data structure needed to define a Pagerduty escalation policy. So, a [json file](escalation-policy.json-example) is used to specify the escalation policy details and a script does lookups in Pagerduty for details, then creates variables in HCL format for Terraform to consume.
+Currently Terraform is not capable of dynamically created the data structure
+needed to define a Pagerduty escalation policy. So, a
+[json file](escalation-policy.json-example) is used to specify the escalation
+policy details and a script does lookups in Pagerduty for details, then creates
+variables in HCL format for Terraform to consume.
 
-The [json file](escalation-policy.json-example) contains details for 2 variables: escalation-rules and teams
+The [json file](escalation-policy.json-example) contains details for
+2 variables: escalation-rules and teams
 
-Escalation-rules is a list of maps. Each map defines an escalation rule. Each escalation rule has fields: escalation_delay and targets. escalation_delay is the delay in minutes between rules. This maps directly to Pagerduty. Targets is a list of targets for the escalation rule. Targets can be user email addresses or schedule names. These will be looked up in Pagerduty and ignored if not found.
+Escalation-rules is a list of maps. Each map defines an escalation rule. Each
+escalation rule has fields: escalation_delay and targets. escalation_delay
+is the delay in minutes between rules. This maps directly to Pagerduty.
+Targets is a list of targets for the escalation rule. Targets can be user
+email addresses or schedule names. These will be looked up in Pagerduty and
+ignored if not found.
 
-Teams is a list of team names. These will be looked up in Pagerduty and ignored if not found.
+Teams is a list of team names. These will be looked up in Pagerduty and
+ignored if not found.
 
 Both variables are required. If teams are not being used, use "teams": []
 
diff --git a/README.md b/README.md
index fe33567..829a135 100644
--- a/README.md
+++ b/README.md
@@ -1,12 +1,20 @@
-[![CircleCI](https://circleci.com/gh/devops-workflow/terraform-pagerduty-service-complete.svg?style=svg)](https://circleci.com/gh/devops-workflow/terraform-pagerduty-service-complete)
-
 # terraform-pagerduty-service-complete
 
-This is a Terraform module to manage an opinionated PagerDuty service. It will create a service with: escalation policy and integrations for AWS Cloudwatch, Datadog, and an AWS Service endpoint monitor lambda.
+[![CircleCI](https://circleci.com/gh/devops-workflow/terraform-pagerduty-service-complete.svg?style=svg)](https://circleci.com/gh/devops-workflow/terraform-pagerduty-service-complete)
+
+This is a Terraform module to manage an opinionated PagerDuty service. It will
+create a service with: escalation policy and integrations for AWS Cloudwatch,
+Datadog, and an AWS Service endpoint monitor lambda.
 
-The idea to define a PagerDuty service for each application with the application's deployment via Terraform. Service, escalation policy, and integrations are unique to each application.
+The idea to define a PagerDuty service for each application with the
+application's deployment via Terraform. Service, escalation policy, and
+integrations are unique to each application.
 
-Escalation policy is defined with a [json file](README-json.md) due to limitations in Terraform. A [script](scripts/variable-generator.py) is run to lookup information in Pagerduty and generate a HCL file with the variable definitions for Terraform to use. Generated file is `variables-generated-escaaltion-policy.tf`
+Escalation policy is defined with a [json file](README-json.md) due to
+limitations in Terraform. A [script](scripts/variable-generator.py) is run to
+lookup information in Pagerduty and generate a HCL file with the variable
+definitions for Terraform to use. Generated file is
+`variables-generated-escalation-policy.tf`
 
 Pagerduty integration keys are provided as outputs for other modules to use.
 
diff --git a/examples/service/run.sh b/examples/service/run.sh
index 49be6e7..64fdc07 100755
--- a/examples/service/run.sh
+++ b/examples/service/run.sh
@@ -1,3 +1,4 @@
 python ../../scripts/variable-generator.py
+terraform fmt
 terraform init
 terraform plan
diff --git a/examples/service/variables-generated-escalation-policy.tf b/examples/service/variables-generated-escalation-policy.tf
index 907ef39..48c04d7 100644
--- a/examples/service/variables-generated-escalation-policy.tf
+++ b/examples/service/variables-generated-escalation-policy.tf
@@ -1,24 +1,9 @@
 variable "escalation_rules" {
-  type = "list"
-
-  default = [
-    {
-      "escalation_delay_in_minutes" = "11"
-
-      "target" = [
-        {
-          "type" = "user_reference"
-          "id"   = "PDBFXEO"
-        },
-      ]
-    },
-  ]
+  type    = "list"
+  default = []
 }
 
 variable "teams" {
-  type = "list"
-
-  default = [
-    "PIUEF8D",
-  ]
+  type    = "list"
+  default = []
 }
diff --git a/main.tf b/main.tf
index b5d0cf7..2f47ed7 100644
--- a/main.tf
+++ b/main.tf
@@ -9,7 +9,7 @@
 
 module "enabled" {
   source  = "devops-workflow/boolean/local"
-  version = "0.1.1"
+  version = "0.1.2"
   value   = "${var.enabled}"
 }
 
@@ -92,24 +92,24 @@ resource "pagerduty_extension" "slack"{
   "name": "Slack-Channel-X",
   "extension_objects": [
     {
-      "self": "https://api.pagerduty.com/services/PWDXXXX",
+      "self": "https://api.pagerduty.com/services/PWXXXXX",
       "type": "service_reference",
-      "id": "PWDXXXX",
-      "html_url": "https://company.pagerduty.com/services/PWDXXXX",
+      "id": "PWXXXXX",
+      "html_url": "https://company.pagerduty.com/services/PWXXXXX",
       "summary": "[Service] Channel X"
     }
   ],
-  "authorization_url": "https://app.pagerduty.com/slack_oauth?webhook=PL6XXXX",
+  "authorization_url": "https://app.pagerduty.com/slack_oauth?webhook=PLXXXXX",
   "type": "webhook",
-  "self": "https://api.pagerduty.com/webhooks/PL6XXXX",
+  "self": "https://api.pagerduty.com/webhooks/PLXXXXX",
   "summary": "Slack-Channel-X",
   "html_url": null,
-  "id": "PL6XXXX",
+  "id": "PLXXXXX",
   "authorized": true,
   "extension_schema": {
-    "self": "https://api.pagerduty.com/extension_schemas/PD8XXXX",
+    "self": "https://api.pagerduty.com/extension_schemas/PDXXXXX",
     "type": "extension_schema_reference",
-    "id": "PD8XXXX",
+    "id": "PDXXXXX",
     "html_url": null,
     "summary": "Slack"
   },
@@ -118,13 +118,13 @@ resource "pagerduty_extension" "slack"{
     "user_id": "U6SCXXXX",
     "access_token": "slack token",
     "bot": {
-      "bot_user_id": "U2P6XXXX"
+      "bot_user_id": "U2XXXXXX"
     },
     "incoming_webhook": {
       "url": "https://hooks.slack.com/services/TTTTTTTT/BBBBBBBB/xxxxxx",
-      "channel_id": "CAC0BXXXX",
+      "channel_id": "CAXXXXXXX",
       "channel": "#mon-channel-x",
-      "configuration_url": "https://company.slack.com/services/BACDNXXXX"
+      "configuration_url": "https://company.slack.com/services/BAXXXXXXX"
     },
     "restrict": "any",
     "team_id": "TTTTTTT",
diff --git a/scripts/find-module-in-cache.sh b/scripts/find-module-in-cache.sh
index 59e5385..1083833 100755
--- a/scripts/find-module-in-cache.sh
+++ b/scripts/find-module-in-cache.sh
@@ -1,3 +1,5 @@
+
+# grep -E "source" *.tf 
 # .terraform/modules/modules.json from current directory after init is run
 jq -r '.Modules[] | select(.Source == "devops-workflow/service-complete/pagerduty") | .Dir' modules.json