diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 75f8f7b..6e1ef3b 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -6,21 +6,29 @@ RUN apt-get update && \ apt-transport-https \ ca-certificates \ curl \ - gnupg + gnupg \ + lsb-release SHELL [ "/bin/bash", "-o", "pipefail", "-c" ] # Install gcloud # ref: https://cloud.google.com/sdk/docs/install#deb RUN curl https://packages.cloud.google.com/apt/doc/apt-key.gpg \ - | gpg --dearmor -o /usr/share/keyrings/cloud.google.gpg -RUN echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] https://packages.cloud.google.com/apt cloud-sdk main" \ + | gpg --dearmor -o /usr/share/keyrings/cloud.google.gpg && \ + echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] https://packages.cloud.google.com/apt cloud-sdk main" \ | tee -a /etc/apt/sources.list.d/google-cloud-sdk.list +# Install Trivy +# ref: https://trivy.dev/dev/getting-started/installation/ +RUN curl https://aquasecurity.github.io/trivy-repo/deb/public.key | apt-key add - && \ + echo "deb https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -sc) main" \ + | tee -a /etc/apt/sources.list.d/trivy.list + # hadolint ignore=DL3008 RUN apt-get update && \ apt-get install -y --no-install-recommends \ - google-cloud-cli + google-cloud-cli \ + trivy FROM mcr.microsoft.com/vscode/devcontainers/base:bookworm @@ -29,4 +37,5 @@ LABEL maintainer="a5chin " COPY --from=builder --chown=vscode: /usr/bin/python* /usr/bin/python* COPY --from=builder --chown=vscode: /usr/bin/gcloud /usr/bin/gcloud +COPY --from=builder --chown=vscode: /usr/bin/trivy /usr/bin/trivy COPY --from=builder --chown=vscode: /usr/lib /usr/lib diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 044775b..de1e731 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -15,6 +15,7 @@ "customizations": { "vscode": { "extensions": [ + "aquasecurityofficial.trivy-vulnerability-scanner", "codezombiech.gitignore", "eamodio.gitlens", "exiasr.hadolint", diff --git a/.github/workflows/terraform-fmt.yml b/.github/workflows/terraform-fmt.yml deleted file mode 100644 index a4dc7a2..0000000 --- a/.github/workflows/terraform-fmt.yml +++ /dev/null @@ -1,20 +0,0 @@ -name: Terraform - -on: - push: - -jobs: - format: - runs-on: ubuntu-latest - - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Setup Terraform - uses: hashicorp/setup-terraform@v3 - with: - terraform_version: 1.9.8 - - - name: Terraform fmt - run: terraform fmt -check -recursive diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml new file mode 100644 index 0000000..f5cf53a --- /dev/null +++ b/.github/workflows/terraform.yml @@ -0,0 +1,118 @@ +name: Terraform + +on: + pull_request: + branches: [main] + push: + branches: [main] + +jobs: + setup: + runs-on: ubuntu-latest + + outputs: + matrix: ${{ steps.extract_modules.outputs.matrix }} + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Extract terraform modules + id: extract_modules + run: | + echo "matrix=$(ls modules | jq -R -s -c '{ "modules": split("\n")[:-1] }')" > $GITHUB_OUTPUT + + format: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Terraform + uses: hashicorp/setup-terraform@v3 + with: + terraform_version: 1.9.8 + + - name: Terraform fmt + run: terraform fmt -check -recursive + + lint: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - uses: actions/cache@v4 + name: Cache plugin dir + with: + path: ~/.tflint.d/plugins + key: ${{ matrix.os }}-tflint-${{ hashFiles('.tflint.hcl') }} + + - uses: terraform-linters/setup-tflint@v4 + name: Setup TFLint + with: + tflint_version: latest + + - name: Init TFLint + run: tflint --init + env: + GITHUB_TOKEN: ${{ github.token }} + + - name: tflint + run: tflint + + tests: + runs-on: ubuntu-latest + + needs: [setup] + + strategy: + fail-fast: false + matrix: ${{ fromJSON(needs.setup.outputs.matrix) }} + + defaults: + run: + working-directory: modules/${{ matrix.modules }} + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Terraform + uses: hashicorp/setup-terraform@v3 + with: + terraform_version: 1.9.8 + + - name: Run terraform test + run: | + terraform init + terraform test + + validate: + runs-on: ubuntu-latest + + needs: [setup] + + strategy: + fail-fast: false + matrix: ${{ fromJSON(needs.setup.outputs.matrix) }} + + defaults: + run: + working-directory: modules/${{ matrix.modules }} + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Terraform + uses: hashicorp/setup-terraform@v3 + with: + terraform_version: 1.9.8 + + - name: Terraform validate + run: | + terraform init + terraform validate diff --git a/.gitignore b/.gitignore index 2faf43d..c7ca3fd 100644 --- a/.gitignore +++ b/.gitignore @@ -10,8 +10,8 @@ crash.log crash.*.log # Exclude all .tfvars files, which are likely to contain sensitive data, such as -# password, private keys, and other secrets. These should not be part of version -# control as they are data points which are potentially sensitive and subject +# password, private keys, and other secrets. These should not be part of version +# control as they are data points which are potentially sensitive and subject # to change depending on the environment. *.tfvars *.tfvars.json @@ -35,3 +35,6 @@ override.tf.json # Ignore CLI configuration files .terraformrc terraform.rc + +# Ignore .terraform.lock.hcl files under modules directory +modules/*/.terraform.lock.hcl diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ea40af2..3b6ccd7 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -2,65 +2,17 @@ default_stages: [commit] repos: - repo: https://github.com/antonbabenko/pre-commit-terraform - rev: v1.96.1 + rev: "v1.96.1" hooks: + - id: terraform_docs + name: terraform-docs + description: "Run terraform-docs" + - id: terraform_fmt name: terraform-fmt description: "Run 'terraform fmt' for format" args: [recursive] - - repo: https://github.com/terraform-docs/terraform-docs - rev: "v0.18.0" - hooks: - - id: terraform-docs-go - name: terraform-docs-gcs2spanner - args: - [ - "markdown", - "table", - "--output-file", - "./README.md", - "./modules/gcs2spanner/", - ] - - - repo: https://github.com/terraform-docs/terraform-docs - rev: "v0.18.0" - hooks: - - id: terraform-docs-go - name: terraform-docs-log2bq - args: - [ - "markdown", - "table", - "--output-file", - "./README.md", - "./modules/log2bq/", - ] - - - repo: https://github.com/terraform-docs/terraform-docs - rev: "v0.18.0" - hooks: - - id: terraform-docs-go - name: terraform-docs-monitoring-tools - args: - [ - "markdown", - "table", - "--output-file", - "./README.md", - "./modules/monitoring-tools/", - ] - - - repo: https://github.com/terraform-docs/terraform-docs - rev: "v0.18.0" - hooks: - - id: terraform-docs-go - name: terraform-docs-microservices - args: - [ - "markdown", - "table", - "--output-file", - "./README.md", - "./modules/microservices/", - ] + - id: terraform_tflint + name: terraform-lint + description: "Run tflint" diff --git a/.tflint.hcl b/.tflint.hcl new file mode 100644 index 0000000..484cf20 --- /dev/null +++ b/.tflint.hcl @@ -0,0 +1,13 @@ +tflint { + required_version = ">= 0.50" +} + +config { + call_module_type = "all" +} + +plugin "google" { + enabled = true + version = "0.30.0" + source = "github.com/terraform-linters/tflint-ruleset-google" +} diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 67e1575..107ee69 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,5 +1,6 @@ { "recommendations": [ + "aquasecurityofficial.trivy-vulnerability-scanner", "codezombiech.gitignore", "eamodio.gitlens", "exiasr.hadolint", diff --git a/.vscode/settings.json b/.vscode/settings.json index 81306ce..044353b 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -34,6 +34,12 @@ "editor.formatOnSaveMode": "file", "editor.tabSize": 2 }, + "[terraform-test]": { + "editor.defaultFormatter": "hashicorp.terraform", + "editor.formatOnSave": true, + "editor.formatOnSaveMode": "file", + "editor.tabSize": 2 + }, "[terraform-vars]": { "editor.defaultFormatter": "hashicorp.terraform", "editor.formatOnSave": true, diff --git a/modules/gcs2spanner/README.md b/modules/gcs2spanner/README.md index 162d2f2..61f7c4e 100644 --- a/modules/gcs2spanner/README.md +++ b/modules/gcs2spanner/README.md @@ -24,7 +24,7 @@ No modules. | Name | Type | |------|------| -| [google-beta_google_project_service_identity.storage](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/google_project_service_identity) | resource | +| [google-beta_google_project_service_identity.storage](https://registry.terraform.io/providers/hashicorp/google-beta/latest/docs/resources/google_project_service_identity) | resource | | [google_cloud_run_v2_service_iam_member.event](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/cloud_run_v2_service_iam_member) | resource | | [google_cloudfunctions2_function.main](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/cloudfunctions2_function) | resource | | [google_compute_network.dataflow](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_network) | resource | @@ -41,19 +41,19 @@ No modules. | [google_storage_bucket.functions](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/storage_bucket) | resource | | [google_storage_bucket_iam_member.data](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/storage_bucket_iam_member) | resource | | [google_storage_bucket_object.functions](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/storage_bucket_object) | resource | -| [archive_file.functions](https://registry.terraform.io/providers/hashicorp/google/latest/docs/data-sources/file) | data source | +| [archive_file.functions](https://registry.terraform.io/providers/hashicorp/archive/latest/docs/data-sources/file) | data source | | [google_project.main](https://registry.terraform.io/providers/hashicorp/google/latest/docs/data-sources/project) | data source | ## Inputs | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| [dataflow](#input\_dataflow) | The Dataflow parameters |
object({
dataflow = object({
name = string
gcsPath = optional(string, "gs://dataflow-templates/2024-01-30-01_RC00/GCS_Avro_to_Cloud_Spanner")
temp_gcs_location = string
parameters = object({
instanceId = string
databaseId = string
subnetwork = string
})
sa = object({
id = string
})
})
})
| n/a | yes | -| [functions](#input\_functions) | The Cloud Functions parameter for creating Dataflow jobs,
using gcsPath as the Google-provided template available in the public GCS bucket |
object({
name = string
bucket = string
max_instance_count = optional(number, 1)
min_instance_count = optional(number, 0)
available_memory = optional(string, "512Mi")
timeout_seconds = optional(number, 60)
max_instance_request_concurrency = optional(number, 80)
available_cpu = optional(number, 1)
sa = object({
id = string
})
event = object({
sa = object({
id = string
})
})
})
| n/a | yes | -| [gcs](#input\_gcs) | The GCS parameters to receive aggregate data |
object({
name = string
lifecycle_rule = optional(
object({
age = number
action = string
}), {
age = 90
action = "Delete"
}
)
allows = set(string)
})
| n/a | yes | +| [dataflow](#input\_dataflow) | The Dataflow parameters |
object({
name = string
gcsPath = optional(string, "gs://dataflow-templates/2024-01-30-01_RC00/GCS_Avro_to_Cloud_Spanner")
temp_gcs_location = string
parameters = object({
instanceId = string
databaseId = string
subnetwork = string
})
sa = object({
id = string
})
})
| n/a | yes | +| [functions](#input\_functions) | The Cloud Functions parameter for creating Dataflow jobs,
using gcsPath as the Google-provided template available in the public GCS bucket |
object({
name = string
bucket = string
max_instance_count = optional(number, 1)
min_instance_count = optional(number, 0)
available_memory = optional(string, "512Mi")
timeout_seconds = optional(number, 60)
max_instance_request_concurrency = optional(number, 80)
available_cpu = optional(number, 1)
sa = object({
id = string
})
event = object({
sa = object({
id = string
})
})
})
| n/a | yes | +| [gcs](#input\_gcs) | The GCS parameters to receive aggregate data |
object({
name = string
lifecycle_rule = optional(
object({
age = number
action = string
}), {
age = 90
action = "Delete"
}
)
allows = set(string)
})
| n/a | yes | | [location](#input\_location) | The location of the Dataflow | `string` | n/a | yes | | [project\_id](#input\_project\_id) | The ID of the Project | `string` | n/a | yes | -| [vpc](#input\_vpc) | Settings for VPC |
object({
network = object({
name = string
})
subnetwork = object({
name = string
ip_cidr_range = string
})
})
| n/a | yes | +| [vpc](#input\_vpc) | Settings for VPC |
object({
network = object({
name = string
})
subnetwork = object({
name = string
ip_cidr_range = string
})
})
| n/a | yes | ## Outputs diff --git a/modules/gcs2spanner/dataflow.tf b/modules/gcs2spanner/dataflow.tf index ca80149..ea504b6 100644 --- a/modules/gcs2spanner/dataflow.tf +++ b/modules/gcs2spanner/dataflow.tf @@ -30,7 +30,7 @@ resource "google_project_iam_member" "dataflow" { for_each = local.dataflow_roles member = "serviceAccount:${google_service_account.dataflow.email}" - project = data.google_project.main.project_id + project = var.project_id role = each.value depends_on = [google_project_service.main] diff --git a/modules/gcs2spanner/functoins.tf b/modules/gcs2spanner/functoins.tf index 64f90f1..1efda81 100644 --- a/modules/gcs2spanner/functoins.tf +++ b/modules/gcs2spanner/functoins.tf @@ -7,9 +7,11 @@ locals { } resource "google_cloudfunctions2_function" "main" { - name = var.functions.name + project = var.project_id location = var.location + name = var.functions.name + build_config { runtime = "python310" entry_point = "create" @@ -59,8 +61,10 @@ resource "google_cloudfunctions2_function" "main" { } resource "google_storage_bucket" "functions" { + project = var.project_id + location = var.location + name = var.functions.bucket - location = var.location force_destroy = false public_access_prevention = "enforced" uniform_bucket_level_access = true @@ -93,7 +97,7 @@ resource "google_project_iam_member" "functions" { for_each = local.functions_roles member = "serviceAccount:${google_service_account.functions.email}" - project = data.google_project.main.project_id + project = var.project_id role = each.value depends_on = [google_project_service.main] diff --git a/modules/gcs2spanner/gcs.tf b/modules/gcs2spanner/gcs.tf index ddf9e14..cc71a80 100644 --- a/modules/gcs2spanner/gcs.tf +++ b/modules/gcs2spanner/gcs.tf @@ -6,8 +6,10 @@ locals { } resource "google_storage_bucket" "data" { + project = var.project_id + location = var.location + name = var.gcs.name - location = var.location force_destroy = false public_access_prevention = "enforced" uniform_bucket_level_access = true diff --git a/modules/gcs2spanner/main.tftest.hcl b/modules/gcs2spanner/main.tftest.hcl new file mode 100644 index 0000000..87166c7 --- /dev/null +++ b/modules/gcs2spanner/main.tftest.hcl @@ -0,0 +1,64 @@ +mock_provider "archive" {} +mock_provider "google" {} +mock_provider "google-beta" {} + +run "valid_roles" { + module { + source = "./" + } + + variables { + project_id = "project_id" + location = "location" + + dataflow = { + name = "name" + temp_gcs_location = "temp_gcs_location" + parameters = { + instanceId = "instanceId" + databaseId = "databaseId" + subnetwork = "subnetwork" + } + sa = { + id = "account-id" + } + } + + functions = { + name = "name" + bucket = "bucket" + sa = { + id = "account-id" + } + event = { + sa = { + id = "account-id" + } + } + } + + gcs = { + name = "name" + allows = [ + "serviceAccount:mail", "group:adress" + ] + } + + vpc = { + network = { + name = "name" + } + subnetwork = { + name = "name" + ip_cidr_range = "0.0.0.0/0" + } + } + } + + command = plan + + assert { + condition = length(google_storage_bucket_iam_member.data) == 4 + error_message = "Service accounts is not properly tied to roles" + } +} diff --git a/modules/gcs2spanner/provider.tf b/modules/gcs2spanner/provider.tf index ddd18da..f7b5121 100644 --- a/modules/gcs2spanner/provider.tf +++ b/modules/gcs2spanner/provider.tf @@ -3,7 +3,7 @@ terraform { required_providers { archive = { - source = "hashicorp/google" + source = "hashicorp/archive" version = ">=2.4.0" } google = { @@ -11,7 +11,7 @@ terraform { version = ">= 5.22.0" } google-beta = { - source = "hashicorp/google" + source = "hashicorp/google-beta" version = ">= 5.22.0" } } diff --git a/modules/gcs2spanner/sa.tf b/modules/gcs2spanner/sa.tf index 0edea0d..ed7df48 100644 --- a/modules/gcs2spanner/sa.tf +++ b/modules/gcs2spanner/sa.tf @@ -16,7 +16,7 @@ resource "google_project_iam_member" "event" { for_each = local.event_roles member = "serviceAccount:${google_service_account.event.email}" - project = data.google_project.main.project_id + project = var.project_id role = each.value depends_on = [google_project_service.main] @@ -35,14 +35,14 @@ resource "google_cloud_run_v2_service_iam_member" "event" { resource "google_project_service_identity" "storage" { provider = google-beta - project = data.google_project.main.project_id + project = var.project_id service = "storage.googleapis.com" depends_on = [google_project_service.main] } resource "google_project_iam_member" "gcs" { - project = data.google_project.main.project_id + project = var.project_id role = "roles/pubsub.publisher" member = "serviceAccount:service-${data.google_project.main.number}@gs-project-accounts.iam.gserviceaccount.com" diff --git a/modules/gcs2spanner/variables.tf b/modules/gcs2spanner/variables.tf index 241bb03..9732569 100644 --- a/modules/gcs2spanner/variables.tf +++ b/modules/gcs2spanner/variables.tf @@ -11,18 +11,16 @@ variable "location" { variable "dataflow" { description = "The Dataflow parameters" type = object({ - dataflow = object({ - name = string - gcsPath = optional(string, "gs://dataflow-templates/2024-01-30-01_RC00/GCS_Avro_to_Cloud_Spanner") - temp_gcs_location = string - parameters = object({ - instanceId = string - databaseId = string - subnetwork = string - }) - sa = object({ - id = string - }) + name = string + gcsPath = optional(string, "gs://dataflow-templates/2024-01-30-01_RC00/GCS_Avro_to_Cloud_Spanner") + temp_gcs_location = string + parameters = object({ + instanceId = string + databaseId = string + subnetwork = string + }) + sa = object({ + id = string }) }) } diff --git a/modules/gcs2spanner/vpc.tf b/modules/gcs2spanner/vpc.tf index ede71ee..249aeab 100644 --- a/modules/gcs2spanner/vpc.tf +++ b/modules/gcs2spanner/vpc.tf @@ -10,7 +10,7 @@ resource "google_compute_subnetwork" "dataflow" { region = var.location name = var.vpc.subnetwork.name - ip_cidr_range = var.vpc.ip_cidr_range + ip_cidr_range = var.vpc.subnetwork.ip_cidr_range network = google_compute_network.dataflow.self_link purpose = "PRIVATE" stack_type = "IPV4_ONLY" diff --git a/modules/log2bq/README.md b/modules/log2bq/README.md index 2f82151..28c9e4b 100644 --- a/modules/log2bq/README.md +++ b/modules/log2bq/README.md @@ -4,15 +4,13 @@ | Name | Version | |------|---------| | [terraform](#requirement\_terraform) | >=1.7 | -| [archive](#requirement\_archive) | >=2.4.0 | | [google](#requirement\_google) | >= 5.22.0 | -| [google-beta](#requirement\_google-beta) | >= 5.22.0 | ## Providers | Name | Version | |------|---------| -| [google](#provider\_google) | >= 5.22.0 | +| [google](#provider\_google) | 6.12.0 | ## Modules @@ -33,8 +31,8 @@ No modules. | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| [bigquery](#input\_bigquery) | The bigquery settings |
object({
dataset = string
table = string
view = string
expiration_days = number
})
| n/a | yes | -| [logging](#input\_logging) | n/a |
object({
target = string
filter = string
})
| n/a | yes | +| [bigquery](#input\_bigquery) | The bigquery settings |
object({
dataset = string
table = string
view = string
expiration_days = number
})
| n/a | yes | +| [logging](#input\_logging) | n/a |
object({
target = string
filter = string
})
| n/a | yes | ## Outputs diff --git a/modules/log2bq/provider.tf b/modules/log2bq/provider.tf index ddd18da..6c48087 100644 --- a/modules/log2bq/provider.tf +++ b/modules/log2bq/provider.tf @@ -2,17 +2,9 @@ terraform { required_version = ">=1.7" required_providers { - archive = { - source = "hashicorp/google" - version = ">=2.4.0" - } google = { source = "hashicorp/google" version = ">= 5.22.0" } - google-beta = { - source = "hashicorp/google" - version = ">= 5.22.0" - } } } diff --git a/modules/microservices/README.md b/modules/microservices/README.md index 827a9d9..11c3e5c 100644 --- a/modules/microservices/README.md +++ b/modules/microservices/README.md @@ -11,8 +11,8 @@ | Name | Version | |------|---------| -| [google](#provider\_google) | >= 5.22.0 | -| [google-beta](#provider\_google-beta) | >= 5.22.0 | +| [google](#provider\_google) | 6.12.0 | +| [google-beta](#provider\_google-beta) | 6.12.0 | ## Modules @@ -22,7 +22,7 @@ No modules. | Name | Type | |------|------| -| [google-beta_google_vpc_access_connector.main](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/google_vpc_access_connector) | resource | +| [google-beta_google_vpc_access_connector.main](https://registry.terraform.io/providers/hashicorp/google-beta/latest/docs/resources/google_vpc_access_connector) | resource | | [google_cloud_run_v2_service.backend](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/cloud_run_v2_service) | resource | | [google_cloud_run_v2_service.frontend](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/cloud_run_v2_service) | resource | | [google_cloud_run_v2_service_iam_member.backend_invoker](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/cloud_run_v2_service_iam_member) | resource | @@ -45,9 +45,9 @@ No modules. | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| [backend](#input\_backend) | The backend settings |
object({
name = string
image = string
max_instance_count = optional(number, 1)
min_instance_count = optional(number, 0)
concurrency = optional(number, 80)
timeout_seconds = optional(number, 60)
cpu = optional(string, "1000m")
memory = optional(string, "1024Mi")
env = object({
HOSTNAME = string
DB_USER = string
DB_PWD = string
DB_NAME = string
DB_TCPHOST = string
DB_PORT = number
})
executor = object({
id = string
roles = optional(
set(string), [
"roles/cloudsql.client",
"roles/cloudtrace.agent",
]
)
})
invoker = object({
ids = set(string)
emails = optional(
set(string), []
)
})
})
| n/a | yes | -| [db](#input\_db) | The Cloud SQL settings |
object({
instance_name = string
database_name = string
version = optional(string, "db-f1-micro")
charset = optional(string, "utf8mb4")
collation = optional(string, "utf8mb4_unicode_ci")
})
| n/a | yes | -| [frontend](#input\_frontend) | The frontend settings |
object({
name = string
image = string
max_instance_count = optional(number, 1)
min_instance_count = optional(number, 0)
concurrency = optional(number, 80)
timeout_seconds = optional(number, 60)
cpu = optional(string, "1000m")
memory = optional(string, "1024Mi")
executor = object({
id = string
roles = optional(
set(string), [
"roles/cloudtrace.agent",
]
)
})
invoker = object({
ids = set(string)
emails = optional(
set(string), []
)
})
})
| n/a | yes | +| [backend](#input\_backend) | The backend settings |
object({
name = string
image = string
max_instance_count = optional(number, 1)
min_instance_count = optional(number, 0)
concurrency = optional(number, 80)
timeout_seconds = optional(number, 60)
cpu = optional(string, "1000m")
memory = optional(string, "1024Mi")
env = object({
HOSTNAME = string
DB_USER = string
DB_PWD = string
DB_NAME = string
DB_TCPHOST = string
DB_PORT = number
})
executor = object({
id = string
roles = optional(
set(string), [
"roles/cloudsql.client",
"roles/cloudtrace.agent",
]
)
})
invoker = object({
ids = set(string)
emails = optional(
set(string), []
)
})
})
| n/a | yes | +| [db](#input\_db) | The Cloud SQL settings |
object({
instance_name = string
database_name = string
version = optional(string, "db-f1-micro")
charset = optional(string, "utf8mb4")
collation = optional(string, "utf8mb4_unicode_ci")
})
| n/a | yes | +| [frontend](#input\_frontend) | The frontend settings |
object({
name = string
image = string
max_instance_count = optional(number, 1)
min_instance_count = optional(number, 0)
concurrency = optional(number, 80)
timeout_seconds = optional(number, 60)
cpu = optional(string, "1000m")
memory = optional(string, "1024Mi")
executor = object({
id = string
roles = optional(
set(string), [
"roles/cloudtrace.agent",
]
)
})
invoker = object({
ids = set(string)
emails = optional(
set(string), []
)
})
})
| n/a | yes | | [location](#input\_location) | The location of the resource. | `string` | n/a | yes | | [project\_id](#input\_project\_id) | The ID of Google Cloud Platform. | `string` | n/a | yes | diff --git a/modules/microservices/db.tf b/modules/microservices/db.tf index ab3c079..feae91e 100644 --- a/modules/microservices/db.tf +++ b/modules/microservices/db.tf @@ -16,7 +16,7 @@ resource "google_sql_database_instance" "main" { } resource "google_sql_database" "main" { - name = var.db.name + name = var.db.database_name instance = google_sql_database_instance.main.name charset = var.db.charset collation = var.db.collation diff --git a/modules/microservices/frontend.tf b/modules/microservices/frontend.tf index 557a955..7a7954f 100644 --- a/modules/microservices/frontend.tf +++ b/modules/microservices/frontend.tf @@ -73,7 +73,7 @@ resource "google_service_account" "frontend_executor" { } resource "google_project_iam_member" "frontend_executor" { - for_each = var.project_id.executor.roles + for_each = var.frontend.executor.roles project = var.project_id role = each.value member = "serviceAccount:${google_service_account.frontend_executor.email}" diff --git a/modules/microservices/provider.tf b/modules/microservices/provider.tf index 3fffb54..b6ead8f 100644 --- a/modules/microservices/provider.tf +++ b/modules/microservices/provider.tf @@ -7,7 +7,7 @@ terraform { version = ">= 5.22.0" } google-beta = { - source = "hashicorp/google" + source = "hashicorp/google-beta" version = ">= 5.22.0" } } diff --git a/modules/monitoring-tools/README.md b/modules/monitoring-tools/README.md index 9a1d360..fb006f7 100644 --- a/modules/monitoring-tools/README.md +++ b/modules/monitoring-tools/README.md @@ -5,13 +5,12 @@ |------|---------| | [terraform](#requirement\_terraform) | >=1.7 | | [google](#requirement\_google) | >= 5.22.0 | -| [google-beta](#requirement\_google-beta) | >= 5.22.0 | ## Providers | Name | Version | |------|---------| -| [google](#provider\_google) | >= 5.22.0 | +| [google](#provider\_google) | 6.12.0 | ## Modules @@ -30,16 +29,14 @@ No modules. | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| [channels](#input\_channels) | Channel variable that contains `error` and `warn` as keys | `map(string)` | n/a | yes | -| [location](#input\_location) | The location of the resource. | `string` | n/a | yes | | [project\_id](#input\_project\_id) | The ID of Google Cloud Platform. | `string` | n/a | yes | -| [secrets](#input\_secrets) | The token required for notifications to Slack.
The variable is required for monitoring. | `string` | n/a | yes | -| [target](#input\_target) | The target information for monitoring.
`base_value` is used to calculate a numeric value based on the target resource.
Specifically, it is used to obtain a percentage, as in `floor(base_value * threshold.value)`. |
object({
title = string
metric = string
resource_type = string
label = string
name = string
filter = string
reducer = string
aligner = string
base_value = optional(number, 1)
threshold = map(
object({
value = number
window = string
})
)
})
| n/a | yes | +| [secrets](#input\_secrets) | The token required for notifications to Slack.
The variable is required for monitoring. | `string` | n/a | yes | +| [target](#input\_target) | The target information for monitoring.
`base_value` is used to calculate a numeric value based on the target resource.
Specifically, it is used to obtain a percentage, as in `floor(base_value * threshold.value)`. |
object({
title = string
metric = string
resource_type = string
label = string
name = string
filter = optional(string, "")
reducer = string
aligner = string
base_value = optional(number, 1)
alert = map(
object({
channel = string
window = string
value = number
})
)
})
| n/a | yes | ## Outputs | Name | Description | |------|-------------| | [enabled\_apis](#output\_enabled\_apis) | Already enabled APIs list. | -| [policies](#output\_policies) | Alert policies name object. | +| [policies](#output\_policies) | Alert policies name map. | \ No newline at end of file diff --git a/modules/monitoring-tools/alert.tf b/modules/monitoring-tools/alert.tf index eb59cb5..d5366ce 100644 --- a/modules/monitoring-tools/alert.tf +++ b/modules/monitoring-tools/alert.tf @@ -1,21 +1,23 @@ resource "google_monitoring_alert_policy" "main" { - for_each = local.levels + for_each = var.target.alert - display_name = "[${upper(each.value)}] ${var.target.name} ${var.target.title}" + project = var.project_id + + display_name = "[${upper(each.key)}] ${var.target.name} ${var.target.title}" conditions { - display_name = "[${upper(each.value)}] ${var.target.name} - ${var.target.title}" + display_name = "[${upper(each.key)}] ${var.target.name} - ${var.target.title}" condition_threshold { filter = < google_monitoring_alert_policy.main[k].name } } diff --git a/modules/monitoring-tools/provider.tf b/modules/monitoring-tools/provider.tf index 3fffb54..6c48087 100644 --- a/modules/monitoring-tools/provider.tf +++ b/modules/monitoring-tools/provider.tf @@ -6,9 +6,5 @@ terraform { source = "hashicorp/google" version = ">= 5.22.0" } - google-beta = { - source = "hashicorp/google" - version = ">= 5.22.0" - } } } diff --git a/modules/monitoring-tools/variables.tf b/modules/monitoring-tools/variables.tf index 74802ed..9c8b658 100644 --- a/modules/monitoring-tools/variables.tf +++ b/modules/monitoring-tools/variables.tf @@ -3,11 +3,6 @@ variable "project_id" { type = string } -variable "location" { - description = "The location of the resource." - type = string -} - variable "target" { description = <