diff --git a/.github/workflows/tflint.yaml b/.github/workflows/tflint.yaml new file mode 100644 index 00000000..fa99d5d9 --- /dev/null +++ b/.github/workflows/tflint.yaml @@ -0,0 +1,47 @@ +name: Terraform Linting +on: + pull_request: + push: + branches: + - main + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + tflint: + runs-on: ubuntu-latest + + strategy: + matrix: + dirs: [terraform/modules/oidc, terraform/modules/tfstate, terraform/implementation/setup, terraform/implementation/ecs] + + steps: + - uses: actions/checkout@v4 + name: Checkout source code + + - uses: actions/cache@v4 + name: Cache plugin dir + with: + path: ~/.tflint.d/plugins + key: ${{ matrix.dirs }}-tflint-${{ hashFiles('.tflint.hcl') }} + + - uses: terraform-linters/setup-tflint@v4 + name: Setup TFLint + with: + tflint_version: v0.52.0 + + - name: Show version + run: tflint --version + + - name: Init TFLint + run: tflint --init + # If rate limiting becomes an issue, setup a GitHub token and enable it as an environment variable + # env: + # https://github.com/terraform-linters/tflint/blob/master/docs/user-guide/plugins.md#avoiding-rate-limiting + # GITHUB_TOKEN: ${{ github.token }} + + - name: Run TFLint + working-directory: ${{ github.workspace }}/${{matrix.dirs}} + run: tflint -f compact \ No newline at end of file diff --git a/terraform/implementation/ecs/README.md b/terraform/implementation/ecs/README.md index 7a66cfae..076b333f 100644 --- a/terraform/implementation/ecs/README.md +++ b/terraform/implementation/ecs/README.md @@ -3,43 +3,36 @@ | Name | Version | |------|---------| +| [terraform](#requirement\_terraform) | ~> 1.9.0 | | [aws](#requirement\_aws) | =5.56.1 | ## Providers -| Name | Version | -|------|---------| -| [aws](#provider\_aws) | =5.56.1 | +No providers. ## Modules | Name | Source | Version | |------|--------|---------| -| [ecs](#module\_ecs) | ../../modules/ecs | n/a | -| [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | n/a | +| [ecs](#module\_ecs) | CDCgov/dibbs-ecr-viewer/aws | 0.1.2 | +| [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | 5.16.0 | ## Resources -| Name | Type | -|------|------| -| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/5.56.1/docs/data-sources/caller_identity) | data source | +No resources. ## Inputs | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| | [availability\_zones](#input\_availability\_zones) | The availability zones to use | `list(string)` |
[| no | -| [ecr\_viewer\_database\_schema](#input\_ecr\_viewer\_database\_schema) | The database schema used for the eCR data tables | `string` | `"core"` | no | -| [ecr\_viewer\_database\_type](#input\_ecr\_viewer\_database\_type) | The SQL variant used for the eCR data tables | `string` | `"postgres"` | no | -| [ecs\_alb\_sg](#input\_ecs\_alb\_sg) | The security group for the Application Load Balancer | `string` | `"ecs-albsg"` | no | | [internal](#input\_internal) | Flag to determine if the several AWS resources are public (intended for external access, public internet) or private (only intended to be accessed within your AWS VPC or avaiable with other means, a transit gateway for example). | `bool` | `true` | no | | [owner](#input\_owner) | The owner of the infrastructure | `string` | `"skylight"` | no | -| [phdi\_version](#input\_phdi\_version) | PHDI container image version | `string` | `"v1.4.4"` | no | +| [phdi\_version](#input\_phdi\_version) | PHDI container image version | `string` | `"v1.6.9"` | no | | [private\_subnets](#input\_private\_subnets) | The private subnets | `list(string)` |
"us-east-1a",
"us-east-1b",
"us-east-1c"
]
[| no | | [project](#input\_project) | The project name | `string` | `"dibbs"` | no | | [public\_subnets](#input\_public\_subnets) | The public subnets | `list(string)` |
"176.24.1.0/24",
"176.24.3.0/24"
]
[| no | | [region](#input\_region) | AWS region | `string` | `"us-east-1"` | no | -| [vpc](#input\_vpc) | The name of the VPC | `string` | `"ecs-vpc"` | no | | [vpc\_cidr](#input\_vpc\_cidr) | The CIDR block for the VPC | `string` | `"176.24.0.0/16"` | no | ## Outputs diff --git a/terraform/implementation/ecs/_data.tf b/terraform/implementation/ecs/_data.tf deleted file mode 100644 index d78fce49..00000000 --- a/terraform/implementation/ecs/_data.tf +++ /dev/null @@ -1 +0,0 @@ -data "aws_caller_identity" "current" {} \ No newline at end of file diff --git a/terraform/implementation/ecs/_variable.tf b/terraform/implementation/ecs/_variable.tf index ae70941c..92257979 100644 --- a/terraform/implementation/ecs/_variable.tf +++ b/terraform/implementation/ecs/_variable.tf @@ -10,12 +10,6 @@ variable "internal" { default = true } -variable "ecs_alb_sg" { - description = "The security group for the Application Load Balancer" - type = string - default = "ecs-albsg" -} - variable "owner" { description = "The owner of the infrastructure" type = string @@ -26,7 +20,7 @@ variable "owner" { variable "phdi_version" { description = "PHDI container image version" type = string - default = "v1.4.4" + default = "v1.6.9" } variable "private_subnets" { @@ -53,12 +47,6 @@ variable "region" { default = "us-east-1" } -variable "vpc" { - description = "The name of the VPC" - type = string - default = "ecs-vpc" -} - variable "vpc_cidr" { description = "The CIDR block for the VPC" type = string diff --git a/terraform/implementation/ecs/main.tf b/terraform/implementation/ecs/main.tf index 12d80634..a42cea05 100644 --- a/terraform/implementation/ecs/main.tf +++ b/terraform/implementation/ecs/main.tf @@ -1,5 +1,6 @@ module "vpc" { - source = "terraform-aws-modules/vpc/aws" + source = "terraform-aws-modules/vpc/aws" + version = "5.16.0" name = local.vpc_name cidr = var.vpc_cidr @@ -22,9 +23,10 @@ module "ecs" { vpc_id = module.vpc.vpc_id region = var.region - owner = var.owner - project = var.project - tags = local.tags + owner = var.owner + project = var.project + tags = local.tags + phdi_version = var.phdi_version # If intent is to pull from the phdi GHCR, set disable_ecr to true (default is false) # disable_ecr = true diff --git a/terraform/implementation/ecs/provider.tf b/terraform/implementation/ecs/provider.tf new file mode 100644 index 00000000..77fe6006 --- /dev/null +++ b/terraform/implementation/ecs/provider.tf @@ -0,0 +1,3 @@ +terraform { + required_version = "~> 1.9.0" +} diff --git a/terraform/implementation/setup/README.md b/terraform/implementation/setup/README.md index da50e741..eafd7a44 100644 --- a/terraform/implementation/setup/README.md +++ b/terraform/implementation/setup/README.md @@ -3,7 +3,11 @@ | Name | Version | |------|---------| +| [terraform](#requirement\_terraform) | ~> 1.9.0 | | [aws](#requirement\_aws) | =5.70.0 | +| [aws](#requirement\_aws) | ~> 5.56.1 | +| [local](#requirement\_local) | ~> 2.5.0 | +| [random](#requirement\_random) | ~> 3.6.3 | ## Providers diff --git a/terraform/implementation/setup/main.tf b/terraform/implementation/setup/main.tf index 2d25ae0b..91cb3950 100644 --- a/terraform/implementation/setup/main.tf +++ b/terraform/implementation/setup/main.tf @@ -9,7 +9,6 @@ module "tfstate" { identifier = random_string.setup.result owner = var.owner project = var.project - region = var.region } # GitHub OIDC for prod diff --git a/terraform/implementation/setup/provider.tf b/terraform/implementation/setup/provider.tf new file mode 100644 index 00000000..59f52705 --- /dev/null +++ b/terraform/implementation/setup/provider.tf @@ -0,0 +1,17 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 5.56.1" + } + random = { + source = "hashicorp/random" + version = "~> 3.6.3" + } + local = { + source = "hashicorp/local" + version = "~> 2.5.0" + } + } + required_version = "~> 1.9.0" +} diff --git a/terraform/modules/oidc/README.md b/terraform/modules/oidc/README.md new file mode 100644 index 00000000..4ad8da10 --- /dev/null +++ b/terraform/modules/oidc/README.md @@ -0,0 +1,62 @@ + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | ~> 1.9.0 | +| [aws](#requirement\_aws) | ~> 5.56.1 | +| [random](#requirement\_random) | ~> 3.6.3 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | ~> 5.56.1 | +| [random](#provider\_random) | ~> 3.6.3 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_iam_policy.request_tags_create_actions](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | +| [aws_iam_policy.resource_tags_delete_actions](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | +| [aws_iam_policy.resource_tags_update_actions](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | +| [aws_iam_policy.scoped_one](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | +| [aws_iam_policy.scoped_two](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | +| [aws_iam_policy.storage](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | +| [aws_iam_policy.wildcard](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | +| [aws_iam_role.github](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | +| [random_string.oidc](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/string) | resource | +| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source | +| [aws_iam_policy_document.github_assume_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_iam_policy_document.request_tags_create_actions](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_iam_policy_document.resource_tags_delete_actions](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_iam_policy_document.resource_tags_update_actions](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_iam_policy_document.scoped_one](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_iam_policy_document.scoped_two](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_iam_policy_document.storage](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_iam_policy_document.wildcard](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [dynamodb\_table\_arn](#input\_dynamodb\_table\_arn) | The ARN of the DynamoDB table for state | `string` | `""` | no | +| [oidc\_github\_repo](#input\_oidc\_github\_repo) | The GitHub repository for OIDC | `string` | `""` | no | +| [owner](#input\_owner) | The owner of the project | `string` | `"skylight"` | no | +| [project](#input\_project) | The name of the project | `string` | `"dibbs"` | no | +| [region](#input\_region) | The AWS region where resources are created | `string` | `""` | no | +| [state\_bucket\_arn](#input\_state\_bucket\_arn) | The ARN of the S3 bucket for state | `string` | `""` | no | +| [vpc\_id](#input\_vpc\_id) | ID of the VPC | `string` | `""` | no | +| [workspace](#input\_workspace) | terraform workspace that OIDC will have permissions to | `string` | `""` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [role](#output\_role) | n/a | + \ No newline at end of file diff --git a/terraform/modules/oidc/_data.tf b/terraform/modules/oidc/_data.tf index 30819360..ee079ee9 100644 --- a/terraform/modules/oidc/_data.tf +++ b/terraform/modules/oidc/_data.tf @@ -38,9 +38,9 @@ data "aws_iam_policy_document" "storage" { ] resources = [ "arn:aws:s3:::*", - "${var.state_bucket_arn}", + var.state_bucket_arn, "${var.state_bucket_arn}/*", - "${var.dynamodb_table_arn}", + var.dynamodb_table_arn, ] } } diff --git a/terraform/modules/oidc/_local.tf b/terraform/modules/oidc/_local.tf index c5d5a73b..97b7f559 100644 --- a/terraform/modules/oidc/_local.tf +++ b/terraform/modules/oidc/_local.tf @@ -1,7 +1,6 @@ locals { github_role_name = "${var.project}-github-role-${var.owner}-${random_string.oidc.result}" project_owner_workspace = "${var.project}-${var.owner}-${var.workspace}" - workspace = var.workspace wildcard = "*" vpc_id = var.vpc_id == "" ? local.wildcard : var.vpc_id } \ No newline at end of file diff --git a/terraform/modules/oidc/provider.tf b/terraform/modules/oidc/provider.tf new file mode 100644 index 00000000..ab1a18bb --- /dev/null +++ b/terraform/modules/oidc/provider.tf @@ -0,0 +1,13 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 5.56.1" + } + random = { + source = "hashicorp/random" + version = "~> 3.6.3" + } + } + required_version = "~> 1.9.0" +} diff --git a/terraform/modules/tfstate/README.md b/terraform/modules/tfstate/README.md new file mode 100644 index 00000000..5a72bb50 --- /dev/null +++ b/terraform/modules/tfstate/README.md @@ -0,0 +1,43 @@ + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | ~> 1.9.0 | +| [aws](#requirement\_aws) | ~> 5.56.1 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | ~> 5.56.1 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_dynamodb_table.tfstate_lock](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/dynamodb_table) | resource | +| [aws_s3_bucket.tfstate](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket) | resource | +| [aws_s3_bucket_public_access_block.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_public_access_block) | resource | +| [aws_s3_bucket_server_side_encryption_configuration.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_server_side_encryption_configuration) | resource | +| [aws_s3_bucket_versioning.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_versioning) | resource | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [identifier](#input\_identifier) | n/a | `string` | `""` | no | +| [owner](#input\_owner) | The owner of the project | `string` | `"skylight"` | no | +| [project](#input\_project) | The name of the project | `string` | `"dibbs"` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [dynamodb\_table](#output\_dynamodb\_table) | n/a | +| [state\_bucket](#output\_state\_bucket) | n/a | + \ No newline at end of file diff --git a/terraform/modules/tfstate/_variable.tf b/terraform/modules/tfstate/_variable.tf index 514d742c..5f891b56 100644 --- a/terraform/modules/tfstate/_variable.tf +++ b/terraform/modules/tfstate/_variable.tf @@ -14,16 +14,6 @@ variable "project" { default = "dibbs" } -variable "region" { - type = string - description = "The AWS region where resources are created" - default = "" - validation { - condition = can(regex("^(us)-[[:alnum:]]{2,10}-[0-9]$", var.region)) - error_message = "region must be a valid AWS region" - } -} - variable "identifier" { type = string default = "" diff --git a/terraform/modules/tfstate/provider.tf b/terraform/modules/tfstate/provider.tf new file mode 100644 index 00000000..c7c2964f --- /dev/null +++ b/terraform/modules/tfstate/provider.tf @@ -0,0 +1,9 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 5.56.1" + } + } + required_version = "~> 1.9.0" +} diff --git a/terraform/utilities/generate_tf_docs.sh b/terraform/utilities/tfdocs.sh similarity index 69% rename from terraform/utilities/generate_tf_docs.sh rename to terraform/utilities/tfdocs.sh index 73962bdd..bec9282a 100755 --- a/terraform/utilities/generate_tf_docs.sh +++ b/terraform/utilities/tfdocs.sh @@ -1,5 +1,6 @@ #!/bin/bash -terraform-docs markdown table --output-file README.md --output-mode inject ../modules/ecs +terraform-docs markdown table --output-file README.md --output-mode inject ../modules/oidc +terraform-docs markdown table --output-file README.md --output-mode inject ../modules/tfstate terraform-docs markdown table --output-file README.md --output-mode inject ../implementation/ecs terraform-docs markdown table --output-file README.md --output-mode inject ../implementation/setup diff --git a/terraform/utilities/tf_fmt.sh b/terraform/utilities/tffmt.sh similarity index 100% rename from terraform/utilities/tf_fmt.sh rename to terraform/utilities/tffmt.sh diff --git a/terraform/utilities/tflint.sh b/terraform/utilities/tflint.sh new file mode 100755 index 00000000..a822ca05 --- /dev/null +++ b/terraform/utilities/tflint.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +tflint -f compact --chdir ../modules/oidc +tflint -f compact --chdir ../modules/tfstate +tflint -f compact --chdir ../implementation/setup +tflint -f compact --chdir ../implementation/ecs
"176.24.2.0/24",
"176.24.4.0/24"
]