From b6386eba9e26dc38825ae761f9aa27d235637933 Mon Sep 17 00:00:00 2001 From: Sean Rankine Date: Thu, 11 Jul 2024 14:20:54 +0100 Subject: [PATCH] Lint terraform `terraform fmt -recursive .` --- .github/workflows/ci-terraform.yml | 67 +++++++++++++++ assets.tf | 12 +-- bouncer.tf | 4 +- datagovuk.tf | 12 +-- main.tf | 4 +- modules/assets/provider.tf | 2 +- modules/assets/service.tf | 82 +++++++++--------- modules/bouncer/provider.tf | 4 +- modules/bouncer/service.tf | 34 ++++---- modules/bouncer/variables.tf | 8 +- modules/datagovuk/provider.tf | 2 +- modules/datagovuk/service.tf | 92 ++++++++++----------- modules/service-domain-redirect/provider.tf | 2 +- modules/tld-redirect/provider.tf | 2 +- modules/www/provider.tf | 2 +- modules/www/service.tf | 2 +- www.tf | 18 ++-- 17 files changed, 208 insertions(+), 141 deletions(-) create mode 100644 .github/workflows/ci-terraform.yml diff --git a/.github/workflows/ci-terraform.yml b/.github/workflows/ci-terraform.yml new file mode 100644 index 0000000..534cef4 --- /dev/null +++ b/.github/workflows/ci-terraform.yml @@ -0,0 +1,67 @@ +name: Terraform linting +on: + push: + paths: ['**/*.tf', '**/*.hcl', '.github/workflows/ci-terraform.yml'] +env: + TF_IN_AUTOMATION: true + TF_PLUGIN_CACHE_DIR: ${{ github.workspace }}/.terraform.d/plugin-cache +jobs: + tflint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + show-progress: false + + - name: Determine Terraform version to use + uses: dflook/terraform-version@33f9a69ab2950c83a6d3a8626f35075481a64ca0 + id: terraform-version + with: + path: terraform + + - uses: hashicorp/setup-terraform@v3 + with: + terraform_version: ${{ steps.terraform-version.outputs.terraform }} + terraform_wrapper: false + + - name: Create Terraform plugin cache dir + run: mkdir -p "$TF_PLUGIN_CACHE_DIR" + + - name: Cache Terraform plugins + uses: actions/cache@v4 + with: + path: ${{ env.TF_PLUGIN_CACHE_DIR }} + key: + terraform-plugins-${{ runner.os }}-${{ hashFiles('**/.terraform.lock.hcl') }} + + - uses: actions/cache@v4 + name: Cache TFLint plugins + with: + path: ~/.tflint.d/plugins + key: tflint-${{ runner.os }}-${{ hashFiles('**/tflint.hcl') }} + + - uses: terraform-linters/setup-tflint@v4 + name: Set up TFLint + with: + tflint_version: v0.47.0 + + - name: terraform fmt + working-directory: terraform + run: | + if ! terraform fmt -check -diff -list=true -recursive .; then + >&2 echo "Some terraform files weren't formatted correctly. Run 'terraform fmt' to fix them." + exit 1 + fi + + - name: tflint + run: | + tflint --version + tflint --init --recursive + tflint --format compact --module --recursive --force \ + --enable-rule=terraform_comment_syntax \ + --enable-rule=terraform_deprecated_index \ + --enable-rule=terraform_required_providers \ + --enable-rule=terraform_standard_module_structure \ + --enable-rule=terraform_typed_variables \ + --enable-rule=terraform_unused_declarations \ + --enable-rule=terraform_unused_required_providers diff --git a/assets.tf b/assets.tf index 2e69f95..658adae 100644 --- a/assets.tf +++ b/assets.tf @@ -7,8 +7,8 @@ module "assets-integration" { configuration = { environment = "integration" - git_hash = var.TFC_CONFIGURATION_VERSION_GIT_COMMIT_SHA - probe = "/" + git_hash = var.TFC_CONFIGURATION_VERSION_GIT_COMMIT_SHA + probe = "/" } secrets = yamldecode(var.assets_integration) @@ -25,8 +25,8 @@ module "assets-staging" { configuration = { environment = "staging" - git_hash = var.TFC_CONFIGURATION_VERSION_GIT_COMMIT_SHA - probe = "/" + git_hash = var.TFC_CONFIGURATION_VERSION_GIT_COMMIT_SHA + probe = "/" } secrets = yamldecode(var.assets_staging) @@ -43,8 +43,8 @@ module "assets-production" { configuration = { environment = "production" - git_hash = var.TFC_CONFIGURATION_VERSION_GIT_COMMIT_SHA - probe = "/" + git_hash = var.TFC_CONFIGURATION_VERSION_GIT_COMMIT_SHA + probe = "/" } secrets = yamldecode(var.assets_production) diff --git a/bouncer.tf b/bouncer.tf index 59c0995..37ec9fa 100644 --- a/bouncer.tf +++ b/bouncer.tf @@ -6,7 +6,7 @@ module "bouncer-production" { source = "./modules/bouncer" environment = "production" - domain = "publishing.service.gov.uk" - + domain = "publishing.service.gov.uk" + secrets = yamldecode(var.bouncer_production) } diff --git a/datagovuk.tf b/datagovuk.tf index 1e05c81..394ecdc 100644 --- a/datagovuk.tf +++ b/datagovuk.tf @@ -7,8 +7,8 @@ module "datagovuk-integration" { configuration = { environment = "integration" - git_hash = var.TFC_CONFIGURATION_VERSION_GIT_COMMIT_SHA - probe = "/" + git_hash = var.TFC_CONFIGURATION_VERSION_GIT_COMMIT_SHA + probe = "/" } secrets = yamldecode(var.datagovuk_integration) @@ -25,8 +25,8 @@ module "datagovuk-staging" { configuration = { environment = "staging" - git_hash = var.TFC_CONFIGURATION_VERSION_GIT_COMMIT_SHA - probe = "/" + git_hash = var.TFC_CONFIGURATION_VERSION_GIT_COMMIT_SHA + probe = "/" } secrets = yamldecode(var.datagovuk_staging) @@ -43,8 +43,8 @@ module "datagovuk-production" { configuration = { environment = "production" - git_hash = var.TFC_CONFIGURATION_VERSION_GIT_COMMIT_SHA - probe = "/" + git_hash = var.TFC_CONFIGURATION_VERSION_GIT_COMMIT_SHA + probe = "/" } secrets = yamldecode(var.datagovuk_production) diff --git a/main.tf b/main.tf index 03e88a0..e1dc3e5 100644 --- a/main.tf +++ b/main.tf @@ -16,8 +16,8 @@ terraform { provider "fastly" {} variable "TFC_CONFIGURATION_VERSION_GIT_COMMIT_SHA" { - type = string - default = "unknown" + type = string + default = "unknown" description = "Git commit hash (automatically populated)" } diff --git a/modules/assets/provider.tf b/modules/assets/provider.tf index 2919785..f715a99 100644 --- a/modules/assets/provider.tf +++ b/modules/assets/provider.tf @@ -1,7 +1,7 @@ terraform { required_providers { fastly = { - source = "fastly/fastly" + source = "fastly/fastly" } } } diff --git a/modules/assets/service.tf b/modules/assets/service.tf index 90c690e..3705ade 100644 --- a/modules/assets/service.tf +++ b/modules/assets/service.tf @@ -1,28 +1,28 @@ locals { template_values = merge( { # some defaults - aws_origin_port = 443 - minimum_tls_version = "1.2" - ssl_ciphers = "ECDHE-RSA-AES256-GCM-SHA384" + aws_origin_port = 443 + minimum_tls_version = "1.2" + ssl_ciphers = "ECDHE-RSA-AES256-GCM-SHA384" basic_authentication = null - probe_dns_only = false + probe_dns_only = false # these values are needed even if mirrors aren't enabled in an environment - s3_mirror_hostname = null - s3_mirror_prefix = null - s3_mirror_probe = null - s3_mirror_port = 443 + s3_mirror_hostname = null + s3_mirror_prefix = null + s3_mirror_probe = null + s3_mirror_port = 443 s3_mirror_replica_hostname = null - s3_mirror_replica_prefix = null - s3_mirror_replica_probe = null - s3_mirror_replica_port = 443 - gcs_mirror_hostname = null - gcs_mirror_access_id = null - gcs_mirror_secret_key = null - gcs_mirror_bucket_name = null - gcs_mirror_prefix = null - gcs_mirror_probe = null - gcs_mirror_port = 443 + s3_mirror_replica_prefix = null + s3_mirror_replica_probe = null + s3_mirror_replica_port = 443 + gcs_mirror_hostname = null + gcs_mirror_access_id = null + gcs_mirror_secret_key = null + gcs_mirror_bucket_name = null + gcs_mirror_prefix = null + gcs_mirror_probe = null + gcs_mirror_port = 443 }, { # computed values module_path = "${path.module}" @@ -43,8 +43,8 @@ resource "fastly_service_vcl" "service" { } vcl { - main = true - name = "main" + main = true + name = "main" content = templatefile("${path.module}/${var.vcl_template_file}", local.template_values) } @@ -54,10 +54,10 @@ resource "fastly_service_vcl" "service" { } iterator = each content { - name = each.key - priority = each.value.priority + name = each.key + priority = each.value.priority statement = each.value.statement - type = each.value.type + type = each.value.type } } @@ -114,10 +114,10 @@ resource "fastly_service_vcl" "service" { } EOT )) - tls_hostname = each.value.hostname - token = each.value.token - url = each.value.url - use_tls = true + tls_hostname = each.value.hostname + token = each.value.token + url = each.value.url + use_tls = true response_condition = lookup(each.value, "response_condition", null) } } @@ -128,19 +128,19 @@ resource "fastly_service_vcl" "service" { } iterator = each content { - name = each.key - bucket_name = each.value.bucket_name - domain = each.value.domain - path = each.value.path - period = each.value.period - redundancy = each.value.redundancy - s3_access_key = each.value.access_key_id - s3_secret_key = each.value.secret_access_key + name = each.key + bucket_name = each.value.bucket_name + domain = each.value.domain + path = each.value.path + period = each.value.period + redundancy = each.value.redundancy + s3_access_key = each.value.access_key_id + s3_secret_key = each.value.secret_access_key response_condition = lookup(each.value, "response_condition", null) - format_version = 2 - message_type = "blank" - gzip_level = 9 + format_version = 2 + message_type = "blank" + gzip_level = 9 timestamp_format = "%Y-%m-%dT%H:%M:%S.000" format = lookup(each.value, "format", chomp( @@ -176,8 +176,8 @@ resource "fastly_service_dictionary_items" "items" { for_each = { for d in fastly_service_vcl.service.dictionary : d.name => d } - service_id = fastly_service_vcl.service.id + service_id = fastly_service_vcl.service.id dictionary_id = each.value.dictionary_id - items = var.dictionaries[each.key] - manage_items = true + items = var.dictionaries[each.key] + manage_items = true } diff --git a/modules/bouncer/provider.tf b/modules/bouncer/provider.tf index a5dde6a..3229e8c 100644 --- a/modules/bouncer/provider.tf +++ b/modules/bouncer/provider.tf @@ -1,10 +1,10 @@ terraform { required_providers { fastly = { - source = "fastly/fastly" + source = "fastly/fastly" } http = { - source = "hashicorp/http" + source = "hashicorp/http" version = "3.4.0" } } diff --git a/modules/bouncer/service.tf b/modules/bouncer/service.tf index 96430f0..4e32e92 100644 --- a/modules/bouncer/service.tf +++ b/modules/bouncer/service.tf @@ -2,23 +2,23 @@ data "http" "domains" { url = "https://transition.publishing.service.gov.uk/hosts.json" } -locals { +locals { domains_json = jsondecode(data.http.domains.response_body) domains = { - for d in local.domains_json.results: - d.hostname => "" + for d in local.domains_json.results : + d.hostname => "" } } resource "fastly_service_vcl" "service" { - name = "${title(var.environment)} Bouncer" + name = "${title(var.environment)} Bouncer" comment = "" dynamic "domain" { for_each = local.domains iterator = each content { - name = each.key + name = each.key comment = "" } } @@ -27,7 +27,7 @@ resource "fastly_service_vcl" "service" { main = true name = "main" content = templatefile("${path.module}/${var.vcl_template_file}", { - domain = var.domain, + domain = var.domain, module_path = "${path.module}" }) } @@ -38,19 +38,19 @@ resource "fastly_service_vcl" "service" { } iterator = each content { - name = each.key - bucket_name = each.value.bucket_name - domain = each.value.domain - path = each.value.path - period = each.value.period - redundancy = each.value.redundancy - s3_access_key = each.value.access_key_id - s3_secret_key = each.value.secret_access_key + name = each.key + bucket_name = each.value.bucket_name + domain = each.value.domain + path = each.value.path + period = each.value.period + redundancy = each.value.redundancy + s3_access_key = each.value.access_key_id + s3_secret_key = each.value.secret_access_key response_condition = lookup(each.value, "response_condition", null) - format_version = 2 - message_type = "blank" - gzip_level = 9 + format_version = 2 + message_type = "blank" + gzip_level = 9 timestamp_format = "%Y-%m-%dT%H:%M:%S.000" format = lookup(each.value, "format", chomp( diff --git a/modules/bouncer/variables.tf b/modules/bouncer/variables.tf index 1ce3cbf..b10f840 100644 --- a/modules/bouncer/variables.tf +++ b/modules/bouncer/variables.tf @@ -1,16 +1,16 @@ variable "vcl_template_file" { - type = string - default = "bouncer.vcl.tftpl" + type = string + default = "bouncer.vcl.tftpl" description = "Relateive path to VCL template" } variable "environment" { - type = string + type = string default = "production" } variable "domain" { - type = string + type = string default = "publishing.service.gov.uk" } diff --git a/modules/datagovuk/provider.tf b/modules/datagovuk/provider.tf index 2919785..f715a99 100644 --- a/modules/datagovuk/provider.tf +++ b/modules/datagovuk/provider.tf @@ -1,7 +1,7 @@ terraform { required_providers { fastly = { - source = "fastly/fastly" + source = "fastly/fastly" } } } diff --git a/modules/datagovuk/service.tf b/modules/datagovuk/service.tf index 961cebf..86acb99 100644 --- a/modules/datagovuk/service.tf +++ b/modules/datagovuk/service.tf @@ -8,34 +8,34 @@ locals { ] template_values = merge( { # some defaults - origin_port = 443 - minimum_tls_version = "1.2" - ssl_ciphers = "ECDHE-RSA-AES256-GCM-SHA384" + origin_port = 443 + minimum_tls_version = "1.2" + ssl_ciphers = "ECDHE-RSA-AES256-GCM-SHA384" basic_authentication = null - probe_dns_only = true + probe_dns_only = true # these values are needed even if mirrors aren't enabled in an environment - s3_mirror_hostname = null - s3_mirror_prefix = null - s3_mirror_probe = null - s3_mirror_port = 443 + s3_mirror_hostname = null + s3_mirror_prefix = null + s3_mirror_probe = null + s3_mirror_port = 443 s3_mirror_replica_hostname = null - s3_mirror_replica_prefix = null - s3_mirror_replica_probe = null - s3_mirror_replica_port = 443 - gcs_mirror_hostname = null - gcs_mirror_access_id = null - gcs_mirror_secret_key = null - gcs_mirror_bucket_name = null - gcs_mirror_prefix = null - gcs_mirror_probe = null - gcs_mirror_port = 443 + s3_mirror_replica_prefix = null + s3_mirror_replica_probe = null + s3_mirror_replica_port = 443 + gcs_mirror_hostname = null + gcs_mirror_access_id = null + gcs_mirror_secret_key = null + gcs_mirror_bucket_name = null + gcs_mirror_prefix = null + gcs_mirror_probe = null + gcs_mirror_port = 443 private_extra_vcl_recv = "" }, { # computed values formatted_allowed_ip_addresses = local.formatted_allowed_ips - module_path = "${path.module}" + module_path = "${path.module}" }, var.configuration, var.secrets @@ -55,8 +55,8 @@ resource "fastly_service_vcl" "service" { } vcl { - main = true - name = "main" + main = true + name = "main" content = templatefile("${path.module}/${var.vcl_template_file}", local.template_values) } @@ -71,10 +71,10 @@ resource "fastly_service_vcl" "service" { } iterator = each content { - name = each.key - priority = each.value.priority + name = each.key + priority = each.value.priority statement = each.value.statement - type = each.value.type + type = each.value.type } } @@ -84,11 +84,11 @@ resource "fastly_service_vcl" "service" { } iterator = each content { - name = each.key - action = each.value.action - type = each.value.type - destination = each.value.destination - source = each.value.source + name = each.key + action = each.value.action + type = each.value.type + destination = each.value.destination + source = each.value.source response_condition = each.value.response_condition } } @@ -99,8 +99,8 @@ resource "fastly_service_vcl" "service" { } iterator = each content { - name = each.key - status = each.value.status + name = each.key + status = each.value.status request_condition = each.value.request_condition } @@ -131,10 +131,10 @@ resource "fastly_service_vcl" "service" { } EOT )) - tls_hostname = each.value.hostname - token = each.value.token - url = each.value.url - use_tls = true + tls_hostname = each.value.hostname + token = each.value.token + url = each.value.url + use_tls = true response_condition = lookup(each.value, "response_condition", null) } } @@ -145,19 +145,19 @@ resource "fastly_service_vcl" "service" { } iterator = each content { - name = each.key - bucket_name = each.value.bucket_name - domain = each.value.domain - path = each.value.path - period = each.value.period - redundancy = each.value.redundancy - s3_access_key = each.value.access_key_id - s3_secret_key = each.value.secret_access_key + name = each.key + bucket_name = each.value.bucket_name + domain = each.value.domain + path = each.value.path + period = each.value.period + redundancy = each.value.redundancy + s3_access_key = each.value.access_key_id + s3_secret_key = each.value.secret_access_key response_condition = lookup(each.value, "response_condition", null) - format_version = 2 - message_type = "blank" - gzip_level = 9 + format_version = 2 + message_type = "blank" + gzip_level = 9 timestamp_format = "%Y-%m-%dT%H:%M:%S.000" format = lookup(each.value, "format", chomp( diff --git a/modules/service-domain-redirect/provider.tf b/modules/service-domain-redirect/provider.tf index 2919785..f715a99 100644 --- a/modules/service-domain-redirect/provider.tf +++ b/modules/service-domain-redirect/provider.tf @@ -1,7 +1,7 @@ terraform { required_providers { fastly = { - source = "fastly/fastly" + source = "fastly/fastly" } } } diff --git a/modules/tld-redirect/provider.tf b/modules/tld-redirect/provider.tf index 2919785..f715a99 100644 --- a/modules/tld-redirect/provider.tf +++ b/modules/tld-redirect/provider.tf @@ -1,7 +1,7 @@ terraform { required_providers { fastly = { - source = "fastly/fastly" + source = "fastly/fastly" } } } diff --git a/modules/www/provider.tf b/modules/www/provider.tf index 2919785..f715a99 100644 --- a/modules/www/provider.tf +++ b/modules/www/provider.tf @@ -1,7 +1,7 @@ terraform { required_providers { fastly = { - source = "fastly/fastly" + source = "fastly/fastly" } } } diff --git a/modules/www/service.tf b/modules/www/service.tf index d2e511f..83a2768 100644 --- a/modules/www/service.tf +++ b/modules/www/service.tf @@ -32,7 +32,7 @@ locals { gcs_mirror_port = 443 private_extra_vcl_recv = "" - ab_tests = [] + ab_tests = [] }, { # computed values formatted_allowed_ip_addresses = local.formatted_allowed_ips diff --git a/www.tf b/www.tf index b932791..c631010 100644 --- a/www.tf +++ b/www.tf @@ -11,9 +11,9 @@ module "www-integration" { configuration = { environment = "integration" - git_hash = var.TFC_CONFIGURATION_VERSION_GIT_COMMIT_SHA - probe = "/" - ab_tests = local.ab_tests + git_hash = var.TFC_CONFIGURATION_VERSION_GIT_COMMIT_SHA + probe = "/" + ab_tests = local.ab_tests } secrets = yamldecode(var.www_integration) @@ -30,9 +30,9 @@ module "www-staging" { configuration = { environment = "staging" - git_hash = var.TFC_CONFIGURATION_VERSION_GIT_COMMIT_SHA - probe = "/" - ab_tests = local.ab_tests + git_hash = var.TFC_CONFIGURATION_VERSION_GIT_COMMIT_SHA + probe = "/" + ab_tests = local.ab_tests } secrets = yamldecode(var.www_staging) @@ -49,9 +49,9 @@ module "www-production" { configuration = { environment = "production" - git_hash = var.TFC_CONFIGURATION_VERSION_GIT_COMMIT_SHA - probe = "/" - ab_tests = local.ab_tests + git_hash = var.TFC_CONFIGURATION_VERSION_GIT_COMMIT_SHA + probe = "/" + ab_tests = local.ab_tests } secrets = yamldecode(var.www_production)