diff --git a/.github/workflows/plan.yml b/.github/workflows/plan.yml index f5c545e..9e2ccbf 100644 --- a/.github/workflows/plan.yml +++ b/.github/workflows/plan.yml @@ -66,22 +66,24 @@ jobs: echo "::set-output name=plan::$out" continue-on-error: true - - uses: actions/github-script@v5 + - name: Post comment with Terraform plan + uses: actions/github-script@v5 with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | - const output = `#### Terraform Plan 📖\`${{ steps.plan.outcome }}\` + const output = `#### Terraform Plan 📖 + \`${{ steps.plan.outcome }}\`
Show Plan - \`\`\`terraform\n + \`\`\`terraform ${{ steps.plan.outputs.plan }} - \n\`\`\` + \`\`\` -
+ `; github.rest.issues.createComment({ issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, body: output - }) + }); diff --git a/modules/cloudrun/main.tf b/modules/cloudrun/main.tf index 5501eeb..9706c07 100644 --- a/modules/cloudrun/main.tf +++ b/modules/cloudrun/main.tf @@ -21,15 +21,16 @@ data "docker_registry_image" "image" { } resource "google_cloud_run_service" "cloudrun" { - count = length(var.regions) - name = format("%s-%s", var.name, var.regions[count.index]) - location = var.regions[count.index] + for_each = toset(var.regions) + name = var.name + location = each.value lifecycle { ignore_changes = [ metadata[0].annotations["run.googleapis.com/launch-stage"], metadata[0].effective_annotations["run.googleapis.com/launch-stage"] ] + create_before_destroy = true } metadata { @@ -110,24 +111,27 @@ resource "google_cloud_run_service" "cloudrun" { } resource "google_cloud_run_service_iam_member" "invoker" { - count = length(var.regions) - location = google_cloud_run_service.cloudrun[count.index].location - service = google_cloud_run_service.cloudrun[count.index].name + for_each = toset(var.regions) + location = each.value + service = google_cloud_run_service.cloudrun[each.value].name role = "roles/run.invoker" member = "allUsers" } # create a serverless NEG for this set of regional services resource "google_compute_region_network_endpoint_group" "neg" { - count = length(var.regions) - - name = "libops-neg-${google_cloud_run_service.cloudrun[count.index].name}" + for_each = toset(var.regions) + name = "libops-neg-${var.name}-${each.value}" network_endpoint_type = "SERVERLESS" - region = google_cloud_run_service.cloudrun[count.index].location + region = each.value project = var.project cloud_run { - service = google_cloud_run_service.cloudrun[count.index].name + service = google_cloud_run_service.cloudrun[each.value].name + } + + lifecycle { + create_before_destroy = true } } diff --git a/modules/lb/dashboard.json b/modules/lb/dashboard.json index fba6a6c..44a40cb 100644 --- a/modules/lb/dashboard.json +++ b/modules/lb/dashboard.json @@ -1,306 +1,346 @@ { - "displayName": "Cloud CDN", - "mosaicLayout": { - "columns": 12, - "tiles": [ + "displayName": "Cloud Run Monitoring", + "gridLayout": { + "columns": "2", + "widgets": [ { - "height": 4, - "widget": { - "title": "Request Count by Continent", - "xyChart": { - "chartOptions": { - "mode": "COLOR" - }, - "dataSets": [ - { - "plotType": "STACKED_AREA", - "timeSeriesQuery": { - "timeSeriesQueryLanguage": "fetch https_lb_rule\n| metric 'loadbalancing.googleapis.com/https/request_count'\n| align rate(1m)\n| every 1m\n| group_by [metric.proxy_continent],\n [row_count: row_count()]" - } - } - ], - "timeshiftDuration": "0s", - "yAxis": { - "scale": "LINEAR" - } - } + "title": "Request Count", + "xyChart": { + "chartOptions": { + "mode": "COLOR" }, - "width": 6, - "yPos": 8 - }, - { - "height": 4, - "widget": { - "title": "Cache Hit Response Bytes by Continent", - "xyChart": { - "chartOptions": { - "mode": "COLOR" - }, - "dataSets": [ - { - "plotType": "STACKED_BAR", - "timeSeriesQuery": { - "timeSeriesQueryLanguage": "fetch https_lb_rule\n| metric 'loadbalancing.googleapis.com/https/response_bytes_count'\n| filter (metric.cache_result = 'HIT')\n| align rate(1m)\n| every 1m\n| group_by [metric.proxy_continent],\n [value_response_bytes_count_aggregate:\n aggregate(value.response_bytes_count)]" - } - } - ], - "timeshiftDuration": "0s", - "yAxis": { - "scale": "LINEAR" + "dataSets": [ + { + "minAlignmentPeriod": "60s", + "plotType": "STACKED_BAR", + "timeSeriesQuery": { + "timeSeriesFilter": { + "aggregation": { + "crossSeriesReducer": "REDUCE_COUNT", + "perSeriesAligner": "ALIGN_RATE" + }, + "filter": "metric.type=\"run.googleapis.com/request_count\" resource.type=\"cloud_run_revision\"", + "secondaryAggregation": {} + }, + "unitOverride": "1" } + } + ], + "timeshiftDuration": "0s", + "yAxis": { + "scale": "LINEAR" } - }, - "width": 6, - "xPos": 6, - "yPos": 4 + } }, { - "height": 4, - "widget": { - "title": "Cache Status by Count", - "xyChart": { - "chartOptions": { - "mode": "COLOR" - }, - "dataSets": [ - { - "plotType": "LINE", - "timeSeriesQuery": { - "timeSeriesQueryLanguage": "fetch https_lb_rule\n| metric 'loadbalancing.googleapis.com/https/request_count'\n| align rate(1m)\n| every 1m\n| group_by [metric.cache_result],\n [row_count: row_count()]\n" - } - } - ], - "timeshiftDuration": "0s", - "yAxis": { - "scale": "LINEAR" - } - } + "title": "Request Latency", + "xyChart": { + "chartOptions": { + "mode": "COLOR" }, - "width": 6, - "yPos": 4 - }, - { - "height": 4, - "widget": { - "title": "Response Egress by Cache Status", - "xyChart": { - "chartOptions": { - "mode": "COLOR" - }, - "dataSets": [ - { - "plotType": "STACKED_AREA", - "timeSeriesQuery": { - "timeSeriesQueryLanguage": "fetch https_lb_rule\n| metric 'loadbalancing.googleapis.com/https/response_bytes_count'\n| align rate(1m)\n| every 1m\n| group_by [metric.cache_result],\n [value_response_bytes_count_aggregate:\n aggregate(value.response_bytes_count)]" - } + "dataSets": [ + { + "minAlignmentPeriod": "60s", + "plotType": "LINE", + "timeSeriesQuery": { + "timeSeriesFilter": { + "aggregation": { + "crossSeriesReducer": "REDUCE_PERCENTILE_95", + "perSeriesAligner": "ALIGN_DELTA" + }, + "filter": "metric.type=\"run.googleapis.com/request_latencies\" resource.type=\"cloud_run_revision\"", + "secondaryAggregation": {} + }, + "unitOverride": "ms" } - ], - "timeshiftDuration": "0s", - "yAxis": { - "scale": "LINEAR" + }, + { + "minAlignmentPeriod": "60s", + "plotType": "LINE", + "timeSeriesQuery": { + "timeSeriesFilter": { + "aggregation": { + "crossSeriesReducer": "REDUCE_PERCENTILE_05", + "perSeriesAligner": "ALIGN_DELTA" + }, + "filter": "metric.type=\"run.googleapis.com/request_latencies\" resource.type=\"cloud_run_revision\"", + "secondaryAggregation": {} + }, + "unitOverride": "ms" } - } - }, - "width": 6, - "xPos": 6 - }, - { - "height": 4, - "widget": { - "title": "Latency by Continent 95%", - "xyChart": { - "chartOptions": { - "mode": "COLOR" - }, - "dataSets": [ - { - "plotType": "LINE", - "timeSeriesQuery": { - "timeSeriesQueryLanguage": "fetch https_lb_rule\n| metric 'loadbalancing.googleapis.com/https/frontend_tcp_rtt'\n| group_by 1m,\n [value_frontend_tcp_rtt_aggregate: aggregate(value.frontend_tcp_rtt)]\n| every 1m\n| group_by [metric.proxy_continent],\n [value_frontend_tcp_rtt_aggregate_percentile:\n percentile(value_frontend_tcp_rtt_aggregate, 95)]" - } + }, + { + "minAlignmentPeriod": "60s", + "plotType": "LINE", + "timeSeriesQuery": { + "timeSeriesFilter": { + "aggregation": { + "crossSeriesReducer": "REDUCE_PERCENTILE_50", + "perSeriesAligner": "ALIGN_DELTA" + }, + "filter": "metric.type=\"run.googleapis.com/request_latencies\" resource.type=\"cloud_run_revision\"", + "secondaryAggregation": {} + }, + "unitOverride": "ms" } - ], - "timeshiftDuration": "0s", - "yAxis": { - "scale": "LINEAR" + }, + { + "minAlignmentPeriod": "60s", + "plotType": "LINE", + "timeSeriesQuery": { + "timeSeriesFilter": { + "aggregation": { + "crossSeriesReducer": "REDUCE_MAX", + "perSeriesAligner": "ALIGN_PERCENTILE_99" + }, + "filter": "metric.type=\"run.googleapis.com/request_latencies\" resource.type=\"cloud_run_revision\"", + "secondaryAggregation": {} + }, + "unitOverride": "ms" } + } + ], + "timeshiftDuration": "0s", + "yAxis": { + "scale": "LINEAR" } - }, - "width": 6, - "yPos": 12 + } }, { - "height": 4, - "widget": { - "title": "Client Response Code", - "xyChart": { - "chartOptions": { - "mode": "COLOR" - }, - "dataSets": [ - { - "plotType": "STACKED_AREA", - "timeSeriesQuery": { - "timeSeriesQueryLanguage": "fetch https_lb_rule\n| metric 'loadbalancing.googleapis.com/https/request_count'\n| group_by 1h, [row_count: row_count()]\n| every 1h\n| group_by [metric.response_code_class],\n [row_count_aggregate: aggregate(row_count)]" - } - } - ], - "timeshiftDuration": "0s", - "yAxis": { - "scale": "LINEAR" + "title": "Billable Instance Time", + "xyChart": { + "chartOptions": { + "mode": "COLOR" + }, + "dataSets": [ + { + "minAlignmentPeriod": "60s", + "plotType": "LINE", + "timeSeriesQuery": { + "timeSeriesFilter": { + "aggregation": { + "crossSeriesReducer": "REDUCE_SUM", + "perSeriesAligner": "ALIGN_RATE" + }, + "filter": "metric.type=\"run.googleapis.com/container/billable_instance_time\" resource.type=\"cloud_run_revision\"", + "secondaryAggregation": {} + }, + "unitOverride": "s" } + } + ], + "timeshiftDuration": "0s", + "yAxis": { + "scale": "LINEAR" } - }, - "width": 6, - "xPos": 6, - "yPos": 8 + } }, { - "height": 4, - "widget": { - "title": "Non 2xx Error Codes", - "xyChart": { - "chartOptions": { - "mode": "COLOR" - }, - "dataSets": [ - { - "plotType": "STACKED_AREA", - "timeSeriesQuery": { - "timeSeriesQueryLanguage": "fetch https_lb_rule\n| metric 'loadbalancing.googleapis.com/https/request_count'\n| filter (metric.response_code_class != 200)\n| group_by 1h, [row_count: row_count()]\n| every 1h\n| group_by [metric.response_code_class],\n [row_count_aggregate: aggregate(row_count)]" - } - } - ], - "timeshiftDuration": "0s", - "yAxis": { - "scale": "LINEAR" + "title": "Container CPU Allocation", + "xyChart": { + "chartOptions": { + "mode": "COLOR" + }, + "dataSets": [ + { + "minAlignmentPeriod": "60s", + "plotType": "LINE", + "timeSeriesQuery": { + "timeSeriesFilter": { + "aggregation": { + "crossSeriesReducer": "REDUCE_SUM", + "perSeriesAligner": "ALIGN_RATE" + }, + "filter": "metric.type=\"run.googleapis.com/container/cpu/allocation_time\" resource.type=\"cloud_run_revision\"", + "secondaryAggregation": {} + }, + "unitOverride": "s" } + } + ], + "timeshiftDuration": "0s", + "yAxis": { + "scale": "LINEAR" } - }, - "width": 6, - "xPos": 6, - "yPos": 12 + } }, { - "height": 2, - "widget": { - "scorecard": { + "title": "Container Memory Allocation", + "xyChart": { + "chartOptions": { + "mode": "COLOR" + }, + "dataSets": [ + { + "minAlignmentPeriod": "60s", + "plotType": "LINE", "timeSeriesQuery": { - "timeSeriesFilter": { + "timeSeriesFilter": { "aggregation": { - "alignmentPeriod": "60s", - "crossSeriesReducer": "REDUCE_SUM", - "perSeriesAligner": "ALIGN_SUM" + "crossSeriesReducer": "REDUCE_SUM", + "perSeriesAligner": "ALIGN_RATE" }, - "filter": "metric.type=\"loadbalancing.googleapis.com/https/request_count\" resource.type=\"https_lb_rule\"" - } + "filter": "metric.type=\"run.googleapis.com/container/memory/allocation_time\" resource.type=\"cloud_run_revision\"", + "secondaryAggregation": {} + }, + "unitOverride": "GiBy.s" } - }, - "title": "Total Requests" - }, - "width": 3 + } + ], + "timeshiftDuration": "0s", + "yAxis": { + "scale": "LINEAR" + } + } }, { - "height": 2, - "widget": { - "scorecard": { + "title": "Container CPU Utilization", + "xyChart": { + "chartOptions": { + "mode": "COLOR" + }, + "dataSets": [ + { + "minAlignmentPeriod": "60s", + "plotType": "LINE", "timeSeriesQuery": { - "timeSeriesFilter": { + "timeSeriesFilter": { "aggregation": { - "alignmentPeriod": "60s", - "crossSeriesReducer": "REDUCE_SUM", - "perSeriesAligner": "ALIGN_SUM" + "crossSeriesReducer": "REDUCE_PERCENTILE_95", + "perSeriesAligner": "ALIGN_DELTA" }, - "filter": "metric.type=\"loadbalancing.googleapis.com/https/response_bytes_count\" resource.type=\"https_lb_rule\"" + "filter": "metric.type=\"run.googleapis.com/container/cpu/utilizations\" resource.type=\"cloud_run_revision\"", + "secondaryAggregation": {} + }, + "unitOverride": "10^2.%" } + }, + { + "minAlignmentPeriod": "60s", + "plotType": "LINE", + "timeSeriesQuery": { + "timeSeriesFilter": { + "aggregation": { + "crossSeriesReducer": "REDUCE_PERCENTILE_05", + "perSeriesAligner": "ALIGN_DELTA" + }, + "filter": "metric.type=\"run.googleapis.com/container/cpu/utilizations\" resource.type=\"cloud_run_revision\"", + "secondaryAggregation": {} + }, + "unitOverride": "10^2.%" } - }, - "title": "Total Egress" - }, - "width": 3, - "xPos": 3 - }, - { - "height": 2, - "widget": { - "scorecard": { + }, + { + "minAlignmentPeriod": "60s", + "plotType": "LINE", "timeSeriesQuery": { - "timeSeriesFilter": { + "timeSeriesFilter": { "aggregation": { - "alignmentPeriod": "60s", - "crossSeriesReducer": "REDUCE_SUM", - "perSeriesAligner": "ALIGN_SUM" + "crossSeriesReducer": "REDUCE_PERCENTILE_50", + "perSeriesAligner": "ALIGN_DELTA" }, - "filter": "metric.type=\"loadbalancing.googleapis.com/https/response_bytes_count\" resource.type=\"https_lb_rule\" metric.label.\"cache_result\"=\"HIT\"" + "filter": "metric.type=\"run.googleapis.com/container/cpu/utilizations\" resource.type=\"cloud_run_revision\"", + "secondaryAggregation": {} + }, + "unitOverride": "10^2.%" } + }, + { + "minAlignmentPeriod": "60s", + "plotType": "LINE", + "timeSeriesQuery": { + "timeSeriesFilter": { + "aggregation": { + "crossSeriesReducer": "REDUCE_MAX", + "perSeriesAligner": "ALIGN_PERCENTILE_99" + }, + "filter": "metric.type=\"run.googleapis.com/container/cpu/utilizations\" resource.type=\"cloud_run_revision\"", + "secondaryAggregation": {} + }, + "unitOverride": "10^2.%" } - }, - "title": "Cache Hit Egress" - }, - "width": 3, - "yPos": 2 + } + ], + "timeshiftDuration": "0s", + "yAxis": { + "scale": "LINEAR" + } + } }, { - "height": 2, - "widget": { - "scorecard": { + "title": "Container Memory Utilization", + "xyChart": { + "chartOptions": { + "mode": "COLOR" + }, + "dataSets": [ + { + "minAlignmentPeriod": "60s", + "plotType": "LINE", "timeSeriesQuery": { - "timeSeriesFilter": { + "timeSeriesFilter": { "aggregation": { - "alignmentPeriod": "60s", - "crossSeriesReducer": "REDUCE_SUM", - "perSeriesAligner": "ALIGN_SUM" + "crossSeriesReducer": "REDUCE_PERCENTILE_99", + "perSeriesAligner": "ALIGN_DELTA" }, - "filter": "metric.type=\"loadbalancing.googleapis.com/https/response_bytes_count\" resource.type=\"https_lb_rule\" metric.label.\"cache_result\"=\"MISS\"" + "filter": "metric.type=\"run.googleapis.com/container/memory/utilizations\" resource.type=\"cloud_run_revision\"", + "secondaryAggregation": {} + }, + "unitOverride": "10^2.%" } + }, + { + "minAlignmentPeriod": "60s", + "plotType": "LINE", + "timeSeriesQuery": { + "timeSeriesFilter": { + "aggregation": { + "crossSeriesReducer": "REDUCE_PERCENTILE_05", + "perSeriesAligner": "ALIGN_DELTA" + }, + "filter": "metric.type=\"run.googleapis.com/container/memory/utilizations\" resource.type=\"cloud_run_revision\"", + "secondaryAggregation": {} + }, + "unitOverride": "10^2.%" } - }, - "title": "Cache Miss Egress" - }, - "width": 3, - "xPos": 3, - "yPos": 2 - }, - { - "height": 4, - "widget": { - "title": "Request Count by Country", - "xyChart": { - "chartOptions": { - "mode": "COLOR" - }, - "dataSets": [ - { - "minAlignmentPeriod": "60s", - "plotType": "STACKED_AREA", - "timeSeriesQuery": { - "timeSeriesFilter": { - "aggregation": { - "alignmentPeriod": "60s", - "perSeriesAligner": "ALIGN_RATE" - }, - "filter": "metric.type=\"loadbalancing.googleapis.com/https/request_count\" resource.type=\"https_lb_rule\"", - "secondaryAggregation": { - "alignmentPeriod": "60s", - "crossSeriesReducer": "REDUCE_SUM", - "groupByFields": [ - "metric.label.\"client_country\"" - ], - "perSeriesAligner": "ALIGN_SUM" - } - } - } + }, + { + "minAlignmentPeriod": "60s", + "plotType": "LINE", + "timeSeriesQuery": { + "timeSeriesFilter": { + "aggregation": { + "crossSeriesReducer": "REDUCE_PERCENTILE_50", + "perSeriesAligner": "ALIGN_DELTA" + }, + "filter": "metric.type=\"run.googleapis.com/container/memory/utilizations\" resource.type=\"cloud_run_revision\"", + "secondaryAggregation": {} + }, + "unitOverride": "10^2.%" } - ], - "timeshiftDuration": "0s", - "yAxis": { - "scale": "LINEAR" + }, + { + "minAlignmentPeriod": "60s", + "plotType": "LINE", + "timeSeriesQuery": { + "timeSeriesFilter": { + "aggregation": { + "crossSeriesReducer": "REDUCE_MAX", + "perSeriesAligner": "ALIGN_PERCENTILE_99" + }, + "filter": "metric.type=\"run.googleapis.com/container/memory/utilizations\" resource.type=\"cloud_run_revision\"", + "secondaryAggregation": {} + }, + "unitOverride": "10^2.%" } + } + ], + "timeshiftDuration": "0s", + "yAxis": { + "scale": "LINEAR" } - }, - "width": 6, - "yPos": 16 + } } - ] + ] } -} \ No newline at end of file + } \ No newline at end of file