Merge branch 'master' into lcaggio/fix-20221123
This commit is contained in:
commit
d1cc0519d8
|
@ -11,3 +11,16 @@
|
|||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
'on:blueprints':
|
||||
- blueprints/**/*
|
||||
'on:documentation':
|
||||
- '**/*.md'
|
||||
- assets/**/*
|
||||
- tests/**/*
|
||||
'on:FAST':
|
||||
- fast/**/*
|
||||
'on:modules':
|
||||
- modules/**/*
|
||||
'on:tools':
|
||||
- tools/**/*
|
|
@ -12,23 +12,19 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import pytest
|
||||
name: "Build and push the Squid container image"
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
paths:
|
||||
- 'modules/cloud-config-container/squid/docker/**'
|
||||
|
||||
@pytest.fixture
|
||||
def resources(plan_runner):
|
||||
_, resources = plan_runner()
|
||||
return resources
|
||||
|
||||
|
||||
def test_resource_count(resources):
|
||||
"Test number of resources created."
|
||||
assert len(resources) == 3
|
||||
|
||||
|
||||
def test_iam(resources):
|
||||
"Test IAM binding resources."
|
||||
bindings = [r['values'] for r in resources if r['type']
|
||||
== 'google_cloudfunctions_function_iam_binding']
|
||||
assert len(bindings) == 1
|
||||
assert bindings[0]['role'] == 'roles/cloudfunctions.invoker'
|
||||
jobs:
|
||||
build-push-squid-container-image:
|
||||
uses: ./.github/workflows/container-image.yml
|
||||
with:
|
||||
image_name: fabric-squid
|
||||
docker_context: modules/cloud-config-container/squid/docker
|
|
@ -0,0 +1,30 @@
|
|||
# Copyright 2022 Google LLC
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
name: "Build and push the strongSwan container image"
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
paths:
|
||||
- 'modules/cloud-config-container/onprem/docker-images/strongswan/**'
|
||||
|
||||
jobs:
|
||||
build-push-strongswan-container-image:
|
||||
uses: ./.github/workflows/container-image.yml
|
||||
with:
|
||||
image_name: fabric-strongswan
|
||||
docker_context: modules/cloud-config-container/onprem/docker-images/strongswan
|
|
@ -0,0 +1,30 @@
|
|||
# Copyright 2022 Google LLC
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
name: "Build and push the Toolbox container image"
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
paths:
|
||||
- 'modules/cloud-config-container/onprem/docker-images/toolbox/**'
|
||||
|
||||
jobs:
|
||||
build-push-toolbox-container-image:
|
||||
uses: ./.github/workflows/container-image.yml
|
||||
with:
|
||||
image_name: fabric-toolbox
|
||||
docker_context: modules/cloud-config-container/onprem/docker-images/toolbox
|
|
@ -0,0 +1,61 @@
|
|||
# Copyright 2022 Google LLC
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
name: "Build and push a generic container image"
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
image_name:
|
||||
required: true
|
||||
type: string
|
||||
docker_context:
|
||||
required: true
|
||||
type: string
|
||||
|
||||
permissions:
|
||||
packages: write
|
||||
|
||||
env:
|
||||
REGISTRY: ghcr.io
|
||||
|
||||
jobs:
|
||||
build-push-generic-container-image:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Get current date
|
||||
id: date
|
||||
run: echo "::set-output name=date::$(date +'%Y%m%d')"
|
||||
|
||||
- name: Normalise image name
|
||||
run: |
|
||||
echo IMAGE_NAME=$(echo '${{ github.repository_owner }}/${{ inputs.image_name }}' | tr '[:upper:]' '[:lower:]') >> $GITHUB_ENV
|
||||
|
||||
- name: Login to GHCR
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v3
|
||||
with:
|
||||
context: ${{ inputs.docker_context }}
|
||||
push: true
|
||||
tags: |
|
||||
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
|
||||
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.date.outputs.date }}
|
|
@ -0,0 +1,30 @@
|
|||
# Copyright 2022 Google LLC
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
name: "Label Pull Requests"
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
|
||||
jobs:
|
||||
triage:
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/labeler@v4
|
||||
with:
|
||||
repo-token: "${{ secrets.GITHUB_TOKEN }}"
|
||||
sync-labels: true
|
|
@ -37,3 +37,8 @@ examples/cloud-operations/adfs/ansible/gssh.sh
|
|||
examples/cloud-operations/multi-cluster-mesh-gke-fleet-api/ansible/vars.yaml
|
||||
examples/cloud-operations/multi-cluster-mesh-gke-fleet-api/ansible/gssh.sh
|
||||
blueprints/cloud-operations/network-dashboard/cloud-function.zip
|
||||
blueprints/cloud-operations/apigee/bundle-export.zip
|
||||
blueprints/cloud-operations/apigee/bundle-gcs2bq.zip
|
||||
blueprints/cloud-operations/apigee/apiproxy.zip
|
||||
blueprints/cloud-operations/apigee/create-datastore.sh
|
||||
blueprints/cloud-operations/apigee/deploy-apiproxy.sh
|
||||
|
|
41
CHANGELOG.md
41
CHANGELOG.md
|
@ -5,15 +5,22 @@ All notable changes to this project will be documented in this file.
|
|||
|
||||
## [Unreleased]
|
||||
<!-- None < 2022-09-09 18:02:15+00:00 -->
|
||||
- [[#913](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/913)] Adding support for PSA ranges, starting with Redis instances. ([aurelienlegrand](https://github.com/aurelienlegrand)) <!-- 2022-11-09 11:07:41+00:00 -->
|
||||
- [[#939](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/939)] Temporarily duplicate cloud armor example ([ludoo](https://github.com/ludoo)) <!-- 2022-11-02 09:36:04+00:00 -->
|
||||
|
||||
### BLUEPRINTS
|
||||
|
||||
- [[#1003](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1003)] Normalize prefix handling in blueprints ([kunzese](https://github.com/kunzese)) <!-- 2022-11-23 10:09:00+00:00 -->
|
||||
- [[#995](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/995)] Push container images to GitHub instead of Google Container Registry ([kunzese](https://github.com/kunzese)) <!-- 2022-11-21 14:53:52+00:00 -->
|
||||
- [[#984](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/984)] **incompatible change:** Apigee module and blueprint ([apichick](https://github.com/apichick)) <!-- 2022-11-17 16:20:27+00:00 -->
|
||||
- [[#980](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/980)] Have Squid log to /dev/stdout to stream logs to Cloud Logging ([kunzese](https://github.com/kunzese)) <!-- 2022-11-16 13:41:26+00:00 -->
|
||||
- [[#929](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/929)] Updated list of enabled APIs for network dashboard ([maunope](https://github.com/maunope)) <!-- 2022-11-16 09:27:44+00:00 -->
|
||||
- [[#968](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/968)] Enforce PROXY protocol in `filtering-proxy-psc` blueprint ([kunzese](https://github.com/kunzese)) <!-- 2022-11-15 07:18:58+00:00 -->
|
||||
- [[#962](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/962)] Add filtering-proxy-psc blueprint ([kunzese](https://github.com/kunzese)) <!-- 2022-11-11 10:24:38+00:00 -->
|
||||
- [[#913](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/913)] Adding support for PSA ranges, starting with Redis instances. ([aurelienlegrand](https://github.com/aurelienlegrand)) <!-- 2022-11-09 11:07:41+00:00 -->
|
||||
- [[#952](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/952)] Remove duplicate GLB+CA blueprint folder ([ludoo](https://github.com/ludoo)) <!-- 2022-11-07 12:46:22+00:00 -->
|
||||
- [[#949](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/949)] **incompatible change:** Refactor VPC firewall module for Terraform 1.3 ([ludoo](https://github.com/ludoo)) <!-- 2022-11-04 12:56:08+00:00 -->
|
||||
- [[#945](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/945)] Org policy factory ([juliocc](https://github.com/juliocc)) <!-- 2022-11-03 11:30:58+00:00 -->
|
||||
- [[#941](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/941)] **incompatible change:** Refactor ILB module for Terraform 1.3 ([ludoo](https://github.com/ludoo)) <!-- 2022-11-02 17:05:21+00:00 -->
|
||||
- [[#939](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/939)] Temporarily duplicate cloud armor example ([ludoo](https://github.com/ludoo)) <!-- 2022-11-02 09:36:04+00:00 -->
|
||||
- [[#936](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/936)] Enable org policy service and add README notice to modules ([ludoo](https://github.com/ludoo)) <!-- 2022-11-01 13:25:08+00:00 -->
|
||||
- [[#931](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/931)] **incompatible change:** Refactor compute-mig module for Terraform 1.3 ([ludoo](https://github.com/ludoo)) <!-- 2022-11-01 08:39:00+00:00 -->
|
||||
- [[#932](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/932)] feat(project-factory): introduce additive iam bindings to project-fac… ([Malet](https://github.com/Malet)) <!-- 2022-10-31 17:24:25+00:00 -->
|
||||
|
@ -53,6 +60,10 @@ All notable changes to this project will be documented in this file.
|
|||
|
||||
### DOCUMENTATION
|
||||
|
||||
- [[#1007](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1007)] fast README, one line fix: 00-cicd stage got moved to extras/ ([skalolazka](https://github.com/skalolazka)) <!-- 2022-11-23 15:31:01+00:00 -->
|
||||
- [[#1003](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1003)] Normalize prefix handling in blueprints ([kunzese](https://github.com/kunzese)) <!-- 2022-11-23 10:09:00+00:00 -->
|
||||
- [[#987](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/987)] Add tests to factory examples ([juliocc](https://github.com/juliocc)) <!-- 2022-11-18 17:01:41+00:00 -->
|
||||
- [[#972](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/972)] Add note about TF_PLUGIN_CACHE_DIR ([wiktorn](https://github.com/wiktorn)) <!-- 2022-11-14 10:21:37+00:00 -->
|
||||
- [[#961](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/961)] Remove extra file from root ([ludoo](https://github.com/ludoo)) <!-- 2022-11-09 07:53:11+00:00 -->
|
||||
- [[#943](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/943)] Update bootstrap README.md with unique project id requirements ([KPRepos](https://github.com/KPRepos)) <!-- 2022-11-03 22:22:22+00:00 -->
|
||||
- [[#937](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/937)] Fix typos in blueprints README.md ([kumar-dhanagopal](https://github.com/kumar-dhanagopal)) <!-- 2022-11-02 07:39:26+00:00 -->
|
||||
|
@ -64,6 +75,9 @@ All notable changes to this project will be documented in this file.
|
|||
|
||||
### FAST
|
||||
|
||||
- [[#1007](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1007)] fast README, one line fix: 00-cicd stage got moved to extras/ ([skalolazka](https://github.com/skalolazka)) <!-- 2022-11-23 15:31:01+00:00 -->
|
||||
- [[#976](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/976)] FAST: fixes to GitHub workflow and 02/net outputs ([ludoo](https://github.com/ludoo)) <!-- 2022-11-15 07:48:32+00:00 -->
|
||||
- [[#966](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/966)] FAST: improve GitHub workflow, stage 01 output fixes ([ludoo](https://github.com/ludoo)) <!-- 2022-11-11 07:55:58+00:00 -->
|
||||
- [[#963](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/963)] **incompatible change:** Refactor vps-sc module for Terraform 1.3 ([ludoo](https://github.com/ludoo)) <!-- 2022-11-10 18:34:45+00:00 -->
|
||||
- [[#956](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/956)] FAST: bootstrap and extra stage CI/CD improvements and fixes ([ludoo](https://github.com/ludoo)) <!-- 2022-11-08 08:38:16+00:00 -->
|
||||
- [[#949](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/949)] **incompatible change:** Refactor VPC firewall module for Terraform 1.3 ([ludoo](https://github.com/ludoo)) <!-- 2022-11-04 12:56:08+00:00 -->
|
||||
|
@ -94,6 +108,25 @@ All notable changes to this project will be documented in this file.
|
|||
|
||||
### MODULES
|
||||
|
||||
- [[#999](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/999)] Default nodepool creation fix ([astianseb](https://github.com/astianseb)) <!-- 2022-11-22 18:17:58+00:00 -->
|
||||
- [[#1005](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1005)] Only set partitioned table when sink type is bigquery ([juliocc](https://github.com/juliocc)) <!-- 2022-11-22 16:13:53+00:00 -->
|
||||
- [[#997](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/997)] Add BigQuery subcriptions to Pubsub module. ([iht](https://github.com/iht)) <!-- 2022-11-21 17:26:52+00:00 -->
|
||||
- [[#995](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/995)] Push container images to GitHub instead of Google Container Registry ([kunzese](https://github.com/kunzese)) <!-- 2022-11-21 14:53:52+00:00 -->
|
||||
- [[#994](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/994)] Add schemas to Pubsub topic module. ([iht](https://github.com/iht)) <!-- 2022-11-20 16:56:03+00:00 -->
|
||||
- [[#979](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/979)] Add network tags support to the organization module ([LucaPrete](https://github.com/LucaPrete)) <!-- 2022-11-18 14:56:29+00:00 -->
|
||||
- [[#991](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/991)] Allow cross-project backend services in ILB L7 module ([ludoo](https://github.com/ludoo)) <!-- 2022-11-18 08:48:41+00:00 -->
|
||||
- [[#984](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/984)] **incompatible change:** Apigee module and blueprint ([apichick](https://github.com/apichick)) <!-- 2022-11-17 16:20:27+00:00 -->
|
||||
- [[#988](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/988)] Merge cloud function v1 and v2 tests ([juliocc](https://github.com/juliocc)) <!-- 2022-11-17 10:18:57+00:00 -->
|
||||
- [[#965](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/965)] **incompatible change:** Add triggers to Cloud Functions v2 ([wiktorn](https://github.com/wiktorn)) <!-- 2022-11-16 16:00:03+00:00 -->
|
||||
- [[#980](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/980)] Have Squid log to /dev/stdout to stream logs to Cloud Logging ([kunzese](https://github.com/kunzese)) <!-- 2022-11-16 13:41:26+00:00 -->
|
||||
- [[#983](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/983)] **incompatible change:** Add support for serverless NEGs to ILB L7 module ([ludoo](https://github.com/ludoo)) <!-- 2022-11-16 13:14:05+00:00 -->
|
||||
- [[#978](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/978)] Worker pool support for `cloud-function` ([maunope](https://github.com/maunope)) <!-- 2022-11-15 16:38:42+00:00 -->
|
||||
- [[#977](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/977)] Replace Docker's `gcplogs` driver with the GCP COS logging agent ([kunzese](https://github.com/kunzese)) <!-- 2022-11-15 12:19:52+00:00 -->
|
||||
- [[#975](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/975)] Add validation for health check port specification to ILB L7 module ([ludoo](https://github.com/ludoo)) <!-- 2022-11-14 15:20:01+00:00 -->
|
||||
- [[#974](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/974)] **incompatible change:** Refactor net-ilb-l7 module for Terraform 1.3 ([ludoo](https://github.com/ludoo)) <!-- 2022-11-14 13:39:00+00:00 -->
|
||||
- [[#970](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/970)] Update logging sinks to tf1.3 in resman modules ([juliocc](https://github.com/juliocc)) <!-- 2022-11-12 18:36:59+00:00 -->
|
||||
- [[#969](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/969)] Update folder and project org policy tests ([juliocc](https://github.com/juliocc)) <!-- 2022-11-11 17:01:26+00:00 -->
|
||||
- [[#964](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/964)] prefix variable consistency across modules ([skalolazka](https://github.com/skalolazka)) <!-- 2022-11-11 13:38:51+00:00 -->
|
||||
- [[#963](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/963)] **incompatible change:** Refactor vps-sc module for Terraform 1.3 ([ludoo](https://github.com/ludoo)) <!-- 2022-11-10 18:34:45+00:00 -->
|
||||
- [[#958](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/958)] Add support for org policy custom constraints ([averbuks](https://github.com/averbuks)) <!-- 2022-11-09 09:07:46+00:00 -->
|
||||
- [[#960](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/960)] Fix README typo in firewall module ([valeriobponza](https://github.com/valeriobponza)) <!-- 2022-11-08 23:25:34+00:00 -->
|
||||
|
@ -147,6 +180,10 @@ All notable changes to this project will be documented in this file.
|
|||
|
||||
### TOOLS
|
||||
|
||||
- [[#1004](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1004)] Use `actions/labeler` to automatically label pull requests ([kunzese](https://github.com/kunzese)) <!-- 2022-11-22 14:42:47+00:00 -->
|
||||
- [[#998](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/998)] Add missing `write_package` permission ([kunzese](https://github.com/kunzese)) <!-- 2022-11-22 08:32:42+00:00 -->
|
||||
- [[#996](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/996)] Fix `repository name must be lowercase` on docker build ([kunzese](https://github.com/kunzese)) <!-- 2022-11-21 16:04:57+00:00 -->
|
||||
- [[#993](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/993)] Fix variable and output sort check ([juliocc](https://github.com/juliocc)) <!-- 2022-11-21 13:32:56+00:00 -->
|
||||
- [[#950](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/950)] Add a pytest fixture to convert tfvars to yaml ([ludoo](https://github.com/ludoo)) <!-- 2022-11-04 17:37:24+00:00 -->
|
||||
- [[#942](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/942)] Bump tftest and improve dns tests ([juliocc](https://github.com/juliocc)) <!-- 2022-11-02 19:38:01+00:00 -->
|
||||
- [[#919](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/919)] Rename workflow names ([juliocc](https://github.com/juliocc)) <!-- 2022-10-25 15:22:51+00:00 -->
|
||||
|
|
|
@ -71,6 +71,16 @@ pytest tests/examples
|
|||
|
||||
Once everything looks good, add/commit any pending changes then push and open a PR on GitHub. We typically enforce a set of design and style conventions, so please make sure you have familiarized yourself with the following sections and implemented them in your code, to avoid lengthy review cycles.
|
||||
|
||||
HINT: if you work on high-latency or low-bandwidth network use `TF_PLUGIN_CACHE_DIR` environment variable to dramatically speed up the tests, for example:
|
||||
```bash
|
||||
TF_PLUGIN_CACHE_DIR=/tmp/tfcache pytest tests
|
||||
```
|
||||
|
||||
Or just add into your [terraformrc](https://developer.hashicorp.com/terraform/cli/config/config-file):
|
||||
```
|
||||
plugin_cache_dir = "$HOME/.terraform.d/plugin-cache"
|
||||
```
|
||||
|
||||
## Developer's handbook
|
||||
|
||||
Over the years we have assembled a specific set of design principles and style conventions that allow for better readability and make understanding and changing code more predictable.
|
||||
|
@ -199,7 +209,7 @@ module "project" {
|
|||
]
|
||||
}
|
||||
iam = {
|
||||
"roles/editor" = [
|
||||
"roles/editor" = [
|
||||
"serviceAccount:${module.project.service_accounts.cloud_services}"
|
||||
]
|
||||
}
|
||||
|
@ -226,7 +236,7 @@ module "project" {
|
|||
source = "./modules/project"
|
||||
name = "project-example"
|
||||
iam = {
|
||||
"roles/editor" = [
|
||||
"roles/editor" = [
|
||||
"serviceAccount:${module.project.service_accounts.cloud_services}"
|
||||
]
|
||||
}
|
||||
|
@ -531,6 +541,39 @@ locals {
|
|||
}
|
||||
```
|
||||
|
||||
#### The `prefix` variable
|
||||
|
||||
If you would like to use a "prefix" variable for resource names, please keep its definition consistent across all modules:
|
||||
```hcl
|
||||
# variables.tf
|
||||
variable "prefix" {
|
||||
description = "Optional prefix used for resource names."
|
||||
type = string
|
||||
default = null
|
||||
validation {
|
||||
condition = var.prefix != ""
|
||||
error_message = "Prefix cannot be empty, please use null instead."
|
||||
}
|
||||
}
|
||||
|
||||
# main.tf
|
||||
locals {
|
||||
prefix = var.prefix == null ? "" : "${var.prefix}-"
|
||||
}
|
||||
```
|
||||
|
||||
For blueprints the prefix is mandatory:
|
||||
```hcl
|
||||
variable "prefix" {
|
||||
description = "Prefix used for resource names."
|
||||
type = string
|
||||
validation {
|
||||
condition = var.prefix != ""
|
||||
error_message = "Prefix cannot be empty."
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Interacting with checks, tests and tools
|
||||
|
||||
Our modules are designed for composition and live in a monorepo together with several end-to-end blueprints, so it was inevitable that over time we found ways of ensuring that a change does not break consumers.
|
||||
|
|
|
@ -33,7 +33,7 @@ Currently available modules:
|
|||
- **networking** - [DNS](./modules/dns), [Cloud Endpoints](./modules/endpoints), [address reservation](./modules/net-address), [NAT](./modules/net-cloudnat), [Global Load Balancer (classic)](./modules/net-glb/), [L4 ILB](./modules/net-ilb), [L7 ILB](./modules/net-ilb-l7), [VPC](./modules/net-vpc), [VPC firewall](./modules/net-vpc-firewall), [VPC peering](./modules/net-vpc-peering), [VPN dynamic](./modules/net-vpn-dynamic), [HA VPN](./modules/net-vpn-ha), [VPN static](./modules/net-vpn-static), [Service Directory](./modules/service-directory)
|
||||
- **compute** - [VM/VM group](./modules/compute-vm), [MIG](./modules/compute-mig), [COS container](./modules/cloud-config-container/cos-generic-metadata/) (coredns, mysql, onprem, squid), [GKE cluster](./modules/gke-cluster), [GKE hub](./modules/gke-hub), [GKE nodepool](./modules/gke-nodepool)
|
||||
- **data** - [BigQuery dataset](./modules/bigquery-dataset), [Bigtable instance](./modules/bigtable-instance), [Cloud SQL instance](./modules/cloudsql-instance), [Data Catalog Policy Tag](./modules/data-catalog-policy-tag), [Datafusion](./modules/datafusion), [GCS](./modules/gcs), [Pub/Sub](./modules/pubsub)
|
||||
- **development** - [API Gateway](./modules/api-gateway), [Apigee Organization](./modules/apigee-organization), [Apigee X Instance](./modules/apigee-x-instance), [Artifact Registry](./modules/artifact-registry), [Container Registry](./modules/container-registry), [Cloud Source Repository](./modules/source-repository)
|
||||
- **development** - [API Gateway](./modules/api-gateway), [Apigee](./modules/apigee), [Artifact Registry](./modules/artifact-registry), [Container Registry](./modules/container-registry), [Cloud Source Repository](./modules/source-repository)
|
||||
- **security** - [Binauthz](./modules/binauthz/), [KMS](./modules/kms), [SecretManager](./modules/secret-manager), [VPC Service Control](./modules/vpc-sc)
|
||||
- **serverless** - [Cloud Function](./modules/cloud-function), [Cloud Run](./modules/cloud-run)
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ Currently available blueprints:
|
|||
- **data solutions** - [GCE and GCS CMEK via centralized Cloud KMS](./data-solutions/cmek-via-centralized-kms), [Cloud Composer version 2 private instance, supporting Shared VPC and external CMEK key](./data-solutions/composer-2), [Cloud SQL instance with multi-region read replicas](./data-solutions/cloudsql-multiregion), [Data Platform](./data-solutions/data-platform-foundations), [Spinning up a foundation data pipeline on Google Cloud using Cloud Storage, Dataflow and BigQuery](./data-solutions/gcs-to-bq-with-least-privileges), [#SQL Server Always On Groups blueprint](./data-solutions/sqlserver-alwayson), [Data Playground](./data-solutions/data-playground)
|
||||
- **factories** - [The why and the how of Resource Factories](./factories), [Google Cloud Identity Group Factory](./factories/cloud-identity-group-factory), [Google Cloud BQ Factory](./factories/bigquery-factory), [Google Cloud VPC Firewall Factory](./factories/net-vpc-firewall-yaml), [Minimal Project Factory](./factories/project-factory)
|
||||
- **GKE** - [Binary Authorization Pipeline Blueprint](./gke/binauthz), [Storage API](./gke/binauthz/image), [Multi-cluster mesh on GKE (fleet API)](./gke/multi-cluster-mesh-gke-fleet-api), [GKE Multitenant Blueprint](./gke/multitenant-fleet), [Shared VPC with GKE support](./networking/shared-vpc-gke/)
|
||||
- **networking** - [Decentralized firewall management](./networking/decentralized-firewall), [Decentralized firewall validator](./networking/decentralized-firewall/validator), [Network filtering with Squid](./networking/filtering-proxy), [HTTP Load Balancer with Cloud Armor](./networking/glb-and-armor), [Hub and Spoke via VPN](./networking/hub-and-spoke-vpn), [Hub and Spoke via VPC Peering](./networking/hub-and-spoke-peering), [Internal Load Balancer as Next Hop](./networking/ilb-next-hop), [Nginx-based reverse proxy cluster](./networking/nginx-reverse-proxy-cluster), [On-prem DNS and Google Private Access](./networking/onprem-google-access-dns), [Calling a private Cloud Function from On-premises](./networking/private-cloud-function-from-onprem), [Hybrid connectivity to on-premise services through PSC](./networking/psc-hybrid), [PSC Producer](./networking/psc-hybrid/psc-producer), [PSC Consumer](./networking/psc-hybrid/psc-consumer), [Shared VPC with optional GKE cluster](./networking/shared-vpc-gke)
|
||||
- **networking** - [Decentralized firewall management](./networking/decentralized-firewall), [Decentralized firewall validator](./networking/decentralized-firewall/validator), [Network filtering with Squid](./networking/filtering-proxy), [Network filtering with Squid with isolated VPCs using Private Service Connect](./networking/filtering-proxy-psc), [HTTP Load Balancer with Cloud Armor](./networking/glb-and-armor), [Hub and Spoke via VPN](./networking/hub-and-spoke-vpn), [Hub and Spoke via VPC Peering](./networking/hub-and-spoke-peering), [Internal Load Balancer as Next Hop](./networking/ilb-next-hop), [Nginx-based reverse proxy cluster](./networking/nginx-reverse-proxy-cluster), [On-prem DNS and Google Private Access](./networking/onprem-google-access-dns), [Calling a private Cloud Function from On-premises](./networking/private-cloud-function-from-onprem), [Hybrid connectivity to on-premise services through PSC](./networking/psc-hybrid), [PSC Producer](./networking/psc-hybrid/psc-producer), [PSC Consumer](./networking/psc-hybrid/psc-consumer), [Shared VPC with optional GKE cluster](./networking/shared-vpc-gke)
|
||||
- **serverless** - [Creating multi-region deployments for API Gateway](./serverless/api-gateway)
|
||||
- **third party solutions** - [OpenShift on GCP user-provisioned infrastructure](./third-party-solutions/openshift), [Wordpress deployment on Cloud Run](./third-party-solutions/wordpress/cloudrun)
|
||||
|
||||
|
|
|
@ -52,20 +52,20 @@ Once done testing, you can clean up resources by running `terraform destroy`.
|
|||
|
||||
| name | description | type | required | default |
|
||||
|---|---|:---:|:---:|:---:|
|
||||
| [ad_dns_domain_name](variables.tf#L44) | AD DNS domain name. | <code>string</code> | ✓ | |
|
||||
| [adfs_dns_domain_name](variables.tf#L49) | ADFS DNS domain name. | <code>string</code> | ✓ | |
|
||||
| [project_id](variables.tf#L24) | Host project ID. | <code>string</code> | ✓ | |
|
||||
| [ad_ip_cidr_block](variables.tf#L90) | Managed AD IP CIDR block. | <code>string</code> | | <code>"10.0.0.0/24"</code> |
|
||||
| [disk_size](variables.tf#L54) | Disk size. | <code>number</code> | | <code>50</code> |
|
||||
| [disk_type](variables.tf#L60) | Disk type. | <code>string</code> | | <code>"pd-ssd"</code> |
|
||||
| [image](variables.tf#L66) | Image. | <code>string</code> | | <code>"projects/windows-cloud/global/images/family/windows-2022"</code> |
|
||||
| [instance_type](variables.tf#L72) | Instance type. | <code>string</code> | | <code>"n1-standard-2"</code> |
|
||||
| [network_config](variables.tf#L35) | Network configuration | <code title="object({ network = string subnet = string })">object({…})</code> | | <code>null</code> |
|
||||
| [prefix](variables.tf#L29) | Prefix for the resources created. | <code>string</code> | | <code>null</code> |
|
||||
| [project_create](variables.tf#L15) | Parameters for the creation of the new project. | <code title="object({ billing_account_id = string parent = string })">object({…})</code> | | <code>null</code> |
|
||||
| [region](variables.tf#L78) | Region. | <code>string</code> | | <code>"europe-west1"</code> |
|
||||
| [subnet_ip_cidr_block](variables.tf#L96) | Subnet IP CIDR block. | <code>string</code> | | <code>"10.0.1.0/28"</code> |
|
||||
| [zone](variables.tf#L84) | Zone. | <code>string</code> | | <code>"europe-west1-c"</code> |
|
||||
| [ad_dns_domain_name](variables.tf#L15) | AD DNS domain name. | <code>string</code> | ✓ | |
|
||||
| [adfs_dns_domain_name](variables.tf#L26) | ADFS DNS domain name. | <code>string</code> | ✓ | |
|
||||
| [prefix](variables.tf#L64) | Prefix used for resource names. | <code>string</code> | ✓ | |
|
||||
| [project_id](variables.tf#L82) | Host project ID. | <code>string</code> | ✓ | |
|
||||
| [ad_ip_cidr_block](variables.tf#L20) | Managed AD IP CIDR block. | <code>string</code> | | <code>"10.0.0.0/24"</code> |
|
||||
| [disk_size](variables.tf#L31) | Disk size. | <code>number</code> | | <code>50</code> |
|
||||
| [disk_type](variables.tf#L37) | Disk type. | <code>string</code> | | <code>"pd-ssd"</code> |
|
||||
| [image](variables.tf#L43) | Image. | <code>string</code> | | <code>"projects/windows-cloud/global/images/family/windows-2022"</code> |
|
||||
| [instance_type](variables.tf#L49) | Instance type. | <code>string</code> | | <code>"n1-standard-2"</code> |
|
||||
| [network_config](variables.tf#L55) | Network configuration | <code title="object({ network = string subnet = string })">object({…})</code> | | <code>null</code> |
|
||||
| [project_create](variables.tf#L73) | Parameters for the creation of the new project. | <code title="object({ billing_account_id = string parent = string })">object({…})</code> | | <code>null</code> |
|
||||
| [region](variables.tf#L87) | Region. | <code>string</code> | | <code>"europe-west1"</code> |
|
||||
| [subnet_ip_cidr_block](variables.tf#L93) | Subnet IP CIDR block. | <code>string</code> | | <code>"10.0.1.0/28"</code> |
|
||||
| [zone](variables.tf#L99) | Zone. | <code>string</code> | | <code>"europe-west1-c"</code> |
|
||||
|
||||
## Outputs
|
||||
|
||||
|
|
|
@ -12,10 +12,6 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
locals {
|
||||
prefix = (var.prefix == null || var.prefix == "") ? "" : "${var.prefix}-"
|
||||
}
|
||||
|
||||
module "project" {
|
||||
source = "../../../modules/project"
|
||||
billing_account = (
|
||||
|
@ -41,7 +37,7 @@ module "vpc" {
|
|||
count = var.network_config == null ? 1 : 0
|
||||
source = "../../../modules/net-vpc"
|
||||
project_id = module.project.project_id
|
||||
name = "${local.prefix}vpc"
|
||||
name = "${var.prefix}-vpc"
|
||||
subnets = [
|
||||
{
|
||||
ip_cidr_range = var.subnet_ip_cidr_block
|
||||
|
@ -98,7 +94,7 @@ module "server" {
|
|||
|
||||
module "glb" {
|
||||
source = "../../../modules/net-glb"
|
||||
name = "${local.prefix}glb"
|
||||
name = "${var.prefix}-glb"
|
||||
project_id = module.project.project_id
|
||||
|
||||
https = true
|
||||
|
|
|
@ -12,40 +12,17 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
variable "project_create" {
|
||||
description = "Parameters for the creation of the new project."
|
||||
type = object({
|
||||
billing_account_id = string
|
||||
parent = string
|
||||
})
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "project_id" {
|
||||
description = "Host project ID."
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "prefix" {
|
||||
description = "Prefix for the resources created."
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "network_config" {
|
||||
description = "Network configuration"
|
||||
type = object({
|
||||
network = string
|
||||
subnet = string
|
||||
})
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "ad_dns_domain_name" {
|
||||
description = "AD DNS domain name."
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "ad_ip_cidr_block" {
|
||||
description = "Managed AD IP CIDR block."
|
||||
type = string
|
||||
default = "10.0.0.0/24"
|
||||
}
|
||||
|
||||
variable "adfs_dns_domain_name" {
|
||||
description = "ADFS DNS domain name."
|
||||
type = string
|
||||
|
@ -75,26 +52,52 @@ variable "instance_type" {
|
|||
default = "n1-standard-2"
|
||||
}
|
||||
|
||||
variable "network_config" {
|
||||
description = "Network configuration"
|
||||
type = object({
|
||||
network = string
|
||||
subnet = string
|
||||
})
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "prefix" {
|
||||
description = "Prefix used for resource names."
|
||||
type = string
|
||||
validation {
|
||||
condition = var.prefix != ""
|
||||
error_message = "Prefix cannot be empty."
|
||||
}
|
||||
}
|
||||
|
||||
variable "project_create" {
|
||||
description = "Parameters for the creation of the new project."
|
||||
type = object({
|
||||
billing_account_id = string
|
||||
parent = string
|
||||
})
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "project_id" {
|
||||
description = "Host project ID."
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "region" {
|
||||
description = "Region."
|
||||
type = string
|
||||
default = "europe-west1"
|
||||
}
|
||||
|
||||
variable "subnet_ip_cidr_block" {
|
||||
description = "Subnet IP CIDR block."
|
||||
type = string
|
||||
default = "10.0.1.0/28"
|
||||
}
|
||||
|
||||
variable "zone" {
|
||||
description = "Zone."
|
||||
type = string
|
||||
default = "europe-west1-c"
|
||||
}
|
||||
|
||||
variable "ad_ip_cidr_block" {
|
||||
description = "Managed AD IP CIDR block."
|
||||
type = string
|
||||
default = "10.0.0.0/24"
|
||||
}
|
||||
|
||||
variable "subnet_ip_cidr_block" {
|
||||
description = "Subnet IP CIDR block."
|
||||
type = string
|
||||
default = "10.0.1.0/28"
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
# Apigee X Analytics in Bigquery
|
||||
|
||||
The following blueprint shows to how to create an Apigee X trial organization, with an environment group, an environment attached to that environment group and an instance attached to that environment. It creates a NEG that exposes Apigee service attachment. The NEG is added as a backend to a GLB. API proxy requests will pass through the GLB.
|
||||
|
||||
![Analytics northbound networking](diagram1.png)
|
||||
|
||||
In addition to this it also creates the setup depicted in the diagram below to export the Apigee analytics of an organization daily to a BigQuery table.
|
||||
|
||||
![Apigee analytics in BigQuery](diagram2.png)
|
||||
|
||||
Find below a description on how the analytics export to BigQuery works:
|
||||
|
||||
1. A Cloud Scheduler Job runs daily at a selected time, publishing a message to a Pub/Sub topic.
|
||||
2. The message published triggers the execution of a function that makes a call to the Apigee Analytics Export API to export the analytical data available for the previous day.
|
||||
3. The export function is passed the Apigee organization, environments, datastore name as environment variables. The service account used to run the function needs to be granted the Apigee Admin role on the project. The Apigee Analytics engine asynchronously exports the analytical data to a GCS bucket. This requires the _Apigee Service Agent_ service account to be granted the _Storage Admin_ role on the project.
|
||||
4. A notification of the files created on GCS is received in a Pub/Sub topic that triggers the execution of the cloud function in charge of loading the data from GCS to the right BigQuery table partition. This function is passed the name of the BigQuery dataset, its location and the name of the table inside that dataset as environment variables. The service account used to run the function needs to be granted the _Storage Object Viewer_ role on the GCS bucket, the _BigQuery Job User_ role on the project and the _BigQuery Data Editor_ role on the table.
|
||||
|
||||
Note: This setup only works if you are not using custom analytics.
|
||||
|
||||
## Running the blueprint
|
||||
|
||||
1. Clone this repository or [open it in cloud shell](https://ssh.cloud.google.com/cloudshell/editor?cloudshell_git_repo=https%3A%2F%2Fgithub.com%2Fterraform-google-modules%2Fcloud-foundation-fabric&cloudshell_print=cloud-shell-readme.txt&cloudshell_working_dir=blueprints%2Fcloud-operations%apigee), then go through the following steps to create resources:
|
||||
|
||||
2. Copy the file [terraform.tfvars.sample](./terraform.tfvars.sample) to a file called ```terraform.tfvars``` and update the values if required.
|
||||
|
||||
3. Initialize the terraform configuration
|
||||
|
||||
```terraform init```
|
||||
|
||||
4. Apply the terraform configuration
|
||||
|
||||
```terraform apply```
|
||||
|
||||
Once the resources have been created, do the following:
|
||||
|
||||
Create an A record in your DNS registrar to point the environment group hostname to the public IP address returned after the terraform configuration was applied. You might need to wait some time until the certificate is provisioned.
|
||||
|
||||
## Testing the blueprint
|
||||
|
||||
Do the following to verify that everything works as expected.
|
||||
|
||||
1. Create an Apigee datastore
|
||||
|
||||
```./create-datastore.sh```
|
||||
|
||||
2. Deploy an api proxy
|
||||
|
||||
```./deploy-apiproxy.sh test```
|
||||
|
||||
3. Send some traffic to the proxy
|
||||
|
||||
```./send-requests.sh test.my-domain.com 1000```
|
||||
|
||||
4. At 4am (UTC) every day the Cloud Scheduler will run and will export the analytics to the BigQuery table. Double-check they are there.
|
||||
<!-- BEGIN TFDOC -->
|
||||
|
||||
## Variables
|
||||
|
||||
| name | description | type | required | default |
|
||||
|---|---|:---:|:---:|:---:|
|
||||
| [envgroups](variables.tf#L24) | Environment groups (NAME => [HOSTNAMES]). | <code>map(list(string))</code> | ✓ | |
|
||||
| [environments](variables.tf#L30) | Environments. | <code title="map(object({ display_name = optional(string) description = optional(string) node_config = optional(object({ min_node_count = optional(number) max_node_count = optional(number) current_aggregate_node_count = number })) iam = optional(map(list(string))) envgroups = list(string) }))">map(object({…}))</code> | ✓ | |
|
||||
| [instances](variables.tf#L46) | Instance. | <code title="map(object({ display_name = optional(string) description = optional(string) region = string environments = list(string) psa_ip_cidr_range = string disk_encryption_key = optional(string) consumer_accept_list = optional(list(string)) }))">map(object({…}))</code> | ✓ | |
|
||||
| [project_id](variables.tf#L92) | Project ID. | <code>string</code> | ✓ | |
|
||||
| [psc_config](variables.tf#L98) | PSC configuration. | <code>map(string)</code> | ✓ | |
|
||||
| [datastore_name](variables.tf#L17) | Datastore | <code>string</code> | | <code>"gcs"</code> |
|
||||
| [organization](variables.tf#L60) | Apigee organization. | <code title="object({ display_name = optional(string, "Apigee organization created by tf module") description = optional(string, "Apigee organization created by tf module") authorized_network = optional(string, "vpc") runtime_type = optional(string, "CLOUD") billing_type = optional(string) database_encryption_key = optional(string) analytics_region = optional(string, "europe-west1") })">object({…})</code> | | <code title="{ }">{…}</code> |
|
||||
| [path](variables.tf#L76) | Bucket path. | <code>string</code> | | <code>"/analytics"</code> |
|
||||
| [project_create](variables.tf#L83) | Parameters for the creation of the new project. | <code title="object({ billing_account_id = string parent = string })">object({…})</code> | | <code>null</code> |
|
||||
| [vpc_create](variables.tf#L104) | Boolean flag indicating whether the VPC should be created or not. | <code>bool</code> | | <code>true</code> |
|
||||
|
||||
## Outputs
|
||||
|
||||
| name | description | sensitive |
|
||||
|---|---|:---:|
|
||||
| [ip_address](outputs.tf#L17) | IP address. | |
|
||||
|
||||
<!-- END TFDOC -->
|
Binary file not shown.
After Width: | Height: | Size: 37 KiB |
Binary file not shown.
After Width: | Height: | Size: 48 KiB |
|
@ -0,0 +1,103 @@
|
|||
// Copyright 2020 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
const functions = require("@google-cloud/functions-framework");
|
||||
const superagent = require("superagent");
|
||||
const { LoggingBunyan } = require("@google-cloud/logging-bunyan");
|
||||
const bunyan = require("bunyan");
|
||||
const { GoogleAuth } = require("google-auth-library");
|
||||
|
||||
const loggingBunyan = new LoggingBunyan();
|
||||
const logger = bunyan.createLogger({
|
||||
name: "analyticsExport",
|
||||
streams: [
|
||||
{ stream: process.stdout, level: "info" },
|
||||
loggingBunyan.stream("info"),
|
||||
],
|
||||
});
|
||||
|
||||
const ORGANIZATION = process.env.ORGANIZATION;
|
||||
const ENVIRONMENTS = process.env.ENVIRONMENTS.split(',');
|
||||
const DATASTORE = process.env.DATASTORE;
|
||||
|
||||
const MANAGEMENT_API_URL = "https://apigee.googleapis.com/v1";
|
||||
|
||||
function formatDate(date) {
|
||||
var d = new Date(date),
|
||||
month = "" + (d.getMonth() + 1),
|
||||
day = "" + d.getDate(),
|
||||
year = d.getFullYear();
|
||||
|
||||
if (month.length < 2) month = "0" + month;
|
||||
if (day.length < 2) day = "0" + day;
|
||||
|
||||
return [year, month, day].join("-");
|
||||
}
|
||||
|
||||
async function getAccessToken() {
|
||||
logger.info("Requesting access token...");
|
||||
const auth = new GoogleAuth();
|
||||
const token = await auth.getAccessToken();
|
||||
logger.info("Got access token ");
|
||||
return token;
|
||||
}
|
||||
|
||||
async function scheduleAnalyticsExport(org, env, token, startDate, endDate) {
|
||||
logger.info(
|
||||
`Sending request for an analytics export from ${startDate} to ${endDate} for environment ${env}`
|
||||
);
|
||||
try {
|
||||
const response = await superagent
|
||||
.post(
|
||||
`${MANAGEMENT_API_URL}/organizations/${org}/environments/${env}/analytics/exports`
|
||||
)
|
||||
.send({
|
||||
name: `Analytics from ${startDate} to ${endDate}`,
|
||||
description: `Analytics from ${startDate} to ${endDate}`,
|
||||
dateRange: {
|
||||
start: startDate,
|
||||
end: endDate,
|
||||
},
|
||||
outputFormat: "csv",
|
||||
csvDelimiter: ",",
|
||||
datastoreName: DATASTORE,
|
||||
})
|
||||
.set('Authorization', `Bearer ${token}`)
|
||||
.accept('json');
|
||||
logger.info('Analytics export scheduled');
|
||||
return response;
|
||||
} catch (error) {
|
||||
logger.error('Error scheduling analytics export');
|
||||
logger.error(error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
functions.cloudEvent("export", async (cloudEvent) => {
|
||||
const today = new Date();
|
||||
const endDate = formatDate(today);
|
||||
const yesterday = new Date(today.setDate(today.getDate() - 1));
|
||||
const startDate = formatDate(yesterday);
|
||||
const token = await getAccessToken();
|
||||
try {
|
||||
for(let i = 0; i < ENVIRONMENTS.length; i++) {
|
||||
const env = ENVIRONMENTS[i];
|
||||
const response = await scheduleAnalyticsExport(ORGANIZATION, env, token, startDate, endDate);
|
||||
logger.error('Export scheduled: ' + response.body.self);
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error('Analytics exports was not scheduled');
|
||||
logger.error(error);
|
||||
}
|
||||
});
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"name": "export",
|
||||
"version": "1.0.0",
|
||||
"description": "Apigee analytics export to GCS",
|
||||
"main": "index.js",
|
||||
"engines": {
|
||||
"node": ">=16.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@google-cloud/functions-framework": "^3.1.2",
|
||||
"@google-cloud/logging-bunyan": "^4.2.0",
|
||||
"bunyan": "^1.8.15",
|
||||
"express": "^4.18.2",
|
||||
"google-auth-library": "^8.6.0",
|
||||
"superagent": "^8.0.3"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
/**
|
||||
* Copyright 2020 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
const functions = require("@google-cloud/functions-framework");
|
||||
const { Storage } = require('@google-cloud/storage');
|
||||
const { BigQuery } = require('@google-cloud/bigquery');
|
||||
const bunyan = require('bunyan');
|
||||
const schema = require('./schema.json');
|
||||
|
||||
const { LoggingBunyan } = require('@google-cloud/logging-bunyan');
|
||||
|
||||
const loggingBunyan = new LoggingBunyan();
|
||||
|
||||
const logger = bunyan.createLogger({
|
||||
name: 'gcs2bq',
|
||||
streams: [
|
||||
{ stream: process.stdout, level: 'info' },
|
||||
loggingBunyan.stream('info')
|
||||
],
|
||||
});
|
||||
|
||||
const DATASET = process.env.DATASET
|
||||
const TABLE = process.env.TABLE
|
||||
const LOCATION = process.env.LOCATION
|
||||
|
||||
async function loadCSVFromGCS(datasetId, tableId, timePartition, bucket, filename) {
|
||||
const metadata = {
|
||||
sourceFormat: 'CSV',
|
||||
skipLeadingRows: 1,
|
||||
maxBadRecords: 1000,
|
||||
schema: {
|
||||
fields: schema
|
||||
},
|
||||
location: LOCATION
|
||||
};
|
||||
|
||||
logger.info(`Trying to load ${bucket}/${filename} in ${timePartition} time partition of table ${tableId}...`);
|
||||
const bigquery = new BigQuery();
|
||||
const storage = new Storage();
|
||||
const [job] = await bigquery
|
||||
.dataset(datasetId)
|
||||
.table(`${tableId}\$${timePartition}`)
|
||||
.load(storage.bucket(bucket).file(filename), metadata);
|
||||
logger.info(`Job ${job.id} completed.`);
|
||||
const errors = job.status.errors;
|
||||
if (errors && errors.length > 0) {
|
||||
logger.info('Errors occurred:' + JSON.stringify(errors));
|
||||
throw new Error('File could not be loaded in time partition');
|
||||
}
|
||||
}
|
||||
|
||||
functions.cloudEvent("gcs2bq", async (cloudEvent) => {
|
||||
|
||||
const data = JSON.parse(Buffer.from(cloudEvent.data.message.data, 'base64').toString());
|
||||
logger.info('Notification received');
|
||||
logger.info(data);
|
||||
const pattern = /([^/]+\/)?[0-9]{14}\-[0-9a-z]{8}\-[0-9a-z]{4}\-[0-9a-z]{4}\-[0-9a-z]{4}\-[0-9a-z]{12}\-api\-from\-([0-9]{8})0000\-to\-([0-9]{8})0000\/result\-[0-9]+\.csv\.gz/
|
||||
const result = data.name.match(pattern);
|
||||
const timePartition = result[2];
|
||||
|
||||
await loadCSVFromGCS(DATASET, TABLE, timePartition, data.bucket, data.name)
|
||||
|
||||
});
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"name": "gcs2bq",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"engines": {
|
||||
"node": ">=16.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@google-cloud/bigquery": "^6.0.3",
|
||||
"@google-cloud/functions-framework": "^3.1.2",
|
||||
"@google-cloud/logging-bunyan": "^4.2.0",
|
||||
"@google-cloud/storage": "^6.7.0",
|
||||
"bunyan": "^1.8.15"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,447 @@
|
|||
[
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "organization",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "environment",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "apiproxy",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "request_uri",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "proxy",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "proxy_basepath",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "request_verb",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "request_size",
|
||||
"type": "INTEGER"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "response_status_code",
|
||||
"type": "INTEGER"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "is_error",
|
||||
"type": "INTEGER"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "client_received_start_timestamp",
|
||||
"type": "TIMESTAMP"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "client_received_end_timestamp",
|
||||
"type": "TIMESTAMP"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "target_sent_start_timestamp",
|
||||
"type": "TIMESTAMP"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "target_sent_end_timestamp",
|
||||
"type": "TIMESTAMP"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "target_received_start_timestamp",
|
||||
"type": "TIMESTAMP"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "target_received_end_timestamp",
|
||||
"type": "TIMESTAMP"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "client_sent_start_timestamp",
|
||||
"type": "TIMESTAMP"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "client_sent_end_timestamp",
|
||||
"type": "TIMESTAMP"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "client_ip",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "client_id",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "developer",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "developer_app",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "api_product",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "flow_resource",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "target",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "target_url",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "target_host",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "apiproxy_revision",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "proxy_pathsuffix",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "proxy_client_ip",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "target_basepath",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "target_ip",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "request_path",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "response_size",
|
||||
"type": "INTEGER"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "developer_email",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "virtual_host",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "gateway_flow_id",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "message_count",
|
||||
"type": "INTEGER"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "total_response_time",
|
||||
"type": "INTEGER"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "request_processing_latency",
|
||||
"type": "INTEGER"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "response_processing_latency",
|
||||
"type": "INTEGER"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "target_response_time",
|
||||
"type": "INTEGER"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "cache_hit",
|
||||
"type": "INTEGER"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "x_forwarded_for_ip",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "useragent",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "target_response_code",
|
||||
"type": "INTEGER"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "target_error",
|
||||
"type": "INTEGER"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "policy_error",
|
||||
"type": "INTEGER"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "ax_created_time",
|
||||
"type": "TIMESTAMP"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "ax_ua_agent_type",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "ax_ua_os_version",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "ax_ua_os_family",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "ax_ua_agent_version",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "ax_ua_device_category",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "ax_ua_agent_family",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "gateway_source",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "ax_month_of_year",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "ax_hour_of_day",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "ax_week_of_month",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "ax_day_of_week",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "ax_cache_key",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "ax_cache_l1_count",
|
||||
"type": "INTEGER"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "ax_cache_source",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "ax_cache_executed",
|
||||
"type": "INTEGER"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "ax_cache_name",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "ax_edge_execution_fault_code",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "ax_edge_is_apigee_fault",
|
||||
"type": "INTEGER"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "ax_execution_fault_policy_name",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "ax_execution_fault_flow_state",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "ax_execution_fault_flow_name",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "ax_dn_region",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "ax_true_client_ip",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "x_apigee_edge_execution_stats_request_flow_end_timestamp",
|
||||
"type": "TIMESTAMP"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "x_apigee_edge_execution_stats_request_flow_start_timestamp",
|
||||
"type": "TIMESTAMP"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "x_apigee_edge_execution_stats_response_flow_end_timestamp",
|
||||
"type": "TIMESTAMP"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "x_apigee_edge_execution_stats_response_flow_start_timestamp",
|
||||
"type": "TIMESTAMP"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "x_apigee_edge_stats_steps",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "senseaction",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "ax_resolved_client_ip",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "x_forwarded_proto",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "x_apigee_intelligence_service",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "envgroup_hostname",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "x_apigee_mintng_rate",
|
||||
"type": "NUMERIC"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "x_apigee_mintng_rate_plan_id",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "x_apigee_mintng_dev_share",
|
||||
"type": "NUMERIC"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "x_apigee_mintng_currency",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "x_apigee_mintng_price",
|
||||
"type": "NUMERIC"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "x_apigee_mintng_tx_success",
|
||||
"type": "BOOLEAN"
|
||||
},
|
||||
{
|
||||
"mode": "NULLABLE",
|
||||
"name": "x_apigee_mintng_price_multiplier",
|
||||
"type": "NUMERIC"
|
||||
}
|
||||
]
|
|
@ -0,0 +1,311 @@
|
|||
/**
|
||||
* Copyright 2022 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
module "project" {
|
||||
source = "../../../modules/project"
|
||||
billing_account = (var.project_create != null
|
||||
? var.project_create.billing_account_id
|
||||
: null
|
||||
)
|
||||
parent = (var.project_create != null
|
||||
? var.project_create.parent
|
||||
: null
|
||||
)
|
||||
name = var.project_id
|
||||
project_create = var.project_create == null ? false : true
|
||||
services = [
|
||||
"apigee.googleapis.com",
|
||||
"bigquery.googleapis.com",
|
||||
"cloudbuild.googleapis.com",
|
||||
"cloudfunctions.googleapis.com",
|
||||
"cloudscheduler.googleapis.com",
|
||||
"logging.googleapis.com",
|
||||
"compute.googleapis.com",
|
||||
"pubsub.googleapis.com",
|
||||
"servicenetworking.googleapis.com",
|
||||
"storage.googleapis.com"
|
||||
]
|
||||
iam = {
|
||||
"roles/bigquery.jobUser" = [module.function_gcs2bq.service_account_iam_email]
|
||||
"roles/logging.logWriter" = [module.function_export.service_account_iam_email]
|
||||
"roles/logging.logWriter" = [module.function_gcs2bq.service_account_iam_email]
|
||||
"roles/apigee.admin" = [module.function_export.service_account_iam_email]
|
||||
"roles/storage.admin" = ["serviceAccount:${module.project.service_accounts.robots.apigee}"]
|
||||
}
|
||||
}
|
||||
|
||||
module "vpc" {
|
||||
source = "../../../modules/net-vpc"
|
||||
project_id = module.project.project_id
|
||||
name = var.organization.authorized_network
|
||||
vpc_create = var.vpc_create
|
||||
subnets_psc = [for k, v in var.psc_config :
|
||||
{
|
||||
ip_cidr_range = v
|
||||
name = "subnet-psc-${k}"
|
||||
region = k
|
||||
}
|
||||
]
|
||||
psa_config = {
|
||||
ranges = { for k, v in var.instances :
|
||||
"apigee-${k}" => v.psa_ip_cidr_range
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module "apigee" {
|
||||
source = "../../../modules/apigee"
|
||||
project_id = module.project.project_id
|
||||
organization = var.organization
|
||||
envgroups = var.envgroups
|
||||
environments = var.environments
|
||||
instances = var.instances
|
||||
depends_on = [
|
||||
module.vpc
|
||||
]
|
||||
}
|
||||
|
||||
resource "google_compute_region_network_endpoint_group" "neg" {
|
||||
for_each = var.instances
|
||||
name = "apigee-neg-${each.key}"
|
||||
project = module.project.project_id
|
||||
region = each.value.region
|
||||
network_endpoint_type = "PRIVATE_SERVICE_CONNECT"
|
||||
psc_target_service = module.apigee.instances[each.key].service_attachment
|
||||
network = module.vpc.network.self_link
|
||||
subnetwork = module.vpc.subnets_psc["${each.value.region}/subnet-psc-${each.value.region}"].self_link
|
||||
}
|
||||
|
||||
module "glb" {
|
||||
source = "../../../modules/net-glb"
|
||||
name = "glb"
|
||||
project_id = module.project.project_id
|
||||
|
||||
https = true
|
||||
reserve_ip_address = true
|
||||
|
||||
ssl_certificates_config = { for k, v in var.envgroups :
|
||||
"${k}-domain" => {
|
||||
domains = v,
|
||||
unmanaged_config = null
|
||||
}
|
||||
}
|
||||
|
||||
target_proxy_https_config = {
|
||||
ssl_certificates = [for k, v in var.envgroups : "${k}-domain"]
|
||||
}
|
||||
|
||||
health_checks_config_defaults = null
|
||||
|
||||
backend_services_config = {
|
||||
apigee = {
|
||||
bucket_config = null
|
||||
enable_cdn = false
|
||||
cdn_config = null
|
||||
group_config = {
|
||||
backends = [for k, v in google_compute_region_network_endpoint_group.neg :
|
||||
{
|
||||
group = v.id
|
||||
options = null
|
||||
}
|
||||
],
|
||||
health_checks = []
|
||||
log_config = null
|
||||
options = {
|
||||
affinity_cookie_ttl_sec = null
|
||||
custom_request_headers = null
|
||||
custom_response_headers = null
|
||||
connection_draining_timeout_sec = null
|
||||
load_balancing_scheme = "EXTERNAL_MANAGED"
|
||||
locality_lb_policy = null
|
||||
port_name = null
|
||||
security_policy = null
|
||||
session_affinity = null
|
||||
timeout_sec = null
|
||||
circuits_breakers = null
|
||||
consistent_hash = null
|
||||
iap = null
|
||||
protocol = "HTTPS"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
global_forwarding_rule_config = {
|
||||
load_balancing_scheme = "EXTERNAL_MANAGED"
|
||||
ip_protocol = "TCP"
|
||||
ip_version = "IPV4"
|
||||
port_range = null
|
||||
}
|
||||
}
|
||||
|
||||
module "pubsub_export" {
|
||||
source = "../../../modules/pubsub"
|
||||
project_id = module.project.project_id
|
||||
name = "topic-export"
|
||||
}
|
||||
|
||||
module "bucket_export" {
|
||||
source = "../../../modules/gcs"
|
||||
project_id = module.project.project_id
|
||||
name = "${module.project.project_id}-export"
|
||||
iam = {
|
||||
"roles/storage.objectViewer" = [module.function_gcs2bq.service_account_iam_email]
|
||||
}
|
||||
notification_config = {
|
||||
enabled = true
|
||||
payload_format = "JSON_API_V1"
|
||||
sa_email = module.project.service_accounts.robots.storage
|
||||
topic_name = "topic-gcs2bq"
|
||||
event_types = ["OBJECT_FINALIZE"]
|
||||
custom_attributes = {}
|
||||
}
|
||||
}
|
||||
|
||||
module "function_export" {
|
||||
source = "../../../modules/cloud-function"
|
||||
project_id = module.project.project_id
|
||||
name = "export"
|
||||
bucket_name = "${module.project.project_id}-code-export"
|
||||
region = var.organization.analytics_region
|
||||
ingress_settings = "ALLOW_INTERNAL_ONLY"
|
||||
bucket_config = {
|
||||
location = null
|
||||
lifecycle_delete_age = 1
|
||||
}
|
||||
bundle_config = {
|
||||
source_dir = "${path.module}/functions/export"
|
||||
output_path = "${path.module}/bundle-export.zip"
|
||||
excludes = null
|
||||
}
|
||||
function_config = {
|
||||
entry_point = "export"
|
||||
instances = null
|
||||
memory = null
|
||||
runtime = "nodejs16"
|
||||
timeout = 180
|
||||
}
|
||||
environment_variables = {
|
||||
ORGANIZATION = module.apigee.org_name,
|
||||
ENVIRONMENTS = join(",", [for k, v in module.apigee.environments : k])
|
||||
DATASTORE = var.datastore_name
|
||||
}
|
||||
trigger_config = {
|
||||
event = "google.pubsub.topic.publish"
|
||||
resource = module.pubsub_export.id
|
||||
retry = null
|
||||
}
|
||||
service_account_create = true
|
||||
}
|
||||
|
||||
module "function_gcs2bq" {
|
||||
source = "../../../modules/cloud-function"
|
||||
project_id = module.project.project_id
|
||||
name = "gcs2bq"
|
||||
bucket_name = "${module.project.project_id}-code-gcs2bq"
|
||||
region = var.organization.analytics_region
|
||||
ingress_settings = "ALLOW_INTERNAL_ONLY"
|
||||
bucket_config = {
|
||||
location = null
|
||||
lifecycle_delete_age = 1
|
||||
}
|
||||
bundle_config = {
|
||||
source_dir = "${path.module}/functions/gcs2bq"
|
||||
output_path = "${path.module}/bundle-gcs2bq.zip"
|
||||
excludes = null
|
||||
}
|
||||
function_config = {
|
||||
entry_point = "gcs2bq"
|
||||
instances = null
|
||||
memory = null
|
||||
runtime = "nodejs16"
|
||||
timeout = 180
|
||||
}
|
||||
environment_variables = {
|
||||
DATASET = module.bigquery_dataset.dataset_id
|
||||
TABLE = module.bigquery_dataset.tables["analytics"].table_id
|
||||
LOCATION = var.organization.analytics_region
|
||||
}
|
||||
trigger_config = {
|
||||
event = "google.pubsub.topic.publish"
|
||||
resource = module.bucket_export.topic
|
||||
retry = null
|
||||
}
|
||||
service_account_create = true
|
||||
}
|
||||
|
||||
module "bigquery_dataset" {
|
||||
source = "../../../modules/bigquery-dataset"
|
||||
project_id = module.project.project_id
|
||||
id = "apigee"
|
||||
location = var.organization.analytics_region
|
||||
tables = {
|
||||
analytics = {
|
||||
friendly_name = "analytics"
|
||||
labels = {}
|
||||
options = null
|
||||
partitioning = {
|
||||
field = "client_received_end_timestamp"
|
||||
range = null
|
||||
time = { type = "DAY", expiration_ms = null }
|
||||
}
|
||||
schema = file("${path.module}/functions/gcs2bq/schema.json")
|
||||
deletion_protection = false
|
||||
}
|
||||
}
|
||||
iam = {
|
||||
"roles/bigquery.dataEditor" = [module.function_gcs2bq.service_account_iam_email]
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_app_engine_application" "app" {
|
||||
project = module.project.project_id
|
||||
location_id = ((var.organization.analytics_region == "europe-west1" || var.organization.analytics_region == "us-central1") ?
|
||||
substr(var.organization.analytics_region, 0, length(var.organization.analytics_region) - 1) :
|
||||
var.organization.analytics_region)
|
||||
}
|
||||
|
||||
resource "google_cloud_scheduler_job" "job" {
|
||||
name = "export"
|
||||
schedule = "0 4 * * *"
|
||||
time_zone = "Etc/UTC"
|
||||
attempt_deadline = "320s"
|
||||
project = module.project.project_id
|
||||
region = var.organization.analytics_region
|
||||
pubsub_target {
|
||||
topic_name = module.pubsub_export.id
|
||||
data = base64encode("test")
|
||||
}
|
||||
}
|
||||
|
||||
resource "local_file" "create_datastore_file" {
|
||||
content = templatefile("${path.module}/templates/create-datastore.sh.tpl", {
|
||||
org_name = module.apigee.org_name
|
||||
project_id = module.project.project_id
|
||||
datastore_name = var.datastore_name
|
||||
bucket_name = module.bucket_export.name
|
||||
path = var.path
|
||||
})
|
||||
filename = "${path.module}/create-datastore.sh"
|
||||
file_permission = "0777"
|
||||
}
|
||||
|
||||
resource "local_file" "deploy_apiproxy_file" {
|
||||
content = templatefile("${path.module}/templates/deploy-apiproxy.sh.tpl", {
|
||||
org_name = module.apigee.org_name
|
||||
})
|
||||
filename = "${path.module}/deploy-apiproxy.sh"
|
||||
file_permission = "0777"
|
||||
}
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
variable "bucket_name" {
|
||||
type = string
|
||||
default = "test"
|
||||
output "ip_address" {
|
||||
description = "IP address."
|
||||
value = module.glb.ip_address
|
||||
}
|
|
@ -0,0 +1,251 @@
|
|||
{
|
||||
"name": "apigee",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"dependencies": {
|
||||
"superagent-debugger": "^1.2.9"
|
||||
}
|
||||
},
|
||||
"node_modules/ansi-regex": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
|
||||
"integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ansi-styles": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
|
||||
"integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/chalk": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
|
||||
"integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==",
|
||||
"dependencies": {
|
||||
"ansi-styles": "^2.2.1",
|
||||
"escape-string-regexp": "^1.0.2",
|
||||
"has-ansi": "^2.0.0",
|
||||
"strip-ansi": "^3.0.0",
|
||||
"supports-color": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/debug": {
|
||||
"version": "2.6.9",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||
"dependencies": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/escape-string-regexp": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||
"integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/has-ansi": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
|
||||
"integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==",
|
||||
"dependencies": {
|
||||
"ansi-regex": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/lodash": {
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
|
||||
},
|
||||
"node_modules/moment": {
|
||||
"version": "2.29.4",
|
||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz",
|
||||
"integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==",
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
|
||||
},
|
||||
"node_modules/object-assign": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/query-string": {
|
||||
"version": "4.3.4",
|
||||
"resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz",
|
||||
"integrity": "sha512-O2XLNDBIg1DnTOa+2XrIwSiXEV8h2KImXUnjhhn2+UsvZ+Es2uyd5CCRTNQlDGbzUQOW3aYCBx9rVA6dzsiY7Q==",
|
||||
"dependencies": {
|
||||
"object-assign": "^4.1.0",
|
||||
"strict-uri-encode": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/strict-uri-encode": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
|
||||
"integrity": "sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/strip-ansi": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||
"integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==",
|
||||
"dependencies": {
|
||||
"ansi-regex": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/superagent-debugger": {
|
||||
"version": "1.2.9",
|
||||
"resolved": "https://registry.npmjs.org/superagent-debugger/-/superagent-debugger-1.2.9.tgz",
|
||||
"integrity": "sha512-iH4NvJl1utorgRbrsYoOM8yoeTbS7YWLoDkAwRy2rgB6aP5Lr36XxmpE8GbgvmUY6R4QmYr+4R4IdAGMPmwR9g==",
|
||||
"dependencies": {
|
||||
"chalk": "^1.1.3",
|
||||
"debug": "^2.6.0",
|
||||
"lodash": "^4.17.4",
|
||||
"moment": "^2.17.1",
|
||||
"query-string": "^4.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/supports-color": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
|
||||
"integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==",
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-regex": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
|
||||
"integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA=="
|
||||
},
|
||||
"ansi-styles": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
|
||||
"integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA=="
|
||||
},
|
||||
"chalk": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
|
||||
"integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==",
|
||||
"requires": {
|
||||
"ansi-styles": "^2.2.1",
|
||||
"escape-string-regexp": "^1.0.2",
|
||||
"has-ansi": "^2.0.0",
|
||||
"strip-ansi": "^3.0.0",
|
||||
"supports-color": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"debug": {
|
||||
"version": "2.6.9",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||
"requires": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"escape-string-regexp": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||
"integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg=="
|
||||
},
|
||||
"has-ansi": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
|
||||
"integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==",
|
||||
"requires": {
|
||||
"ansi-regex": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"lodash": {
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
|
||||
},
|
||||
"moment": {
|
||||
"version": "2.29.4",
|
||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz",
|
||||
"integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w=="
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
|
||||
},
|
||||
"object-assign": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="
|
||||
},
|
||||
"query-string": {
|
||||
"version": "4.3.4",
|
||||
"resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz",
|
||||
"integrity": "sha512-O2XLNDBIg1DnTOa+2XrIwSiXEV8h2KImXUnjhhn2+UsvZ+Es2uyd5CCRTNQlDGbzUQOW3aYCBx9rVA6dzsiY7Q==",
|
||||
"requires": {
|
||||
"object-assign": "^4.1.0",
|
||||
"strict-uri-encode": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"strict-uri-encode": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
|
||||
"integrity": "sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ=="
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||
"integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==",
|
||||
"requires": {
|
||||
"ansi-regex": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"superagent-debugger": {
|
||||
"version": "1.2.9",
|
||||
"resolved": "https://registry.npmjs.org/superagent-debugger/-/superagent-debugger-1.2.9.tgz",
|
||||
"integrity": "sha512-iH4NvJl1utorgRbrsYoOM8yoeTbS7YWLoDkAwRy2rgB6aP5Lr36XxmpE8GbgvmUY6R4QmYr+4R4IdAGMPmwR9g==",
|
||||
"requires": {
|
||||
"chalk": "^1.1.3",
|
||||
"debug": "^2.6.0",
|
||||
"lodash": "^4.17.4",
|
||||
"moment": "^2.17.1",
|
||||
"query-string": "^4.3.1"
|
||||
}
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
|
||||
"integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g=="
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
# Copyright 2022 Google LLC
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
#!/bin/bash
|
||||
|
||||
if [ $# -lt 2 ]; then
|
||||
echo "Usage: $0 ENVGROUP_HOSTNAME NUM_REQUESTS"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ENVGROUP_HOSTNAME=$1
|
||||
NUM_REQUESTS=$2
|
||||
|
||||
for i in $(seq 1 $NUM_REQUESTS)
|
||||
do
|
||||
curl -v https://$ENVGROUP_HOSTNAME/httpbin/headers
|
||||
done
|
|
@ -0,0 +1,30 @@
|
|||
# Copyright 2022 Google LLC
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
#!/bin/bash
|
||||
|
||||
curl "https://apigee.googleapis.com/v1/organizations/${org_name}/analytics/datastores" \
|
||||
-X POST \
|
||||
-H "Content-type:application/json" \
|
||||
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
|
||||
-d \
|
||||
'{
|
||||
"displayName": "${datastore_name}",
|
||||
"targetType": "gcs",
|
||||
"datastoreConfig": {
|
||||
"projectId": "${project_id}",
|
||||
"bucketName": "${bucket_name}",
|
||||
"path": "${path}"
|
||||
}
|
||||
}'
|
|
@ -0,0 +1,41 @@
|
|||
# Copyright 2022 Google LLC
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
#!/bin/bash
|
||||
|
||||
if [ $# -lt 1 ]; then
|
||||
echo "Usage: $0 ENV_NAME"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ORG_NAME=${org_name}
|
||||
ENV_NAME=$1
|
||||
|
||||
wget https://github.com/apigee/api-platform-samples/raw/master/sample-proxies/apigee-quickstart/httpbin_rev1_2020_02_02.zip -O apiproxy.zip
|
||||
|
||||
export TOKEN=$(gcloud auth print-access-token)
|
||||
|
||||
curl -v -X POST \
|
||||
-H "Authorization: Bearer $TOKEN" \
|
||||
-H "Content-Type:application/octet-stream" \
|
||||
-T 'apiproxy.zip' \
|
||||
"https://apigee.googleapis.com/v1/organizations/$ORG_NAME/apis?name=httpbin&action=import"
|
||||
|
||||
curl -v -X POST \
|
||||
-H "Authorization: Bearer $TOKEN" \
|
||||
"https://apigee.googleapis.com/v1/organizations/$ORG_NAME/environments/$ENV_NAME/apis/httpbin/revisions/1/deployments"
|
||||
|
||||
curl -v \
|
||||
-H "Authorization: Bearer $TOKEN" \
|
||||
"https://apigee.googleapis.com/v1/organizations/$ORG_NAME/environments/$ENV_NAME/apis/httpbin/revisions/1/deployments"
|
|
@ -0,0 +1,23 @@
|
|||
project_create = {
|
||||
billing_account_id = "011D94-9C86C1-ADD197"
|
||||
parent = "folders/586929298360"
|
||||
}
|
||||
project_id = "g-prj-cd-sb-apigee-bq-10"
|
||||
envgroups = {
|
||||
test = ["test.cool-demos.space"]
|
||||
}
|
||||
environments = {
|
||||
apis-test = {
|
||||
envgroups = ["test"]
|
||||
}
|
||||
}
|
||||
instances = {
|
||||
instance-ew1 = {
|
||||
region = "europe-west1"
|
||||
environments = ["apis-test"]
|
||||
psa_ip_cidr_range = "10.0.4.0/22"
|
||||
}
|
||||
}
|
||||
psc_config = {
|
||||
europe-west1 = "10.0.0.0/28"
|
||||
}
|
|
@ -0,0 +1,108 @@
|
|||
/**
|
||||
* Copyright 2022 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
variable "datastore_name" {
|
||||
description = "Datastore"
|
||||
type = string
|
||||
nullable = false
|
||||
default = "gcs"
|
||||
}
|
||||
|
||||
variable "envgroups" {
|
||||
description = "Environment groups (NAME => [HOSTNAMES])."
|
||||
type = map(list(string))
|
||||
nullable = false
|
||||
}
|
||||
|
||||
variable "environments" {
|
||||
description = "Environments."
|
||||
type = map(object({
|
||||
display_name = optional(string)
|
||||
description = optional(string)
|
||||
node_config = optional(object({
|
||||
min_node_count = optional(number)
|
||||
max_node_count = optional(number)
|
||||
current_aggregate_node_count = number
|
||||
}))
|
||||
iam = optional(map(list(string)))
|
||||
envgroups = list(string)
|
||||
}))
|
||||
nullable = false
|
||||
}
|
||||
|
||||
variable "instances" {
|
||||
description = "Instance."
|
||||
type = map(object({
|
||||
display_name = optional(string)
|
||||
description = optional(string)
|
||||
region = string
|
||||
environments = list(string)
|
||||
psa_ip_cidr_range = string
|
||||
disk_encryption_key = optional(string)
|
||||
consumer_accept_list = optional(list(string))
|
||||
}))
|
||||
nullable = false
|
||||
}
|
||||
|
||||
variable "organization" {
|
||||
description = "Apigee organization."
|
||||
type = object({
|
||||
display_name = optional(string, "Apigee organization created by tf module")
|
||||
description = optional(string, "Apigee organization created by tf module")
|
||||
authorized_network = optional(string, "vpc")
|
||||
runtime_type = optional(string, "CLOUD")
|
||||
billing_type = optional(string)
|
||||
database_encryption_key = optional(string)
|
||||
analytics_region = optional(string, "europe-west1")
|
||||
})
|
||||
nullable = false
|
||||
default = {
|
||||
}
|
||||
}
|
||||
|
||||
variable "path" {
|
||||
description = "Bucket path."
|
||||
type = string
|
||||
default = "/analytics"
|
||||
nullable = false
|
||||
}
|
||||
|
||||
variable "project_create" {
|
||||
description = "Parameters for the creation of the new project."
|
||||
type = object({
|
||||
billing_account_id = string
|
||||
parent = string
|
||||
})
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "project_id" {
|
||||
description = "Project ID."
|
||||
type = string
|
||||
nullable = false
|
||||
}
|
||||
|
||||
variable "psc_config" {
|
||||
description = "PSC configuration."
|
||||
type = map(string)
|
||||
nullable = false
|
||||
}
|
||||
|
||||
variable "vpc_create" {
|
||||
description = "Boolean flag indicating whether the VPC should be created or not."
|
||||
type = bool
|
||||
default = true
|
||||
}
|
|
@ -79,19 +79,18 @@ module "cf" {
|
|||
name = var.name
|
||||
bucket_name = "${var.name}-${random_pet.random.id}"
|
||||
bucket_config = {
|
||||
location = var.region
|
||||
lifecycle_delete_age = null
|
||||
location = var.region
|
||||
}
|
||||
bundle_config = {
|
||||
source_dir = "cf"
|
||||
output_path = var.bundle_path
|
||||
excludes = null
|
||||
}
|
||||
service_account = module.service-account.email
|
||||
trigger_config = {
|
||||
event = "google.pubsub.topic.publish"
|
||||
resource = module.pubsub.topic.id
|
||||
retry = null
|
||||
v1 = {
|
||||
event = "google.pubsub.topic.publish"
|
||||
resource = module.pubsub.topic.id
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -26,11 +26,11 @@ Note that Terraform 0.13 at least is required due to the use of `for_each` with
|
|||
|---|---|:---:|:---:|:---:|
|
||||
| [billing_account_id](variables.tf#L17) | Billing account associated with the GCP Projects that will be created for each team. | <code>string</code> | ✓ | |
|
||||
| [folder_id](variables.tf#L28) | Folder ID in which DNS projects will be created. | <code>string</code> | ✓ | |
|
||||
| [shared_vpc_link](variables.tf#L48) | Shared VPC self link, used for DNS peering. | <code>string</code> | ✓ | |
|
||||
| [prefix](variables.tf#L33) | Prefix used for resource names. | <code>string</code> | ✓ | |
|
||||
| [shared_vpc_link](variables.tf#L51) | Shared VPC self link, used for DNS peering. | <code>string</code> | ✓ | |
|
||||
| [dns_domain](variables.tf#L22) | DNS domain under which each application team DNS domain will be created. | <code>string</code> | | <code>"example.org"</code> |
|
||||
| [prefix](variables.tf#L33) | Customer name to use as prefix for resources' naming. | <code>string</code> | | <code>"test-dns"</code> |
|
||||
| [project_services](variables.tf#L39) | Service APIs enabled by default. | <code>list(string)</code> | | <code title="[ "compute.googleapis.com", "dns.googleapis.com", ]">[…]</code> |
|
||||
| [teams](variables.tf#L53) | List of application teams requiring their own Cloud DNS instance. | <code>list(string)</code> | | <code title="[ "team1", "team2", ]">[…]</code> |
|
||||
| [project_services](variables.tf#L42) | Service APIs enabled by default. | <code>list(string)</code> | | <code title="[ "compute.googleapis.com", "dns.googleapis.com", ]">[…]</code> |
|
||||
| [teams](variables.tf#L56) | List of application teams requiring their own Cloud DNS instance. | <code>list(string)</code> | | <code title="[ "team1", "team2", ]">[…]</code> |
|
||||
|
||||
## Outputs
|
||||
|
||||
|
|
|
@ -50,8 +50,12 @@ variable "billing_account" {
|
|||
}
|
||||
|
||||
variable "prefix" {
|
||||
description = "Customer name to use as prefix for resources' naming."
|
||||
default = "test-dns"
|
||||
description = "Prefix used for resource names."
|
||||
type = string
|
||||
validation {
|
||||
condition = var.prefix != ""
|
||||
error_message = "Prefix cannot be empty."
|
||||
}
|
||||
}
|
||||
|
||||
variable "dns_domain" {
|
||||
|
|
|
@ -31,9 +31,12 @@ variable "folder_id" {
|
|||
}
|
||||
|
||||
variable "prefix" {
|
||||
description = "Customer name to use as prefix for resources' naming."
|
||||
description = "Prefix used for resource names."
|
||||
type = string
|
||||
default = "test-dns"
|
||||
validation {
|
||||
condition = var.prefix != ""
|
||||
error_message = "Prefix cannot be empty."
|
||||
}
|
||||
}
|
||||
|
||||
variable "project_services" {
|
||||
|
|
|
@ -27,13 +27,12 @@ By changing the `restricted_role_grant`, the blueprint can be used to grant admi
|
|||
|
||||
You can easily configure the blueprint for this use case:
|
||||
|
||||
```hcl
|
||||
```tfvars
|
||||
# terraform.tfvars
|
||||
|
||||
delegated_role_grants = ["roles/compute.networkUser"]
|
||||
direct_role_grants = []
|
||||
direct_role_grants = []
|
||||
restricted_role_grant = "roles/compute.networkAdmin"
|
||||
# tftest skip
|
||||
```
|
||||
|
||||
This diagram shows the resources and expected behaviour:
|
||||
|
|
|
@ -16,20 +16,25 @@ Three metric descriptors are created for each monitored resource: usage, limit a
|
|||
Clone this repository, then go through the following steps to create resources:
|
||||
- Create a terraform.tfvars file with the following content:
|
||||
```tfvars
|
||||
organization_id = "<YOUR-ORG-ID>"
|
||||
billing_account = "<YOUR-BILLING-ACCOUNT>"
|
||||
monitoring_project_id = "project-0" # Monitoring project where the dashboard will be created and the solution deployed
|
||||
monitored_projects_list = ["project-1", "project2"] # Projects to be monitored by the solution
|
||||
monitored_folders_list = ["folder_id"] # Folders to be monitored by the solution
|
||||
v2 = false # Set to true to use V2 Cloud Functions environment
|
||||
```
|
||||
organization_id = "<YOUR-ORG-ID>"
|
||||
billing_account = "<YOUR-BILLING-ACCOUNT>"
|
||||
monitoring_project_id = "<YOUR-MONITORING-PROJECT>"
|
||||
# Monitoring project where the dashboard will be created and the solution deployed, a project named "mon-network-dahshboard" will be created if left blank
|
||||
monitored_projects_list = ["project-1", "project2"]
|
||||
# Projects to be monitored by the solution
|
||||
monitored_folders_list = ["folder_id"]
|
||||
# Folders to be monitored by the solution
|
||||
prefix = "<YOUR-PREFIX>"
|
||||
# Monitoring project name prefix, monitoring project name is <YOUR-PREFIX>-network-dashboard, ignored if monitoring_project_id variable is provided
|
||||
cf_version = V1|V2
|
||||
# Set to V2 to use V2 Cloud Functions environment
|
||||
```
|
||||
- `terraform init`
|
||||
- `terraform apply`
|
||||
|
||||
Note: Org level viewing permission is required for some metrics such as firewall policies.
|
||||
|
||||
Once the resources are deployed, go to the following page to see the dashboard: https://console.cloud.google.com/monitoring/dashboards?project=<YOUR-MONITORING-PROJECT>.
|
||||
A dashboard called "quotas-utilization" should be created.
|
||||
Once the resources are deployed, go to the following page to see the dashboard: https://console.cloud.google.com/monitoring/dashboards?project=<YOUR-MONITORING-PROJECT> a dashboard called "quotas-utilization" should be created.
|
||||
|
||||
The Cloud Function runs every 10 minutes by default so you should start getting some data points after a few minutes.
|
||||
You can use the metric explorer to view the data points for the different custom metrics created: https://console.cloud.google.com/monitoring/metrics-explorer?project=<YOUR-MONITORING-PROJECT>.
|
||||
|
@ -69,7 +74,6 @@ Note that metrics are created in the cloud-function/metrics.yaml file. You can a
|
|||
- The CF assumes custom routes importing/exporting is ON, this impacts static and dynamic routes usage calculation
|
||||
- The CF assumes all networks in peering groups have the same global routing and custom routes sharing configuration
|
||||
|
||||
|
||||
## Next steps and ideas
|
||||
In a future release, we could support:
|
||||
- Google managed VPCs that are peered with PSA (such as Cloud SQL or Memorystore)
|
||||
|
@ -87,13 +91,13 @@ If you are interested in this and/or would like to contribute, please contact le
|
|||
|---|---|:---:|:---:|:---:|
|
||||
| [billing_account](variables.tf#L17) | The ID of the billing account to associate this project with | <code></code> | ✓ | |
|
||||
| [monitored_projects_list](variables.tf#L36) | ID of the projects to be monitored (where limits and quotas data will be pulled) | <code>list(string)</code> | ✓ | |
|
||||
| [organization_id](variables.tf#L47) | The organization id for the associated services | <code></code> | ✓ | |
|
||||
| [prefix](variables.tf#L51) | Customer name to use as prefix for monitoring project | <code></code> | ✓ | |
|
||||
| [organization_id](variables.tf#L46) | The organization id for the associated services | <code></code> | ✓ | |
|
||||
| [prefix](variables.tf#L50) | Prefix used for resource names. | <code>string</code> | ✓ | |
|
||||
| [cf_version](variables.tf#L21) | Cloud Function version 2nd Gen or 1st Gen. Possible options: 'V1' or 'V2'.Use CFv2 if your Cloud Function timeouts after 9 minutes. By default it is using CFv1. | <code></code> | | <code>V1</code> |
|
||||
| [monitored_folders_list](variables.tf#L30) | ID of the projects to be monitored (where limits and quotas data will be pulled) | <code>list(string)</code> | | <code>[]</code> |
|
||||
| [monitoring_project_id](variables.tf#L41) | Monitoring project where the dashboard will be created and the solution deployed; a project will be created if set to empty string | <code></code> | | |
|
||||
| [project_monitoring_services](variables.tf#L55) | Service APIs enabled in the monitoring project if it will be created. | <code></code> | | <code title="[ "artifactregistry.googleapis.com", "cloudasset.googleapis.com", "cloudbilling.googleapis.com", "cloudbuild.googleapis.com", "cloudresourcemanager.googleapis.com", "cloudscheduler.googleapis.com", "compute.googleapis.com", "cloudfunctions.googleapis.com", "iam.googleapis.com", "iamcredentials.googleapis.com", "logging.googleapis.com", "monitoring.googleapis.com", "run.googleapis.com", "serviceusage.googleapis.com" ]">[…]</code> |
|
||||
| [region](variables.tf#L75) | Region used to deploy the cloud functions and scheduler | <code></code> | | <code>europe-west1</code> |
|
||||
| [schedule_cron](variables.tf#L80) | Cron format schedule to run the Cloud Function. Default is every 10 minutes. | <code></code> | | <code>*/10 * * * *</code> |
|
||||
| [project_monitoring_services](variables.tf#L59) | Service APIs enabled in the monitoring project if it will be created. | <code></code> | | <code title="[ "artifactregistry.googleapis.com", "cloudasset.googleapis.com", "cloudbilling.googleapis.com", "cloudbuild.googleapis.com", "cloudfunctions.googleapis.com", "cloudresourcemanager.googleapis.com", "cloudscheduler.googleapis.com", "compute.googleapis.com", "iam.googleapis.com", "iamcredentials.googleapis.com", "logging.googleapis.com", "monitoring.googleapis.com", "pubsub.googleapis.com", "run.googleapis.com", "servicenetworking.googleapis.com", "serviceusage.googleapis.com", "storage-component.googleapis.com" ]">[…]</code> |
|
||||
| [region](variables.tf#L81) | Region used to deploy the cloud functions and scheduler | <code></code> | | <code>europe-west1</code> |
|
||||
| [schedule_cron](variables.tf#L86) | Cron format schedule to run the Cloud Function. Default is every 10 minutes. | <code></code> | | <code>*/10 * * * *</code> |
|
||||
|
||||
<!-- END TFDOC -->
|
||||
|
|
|
@ -187,7 +187,7 @@ def count_effective_limit(config, project_id, network_dict, usage_metric_name,
|
|||
for peered_network in network_dict['peerings']:
|
||||
if 'usage' not in peered_network:
|
||||
print(
|
||||
f"Can not add metrics for peered network in projects/{project_id} as no usage metrics exist due to missing permissions"
|
||||
f"Cannot add metrics for peered network in projects/{project_id} as no usage metrics exist due to missing permissions"
|
||||
)
|
||||
continue
|
||||
peering_group_usage += peered_network['usage']
|
||||
|
|
|
@ -30,7 +30,7 @@ locals {
|
|||
module "project-monitoring" {
|
||||
count = var.monitoring_project_id == "" ? 1 : 0
|
||||
source = "../../../modules/project"
|
||||
name = "monitoring"
|
||||
name = "network-dashboards"
|
||||
parent = "organizations/${var.organization_id}"
|
||||
prefix = var.prefix
|
||||
billing_account = var.billing_account
|
||||
|
@ -137,15 +137,13 @@ module "cloud-function" {
|
|||
name = "network-dashboard-cloud-function"
|
||||
bucket_name = "${local.monitoring_project}-network-dashboard-bucket"
|
||||
bucket_config = {
|
||||
location = var.region
|
||||
lifecycle_delete_age = null
|
||||
location = var.region
|
||||
}
|
||||
region = var.region
|
||||
|
||||
bundle_config = {
|
||||
source_dir = "cloud-function"
|
||||
output_path = "cloud-function.zip"
|
||||
excludes = null
|
||||
}
|
||||
|
||||
function_config = {
|
||||
|
@ -153,7 +151,7 @@ module "cloud-function" {
|
|||
entry_point = "main"
|
||||
runtime = "python39"
|
||||
instances = 1
|
||||
memory = 256 # Memory in MB
|
||||
memory_mb = 256
|
||||
|
||||
}
|
||||
|
||||
|
@ -169,10 +167,17 @@ module "cloud-function" {
|
|||
# Internal only doesn't seem to work with CFv2:
|
||||
ingress_settings = var.cf_version == "V2" ? "ALLOW_ALL" : "ALLOW_INTERNAL_ONLY"
|
||||
|
||||
trigger_config = {
|
||||
event = "google.pubsub.topic.publish"
|
||||
resource = module.pubsub.topic.id
|
||||
retry = null
|
||||
trigger_config = var.cf_version == "V2" ? {
|
||||
v2 = {
|
||||
event_type = "google.cloud.pubsub.topic.v1.messagePublished"
|
||||
pubsub_topic = module.pubsub.topic.id
|
||||
service_account_create = true
|
||||
}
|
||||
} : {
|
||||
v1 = {
|
||||
event = "google.pubsub.topic.publish"
|
||||
resource = module.pubsub.topic.id
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,12 @@ variable "billing_account" {
|
|||
}
|
||||
|
||||
variable "prefix" {
|
||||
description = "Customer name to use as prefix for resources' naming"
|
||||
description = "Prefix used for resource names."
|
||||
type = string
|
||||
validation {
|
||||
condition = var.prefix != ""
|
||||
error_message = "Prefix cannot be empty."
|
||||
}
|
||||
}
|
||||
|
||||
variable "project_vm_services" {
|
||||
|
@ -36,7 +41,6 @@ variable "project_vm_services" {
|
|||
"servicenetworking.googleapis.com",
|
||||
]
|
||||
}
|
||||
|
||||
variable "region" {
|
||||
description = "Region used to deploy subnets"
|
||||
default = "europe-west1"
|
||||
|
@ -45,4 +49,4 @@ variable "region" {
|
|||
variable "zone" {
|
||||
description = "Zone used to deploy vms"
|
||||
default = "europe-west1-b"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,13 +43,17 @@ variable "monitoring_project_id" {
|
|||
default = ""
|
||||
}
|
||||
|
||||
|
||||
variable "organization_id" {
|
||||
description = "The organization id for the associated services"
|
||||
}
|
||||
|
||||
variable "prefix" {
|
||||
description = "Customer name to use as prefix for monitoring project"
|
||||
description = "Prefix used for resource names."
|
||||
type = string
|
||||
validation {
|
||||
condition = var.prefix != ""
|
||||
error_message = "Prefix cannot be empty."
|
||||
}
|
||||
}
|
||||
|
||||
variable "project_monitoring_services" {
|
||||
|
@ -59,19 +63,21 @@ variable "project_monitoring_services" {
|
|||
"cloudasset.googleapis.com",
|
||||
"cloudbilling.googleapis.com",
|
||||
"cloudbuild.googleapis.com",
|
||||
"cloudfunctions.googleapis.com",
|
||||
"cloudresourcemanager.googleapis.com",
|
||||
"cloudscheduler.googleapis.com",
|
||||
"compute.googleapis.com",
|
||||
"cloudfunctions.googleapis.com",
|
||||
"iam.googleapis.com",
|
||||
"iamcredentials.googleapis.com",
|
||||
"logging.googleapis.com",
|
||||
"monitoring.googleapis.com",
|
||||
"pubsub.googleapis.com",
|
||||
"run.googleapis.com",
|
||||
"serviceusage.googleapis.com"
|
||||
"servicenetworking.googleapis.com",
|
||||
"serviceusage.googleapis.com",
|
||||
"storage-component.googleapis.com"
|
||||
]
|
||||
}
|
||||
|
||||
variable "region" {
|
||||
description = "Region used to deploy the cloud functions and scheduler"
|
||||
default = "europe-west1"
|
||||
|
|
|
@ -52,13 +52,11 @@ module "cf" {
|
|||
name = var.name
|
||||
bucket_name = "${var.name}-${random_pet.random.id}"
|
||||
bucket_config = {
|
||||
location = var.region
|
||||
lifecycle_delete_age = null
|
||||
location = var.region
|
||||
}
|
||||
bundle_config = {
|
||||
source_dir = "cf"
|
||||
output_path = var.bundle_path
|
||||
excludes = null
|
||||
}
|
||||
# https://github.com/hashicorp/terraform-provider-archive/issues/40
|
||||
# https://issuetracker.google.com/issues/155215191
|
||||
|
@ -68,9 +66,10 @@ module "cf" {
|
|||
}
|
||||
service_account_create = true
|
||||
trigger_config = {
|
||||
event = "google.pubsub.topic.publish"
|
||||
resource = module.pubsub.topic.id
|
||||
retry = null
|
||||
v1 = {
|
||||
event = "google.pubsub.topic.publish"
|
||||
resource = module.pubsub.topic.id
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -91,19 +91,18 @@ module "cf" {
|
|||
name = var.name
|
||||
bucket_name = "${var.name}-${random_pet.random.id}"
|
||||
bucket_config = {
|
||||
location = var.region
|
||||
lifecycle_delete_age = null
|
||||
location = var.region
|
||||
}
|
||||
bundle_config = {
|
||||
source_dir = "cf"
|
||||
output_path = var.bundle_path
|
||||
excludes = null
|
||||
}
|
||||
service_account = module.service-account.email
|
||||
trigger_config = {
|
||||
event = "google.pubsub.topic.publish"
|
||||
resource = module.pubsub.topic.id
|
||||
retry = null
|
||||
v1 = {
|
||||
event = "google.pubsub.topic.publish"
|
||||
resource = module.pubsub.topic.id
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -115,8 +114,8 @@ module "cffile" {
|
|||
name = var.name_cffile
|
||||
bucket_name = "${var.name_cffile}-${random_pet.random.id}"
|
||||
bucket_config = {
|
||||
location = var.region
|
||||
lifecycle_delete_age = null
|
||||
location = var.region
|
||||
lifecycle_delete_age_days = null
|
||||
}
|
||||
bundle_config = {
|
||||
source_dir = "cffile"
|
||||
|
@ -125,9 +124,11 @@ module "cffile" {
|
|||
}
|
||||
service_account = module.service-account.email
|
||||
trigger_config = {
|
||||
event = "google.pubsub.topic.publish"
|
||||
resource = module.pubsub_file.topic.id
|
||||
retry = null
|
||||
v1 = {
|
||||
event = "google.pubsub.topic.publish"
|
||||
resource = module.pubsub_file.topic.id
|
||||
retry = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,8 +11,8 @@ The codebase provisions the following list of resources:
|
|||
|
||||
| name | description | type | required | default |
|
||||
|---|---|:---:|:---:|:---:|
|
||||
| [impersonate_service_account_email](variables.tf#L21) | Service account to be impersonated by workload identity. | <code>string</code> | ✓ | |
|
||||
| [project_id](variables.tf#L16) | GCP project ID. | <code>string</code> | ✓ | |
|
||||
| [impersonate_service_account_email](variables.tf#L16) | Service account to be impersonated by workload identity. | <code>string</code> | ✓ | |
|
||||
| [project_id](variables.tf#L21) | GCP project ID. | <code>string</code> | ✓ | |
|
||||
| [workload_identity_pool_provider_id](variables.tf#L26) | GCP workload identity pool provider ID. | <code>string</code> | ✓ | |
|
||||
|
||||
<!-- END TFDOC -->
|
||||
|
|
|
@ -27,9 +27,9 @@ provider "google-beta" {
|
|||
|
||||
| name | description | type | required | default |
|
||||
|---|---|:---:|:---:|:---:|
|
||||
| [impersonate_service_account_email](variables.tf#L22) | Service account to be impersonated by workload identity federation. | <code>string</code> | ✓ | |
|
||||
| [workload_identity_pool_provider_id](variables.tf#L17) | GCP workload identity pool provider ID. | <code>string</code> | ✓ | |
|
||||
| [tmp_oidc_token_path](variables.tf#L27) | Name of the temporary file where TFC OIDC token will be stored to authentificate terraform provider google. | <code>string</code> | | <code>".oidc_token"</code> |
|
||||
| [impersonate_service_account_email](variables.tf#L17) | Service account to be impersonated by workload identity federation. | <code>string</code> | ✓ | |
|
||||
| [workload_identity_pool_provider_id](variables.tf#L28) | GCP workload identity pool provider ID. | <code>string</code> | ✓ | |
|
||||
| [tmp_oidc_token_path](variables.tf#L22) | Name of the temporary file where TFC OIDC token will be stored to authentificate terraform provider google. | <code>string</code> | | <code>".oidc_token"</code> |
|
||||
|
||||
## Outputs
|
||||
|
||||
|
|
|
@ -14,11 +14,6 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
variable "workload_identity_pool_provider_id" {
|
||||
description = "GCP workload identity pool provider ID."
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "impersonate_service_account_email" {
|
||||
description = "Service account to be impersonated by workload identity federation."
|
||||
type = string
|
||||
|
@ -29,3 +24,8 @@ variable "tmp_oidc_token_path" {
|
|||
type = string
|
||||
default = ".oidc_token"
|
||||
}
|
||||
|
||||
variable "workload_identity_pool_provider_id" {
|
||||
description = "GCP workload identity pool provider ID."
|
||||
type = string
|
||||
}
|
||||
|
|
|
@ -13,13 +13,13 @@
|
|||
# limitations under the License.
|
||||
|
||||
|
||||
variable "project_id" {
|
||||
description = "GCP project ID."
|
||||
variable "impersonate_service_account_email" {
|
||||
description = "Service account to be impersonated by workload identity."
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "impersonate_service_account_email" {
|
||||
description = "Service account to be impersonated by workload identity."
|
||||
variable "project_id" {
|
||||
description = "GCP project ID."
|
||||
type = string
|
||||
}
|
||||
|
||||
|
|
|
@ -99,13 +99,13 @@ gcloud compute ssh --zone europe-west1-b nginx-test -- 'uptime'
|
|||
| name | description | type | required | default |
|
||||
|---|---|:---:|:---:|:---:|
|
||||
| [billing_account](variables.tf#L16) | Billing account id used as default for new projects. | <code>string</code> | ✓ | |
|
||||
| [project_id](variables.tf#L33) | Project id to create a project when `project_create` is `true`, or to be used when `false`. | <code>string</code> | ✓ | |
|
||||
| [grace_period](variables.tf#L56) | Grace period for an instance startup. | <code>string</code> | | <code>"180s"</code> |
|
||||
| [location](variables.tf#L21) | App Engine location used in the example (required for CloudFunctions). | <code>string</code> | | <code>"europe-west"</code> |
|
||||
| [project_create](variables.tf#L27) | Create project instead of using an existing one. | <code>bool</code> | | <code>false</code> |
|
||||
| [region](variables.tf#L38) | Compute region used in the example. | <code>string</code> | | <code>"europe-west1"</code> |
|
||||
| [root_node](variables.tf#L44) | The resource name of the parent folder or organization for project creation, in 'folders/folder_id' or 'organizations/org_id' format. | <code>string</code> | | <code>null</code> |
|
||||
| [schedule](variables.tf#L50) | Cron schedule for executing compute instances healthcheck. | <code>string</code> | | <code>"*/5 * * * *" # every five minutes"</code> |
|
||||
| [project_id](variables.tf#L39) | Project id to create a project when `project_create` is `true`, or to be used when `false`. | <code>string</code> | ✓ | |
|
||||
| [grace_period](variables.tf#L21) | Grace period for an instance startup. | <code>string</code> | | <code>"180s"</code> |
|
||||
| [location](variables.tf#L27) | App Engine location used in the example (required for CloudFunctions). | <code>string</code> | | <code>"europe-west"</code> |
|
||||
| [project_create](variables.tf#L33) | Create project instead of using an existing one. | <code>bool</code> | | <code>false</code> |
|
||||
| [region](variables.tf#L44) | Compute region used in the example. | <code>string</code> | | <code>"europe-west1"</code> |
|
||||
| [root_node](variables.tf#L50) | The resource name of the parent folder or organization for project creation, in 'folders/folder_id' or 'organizations/org_id' format. | <code>string</code> | | <code>null</code> |
|
||||
| [schedule](variables.tf#L56) | Cron schedule for executing compute instances healthcheck. | <code>string</code> | | <code>"*/5 * * * *" # every five minutes"</code> |
|
||||
| [tcp_port](variables.tf#L62) | TCP port to run healthcheck against. | <code>string</code> | | <code>"80" #http"</code> |
|
||||
| [timeout](variables.tf#L68) | TCP probe timeout. | <code>string</code> | | <code>"1000ms"</code> |
|
||||
|
||||
|
|
|
@ -114,29 +114,28 @@ module "cf-restarter" {
|
|||
region = var.region
|
||||
bucket_name = "cf-bundle-bucket-${random_pet.random.id}"
|
||||
bucket_config = {
|
||||
location = var.region
|
||||
lifecycle_delete_age = null
|
||||
location = var.region
|
||||
}
|
||||
bundle_config = {
|
||||
source_dir = "${path.module}/function/restarter"
|
||||
output_path = "restarter.zip"
|
||||
excludes = []
|
||||
}
|
||||
service_account = module.service-account-restarter.email
|
||||
|
||||
function_config = {
|
||||
entry_point = "RestartInstance"
|
||||
ingress_settings = null
|
||||
instances = 1
|
||||
memory = 256
|
||||
instance_count = 1
|
||||
memory_mb = 256
|
||||
runtime = "go116"
|
||||
timeout = 300
|
||||
}
|
||||
|
||||
trigger_config = {
|
||||
event = "google.pubsub.topic.publish"
|
||||
resource = module.pubsub.topic.id
|
||||
retry = null
|
||||
v1 = {
|
||||
event = "google.pubsub.topic.publish"
|
||||
resource = module.pubsub.topic.id
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -151,15 +150,14 @@ module "cf-healthchecker" {
|
|||
bundle_config = {
|
||||
source_dir = "${path.module}/function/healthchecker"
|
||||
output_path = "healthchecker.zip"
|
||||
excludes = []
|
||||
}
|
||||
service_account = module.service-account-healthchecker.email
|
||||
|
||||
function_config = {
|
||||
entry_point = "HealthCheck"
|
||||
ingress_settings = null
|
||||
instances = 1
|
||||
memory = 256
|
||||
instance_count = 1
|
||||
memory_mb = 256
|
||||
runtime = "go116"
|
||||
timeout = 300
|
||||
}
|
||||
|
|
|
@ -18,6 +18,12 @@ variable "billing_account" {
|
|||
type = string
|
||||
}
|
||||
|
||||
variable "grace_period" {
|
||||
description = "Grace period for an instance startup."
|
||||
type = string
|
||||
default = "180s"
|
||||
}
|
||||
|
||||
variable "location" {
|
||||
description = "App Engine location used in the example (required for CloudFunctions)."
|
||||
type = string
|
||||
|
@ -53,12 +59,6 @@ variable "schedule" {
|
|||
default = "*/5 * * * *" # every five minutes
|
||||
}
|
||||
|
||||
variable "grace_period" {
|
||||
description = "Grace period for an instance startup."
|
||||
type = string
|
||||
default = "180s"
|
||||
}
|
||||
|
||||
variable "tcp_port" {
|
||||
description = "TCP port to run healthcheck against."
|
||||
type = string
|
||||
|
|
|
@ -143,25 +143,25 @@ The above command will delete the associated resources so there will be no billa
|
|||
| name | description | type | required | default |
|
||||
|---|---|:---:|:---:|:---:|
|
||||
| [postgres_user_password](variables.tf#L40) | `postgres` user password. | <code>string</code> | ✓ | |
|
||||
| [prefix](variables.tf#L51) | Unique prefix used for resource names. Not used for project if 'project_create' is null. | <code>string</code> | ✓ | |
|
||||
| [project_id](variables.tf#L65) | Project id, references existing project if `project_create` is null. | <code>string</code> | ✓ | |
|
||||
| [data_eng_principals](variables.tf#L23) | Groups with Service Account Token creator role on service accounts in IAM format, only user supported on CloudSQL, eg 'user@domain.com'. | <code>list(string)</code> | | <code>[]</code> |
|
||||
| [network_config](variables.tf#L29) | Shared VPC network configurations to use. If null networks will be created in projects with preconfigured values. | <code title="object({ host_project = string network_self_link = string subnet_self_link = string cloudsql_psa_range = string })">object({…})</code> | | <code>null</code> |
|
||||
| [postgres_database](variables.tf#L45) | `postgres` database. | <code>string</code> | | <code>"guestbook"</code> |
|
||||
| [project_create](variables.tf#L56) | Provide values if project creation is needed, uses existing project if null. Parent is in 'folders/nnn' or 'organizations/nnn' format. | <code title="object({ billing_account_id = string parent = string })">object({…})</code> | | <code>null</code> |
|
||||
| [regions](variables.tf#L70) | Map of instance_name => location where instances will be deployed. | <code>map(string)</code> | | <code title="{ primary = "europe-west1" replica = "europe-west3" }">{…}</code> |
|
||||
| [service_encryption_keys](variables.tf#L17) | Cloud KMS keys to use to encrypt resources. Provide a key for each reagion configured. | <code>map(string)</code> | | <code>null</code> |
|
||||
| [sql_configuration](variables.tf#L84) | Cloud SQL configuration | <code title="object({ availability_type = string database_version = string psa_range = string tier = string })">object({…})</code> | | <code title="{ availability_type = "REGIONAL" database_version = "POSTGRES_13" psa_range = "10.60.0.0/16" tier = "db-g1-small" }">{…}</code> |
|
||||
| [prefix](variables.tf#L45) | Prefix used for resource names. | <code>string</code> | ✓ | |
|
||||
| [project_id](variables.tf#L63) | Project id, references existing project if `project_create` is null. | <code>string</code> | ✓ | |
|
||||
| [data_eng_principals](variables.tf#L17) | Groups with Service Account Token creator role on service accounts in IAM format, only user supported on CloudSQL, eg 'user@domain.com'. | <code>list(string)</code> | | <code>[]</code> |
|
||||
| [network_config](variables.tf#L23) | Shared VPC network configurations to use. If null networks will be created in projects with preconfigured values. | <code title="object({ host_project = string network_self_link = string subnet_self_link = string cloudsql_psa_range = string })">object({…})</code> | | <code>null</code> |
|
||||
| [postgres_database](variables.tf#L34) | `postgres` database. | <code>string</code> | | <code>"guestbook"</code> |
|
||||
| [project_create](variables.tf#L54) | Provide values if project creation is needed, uses existing project if null. Parent is in 'folders/nnn' or 'organizations/nnn' format. | <code title="object({ billing_account_id = string parent = string })">object({…})</code> | | <code>null</code> |
|
||||
| [regions](variables.tf#L68) | Map of instance_name => location where instances will be deployed. | <code>map(string)</code> | | <code title="{ primary = "europe-west1" replica = "europe-west3" }">{…}</code> |
|
||||
| [service_encryption_keys](variables.tf#L81) | Cloud KMS keys to use to encrypt resources. Provide a key for each reagion configured. | <code>map(string)</code> | | <code>null</code> |
|
||||
| [sql_configuration](variables.tf#L87) | Cloud SQL configuration | <code title="object({ availability_type = string database_version = string psa_range = string tier = string })">object({…})</code> | | <code title="{ availability_type = "REGIONAL" database_version = "POSTGRES_13" psa_range = "10.60.0.0/16" tier = "db-g1-small" }">{…}</code> |
|
||||
|
||||
## Outputs
|
||||
|
||||
| name | description | sensitive |
|
||||
|---|---|:---:|
|
||||
| [bucket](outputs.tf#L22) | Cloud storage bucket to import/export data from Cloud SQL. | |
|
||||
| [connection_names](outputs.tf#L17) | Connection name of each instance. | |
|
||||
| [demo_commands](outputs.tf#L37) | Demo commands. | |
|
||||
| [ips](outputs.tf#L27) | IP address of each instance. | |
|
||||
| [project_id](outputs.tf#L32) | ID of the project containing all the instances. | |
|
||||
| [bucket](outputs.tf#L17) | Cloud storage bucket to import/export data from Cloud SQL. | |
|
||||
| [connection_names](outputs.tf#L22) | Connection name of each instance. | |
|
||||
| [demo_commands](outputs.tf#L27) | Demo commands. | |
|
||||
| [ips](outputs.tf#L36) | IP address of each instance. | |
|
||||
| [project_id](outputs.tf#L41) | ID of the project containing all the instances. | |
|
||||
| [service_accounts](outputs.tf#L46) | Service Accounts. | |
|
||||
|
||||
<!-- END TFDOC -->
|
||||
|
|
|
@ -14,14 +14,23 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
output "bucket" {
|
||||
description = "Cloud storage bucket to import/export data from Cloud SQL."
|
||||
value = module.gcs.name
|
||||
}
|
||||
|
||||
output "connection_names" {
|
||||
description = "Connection name of each instance."
|
||||
value = module.db.connection_names
|
||||
}
|
||||
|
||||
output "bucket" {
|
||||
description = "Cloud storage bucket to import/export data from Cloud SQL."
|
||||
value = module.gcs.name
|
||||
output "demo_commands" {
|
||||
description = "Demo commands."
|
||||
value = {
|
||||
"01_ssh" = "gcloud compute ssh ${module.test-vm.instance.name} --project ${module.project.name} --zone ${var.regions.primary}-b"
|
||||
"02_cloud_sql_proxy" = "cloud_sql_proxy -enable_iam_login -instances=${module.db.connection_name}=tcp:5432 &"
|
||||
"03_psql" = "psql 'host=127.0.0.1 port=5432 sslmode=disable dbname=${var.postgres_database} user=postgres password=PASSWORD'"
|
||||
}
|
||||
}
|
||||
|
||||
output "ips" {
|
||||
|
@ -34,15 +43,6 @@ output "project_id" {
|
|||
value = module.project.project_id
|
||||
}
|
||||
|
||||
output "demo_commands" {
|
||||
description = "Demo commands."
|
||||
value = {
|
||||
"01_ssh" = "gcloud compute ssh ${module.test-vm.instance.name} --project ${module.project.name} --zone ${var.regions.primary}-b"
|
||||
"02_cloud_sql_proxy" = "cloud_sql_proxy -enable_iam_login -instances=${module.db.connection_name}=tcp:5432 &"
|
||||
"03_psql" = "psql 'host=127.0.0.1 port=5432 sslmode=disable dbname=${var.postgres_database} user=postgres password=PASSWORD'"
|
||||
}
|
||||
}
|
||||
|
||||
output "service_accounts" {
|
||||
description = "Service Accounts."
|
||||
value = {
|
||||
|
|
|
@ -14,12 +14,6 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
variable "service_encryption_keys" {
|
||||
description = "Cloud KMS keys to use to encrypt resources. Provide a key for each reagion configured."
|
||||
type = map(string)
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "data_eng_principals" {
|
||||
description = "Groups with Service Account Token creator role on service accounts in IAM format, only user supported on CloudSQL, eg 'user@domain.com'."
|
||||
type = list(string)
|
||||
|
@ -37,22 +31,26 @@ variable "network_config" {
|
|||
default = null
|
||||
}
|
||||
|
||||
variable "postgres_user_password" {
|
||||
description = "`postgres` user password."
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "postgres_database" {
|
||||
description = "`postgres` database."
|
||||
type = string
|
||||
default = "guestbook"
|
||||
}
|
||||
|
||||
variable "prefix" {
|
||||
description = "Unique prefix used for resource names. Not used for project if 'project_create' is null."
|
||||
variable "postgres_user_password" {
|
||||
description = "`postgres` user password."
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "prefix" {
|
||||
description = "Prefix used for resource names."
|
||||
type = string
|
||||
validation {
|
||||
condition = var.prefix != ""
|
||||
error_message = "Prefix cannot be empty."
|
||||
}
|
||||
}
|
||||
|
||||
variable "project_create" {
|
||||
description = "Provide values if project creation is needed, uses existing project if null. Parent is in 'folders/nnn' or 'organizations/nnn' format."
|
||||
type = object({
|
||||
|
@ -80,6 +78,11 @@ variable "regions" {
|
|||
}
|
||||
}
|
||||
|
||||
variable "service_encryption_keys" {
|
||||
description = "Cloud KMS keys to use to encrypt resources. Provide a key for each reagion configured."
|
||||
type = map(string)
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "sql_configuration" {
|
||||
description = "Cloud SQL configuration"
|
||||
|
|
|
@ -96,14 +96,14 @@ service_encryption_keys = {
|
|||
|
||||
| name | description | type | required | default |
|
||||
|---|---|:---:|:---:|:---:|
|
||||
| [prefix](variables.tf#L78) | Unique prefix used for resource names. Not used for project if 'project_create' is null. | <code>string</code> | ✓ | |
|
||||
| [project_id](variables.tf#L92) | Project id, references existing project if `project_create` is null. | <code>string</code> | ✓ | |
|
||||
| [prefix](variables.tf#L78) | Prefix used for resource names. | <code>string</code> | ✓ | |
|
||||
| [project_id](variables.tf#L96) | Project id, references existing project if `project_create` is null. | <code>string</code> | ✓ | |
|
||||
| [composer_config](variables.tf#L17) | Composer environment configuration. It accepts only following attributes: `environment_size`, `software_config` and `workloads_config`. See [attribute reference](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/composer_environment#argument-reference---cloud-composer-2) for details on settings variables. | <code title="object({ environment_size = string software_config = any workloads_config = object({ scheduler = object( { cpu = number memory_gb = number storage_gb = number count = number } ) web_server = object( { cpu = number memory_gb = number storage_gb = number } ) worker = object( { cpu = number memory_gb = number storage_gb = number min_count = number max_count = number } ) }) })">object({…})</code> | | <code title="{ environment_size = "ENVIRONMENT_SIZE_SMALL" software_config = { image_version = "composer-2-airflow-2" } workloads_config = null }">{…}</code> |
|
||||
| [iam_groups_map](variables.tf#L58) | Map of Role => groups to be added on the project. Example: { \"roles/composer.admin\" = [\"group:gcp-data-engineers@example.com\"]}. | <code>map(list(string))</code> | | <code>null</code> |
|
||||
| [network_config](variables.tf#L64) | Shared VPC network configurations to use. If null networks will be created in projects with preconfigured values. | <code title="object({ host_project = string network_self_link = string subnet_self_link = string composer_secondary_ranges = object({ pods = string services = string }) })">object({…})</code> | | <code>null</code> |
|
||||
| [project_create](variables.tf#L83) | Provide values if project creation is needed, uses existing project if null. Parent is in 'folders/nnn' or 'organizations/nnn' format. | <code title="object({ billing_account_id = string parent = string })">object({…})</code> | | <code>null</code> |
|
||||
| [region](variables.tf#L97) | Reagion where instances will be deployed. | <code>string</code> | | <code>"europe-west1"</code> |
|
||||
| [service_encryption_keys](variables.tf#L103) | Cloud KMS keys to use to encrypt resources. Provide a key for each reagion in use. | <code>map(string)</code> | | <code>null</code> |
|
||||
| [project_create](variables.tf#L87) | Provide values if project creation is needed, uses existing project if null. Parent is in 'folders/nnn' or 'organizations/nnn' format. | <code title="object({ billing_account_id = string parent = string })">object({…})</code> | | <code>null</code> |
|
||||
| [region](variables.tf#L101) | Reagion where instances will be deployed. | <code>string</code> | | <code>"europe-west1"</code> |
|
||||
| [service_encryption_keys](variables.tf#L107) | Cloud KMS keys to use to encrypt resources. Provide a key for each reagion in use. | <code>map(string)</code> | | <code>null</code> |
|
||||
|
||||
## Outputs
|
||||
|
||||
|
|
|
@ -22,7 +22,6 @@ locals {
|
|||
},
|
||||
var.iam_groups_map
|
||||
)
|
||||
|
||||
# Adding Roles on Service Identities Service account as per documentation: https://cloud.google.com/composer/docs/composer-2/configure-shared-vpc#edit_permissions_for_the_google_apis_service_account
|
||||
_shared_vpc_bindings = {
|
||||
"roles/compute.networkUser" = [
|
||||
|
|
|
@ -76,8 +76,12 @@ variable "network_config" {
|
|||
}
|
||||
|
||||
variable "prefix" {
|
||||
description = "Unique prefix used for resource names. Not used for project if 'project_create' is null."
|
||||
description = "Prefix used for resource names."
|
||||
type = string
|
||||
validation {
|
||||
condition = var.prefix != ""
|
||||
error_message = "Prefix cannot be empty."
|
||||
}
|
||||
}
|
||||
|
||||
variable "project_create" {
|
||||
|
|
|
@ -135,7 +135,6 @@ service_encryption_keys = {
|
|||
storage = "KEY_URL_MULTIREGIONAL"
|
||||
pubsub = "KEY_URL_MULTIREGIONAL"
|
||||
}
|
||||
# tftest skip
|
||||
```
|
||||
|
||||
This step is optional and depends on customer policies and security best practices.
|
||||
|
@ -198,8 +197,7 @@ billing_account_id = "111111-222222-333333"
|
|||
older_id = "folders/123456789012"
|
||||
organization_domain = "domain.com"
|
||||
prefix = "myco"
|
||||
# tftest skip`
|
||||
``
|
||||
```
|
||||
|
||||
For more fine details check variables on [`variables.tf`](./variables.tf) and update according to the desired configuration. Remember to create team groups described [below](#groups).
|
||||
|
||||
|
@ -251,29 +249,29 @@ You can find examples in the `[demo](./demo)` folder.
|
|||
| [billing_account_id](variables.tf#L17) | Billing account id. | <code>string</code> | ✓ | |
|
||||
| [folder_id](variables.tf#L53) | Folder to be used for the networking resources in folders/nnnn format. | <code>string</code> | ✓ | |
|
||||
| [organization_domain](variables.tf#L98) | Organization domain. | <code>string</code> | ✓ | |
|
||||
| [prefix](variables.tf#L103) | Unique prefix used for resource names. | <code>string</code> | ✓ | |
|
||||
| [prefix](variables.tf#L103) | Prefix used for resource names. | <code>string</code> | ✓ | |
|
||||
| [composer_config](variables.tf#L22) | Cloud Composer config. | <code title="object({ node_count = number airflow_version = string env_variables = map(string) })">object({…})</code> | | <code title="{ node_count = 3 airflow_version = "composer-1-airflow-2" env_variables = {} }">{…}</code> |
|
||||
| [data_catalog_tags](variables.tf#L36) | List of Data Catalog Policy tags to be created with optional IAM binging configuration in {tag => {ROLE => [MEMBERS]}} format. | <code>map(map(list(string)))</code> | | <code title="{ "3_Confidential" = null "2_Private" = null "1_Sensitive" = null }">{…}</code> |
|
||||
| [data_force_destroy](variables.tf#L47) | Flag to set 'force_destroy' on data services like BiguQery or Cloud Storage. | <code>bool</code> | | <code>false</code> |
|
||||
| [groups](variables.tf#L58) | User groups. | <code>map(string)</code> | | <code title="{ data-analysts = "gcp-data-analysts" data-engineers = "gcp-data-engineers" data-security = "gcp-data-security" }">{…}</code> |
|
||||
| [location](variables.tf#L68) | Location used for multi-regional resources. | <code>string</code> | | <code>"eu"</code> |
|
||||
| [network_config](variables.tf#L74) | Shared VPC network configurations to use. If null networks will be created in projects with preconfigured values. | <code title="object({ host_project = string network_self_link = string subnet_self_links = object({ load = string transformation = string orchestration = string }) composer_ip_ranges = object({ cloudsql = string gke_master = string web_server = string }) composer_secondary_ranges = object({ pods = string services = string }) })">object({…})</code> | | <code>null</code> |
|
||||
| [project_services](variables.tf#L108) | List of core services enabled on all projects. | <code>list(string)</code> | | <code title="[ "cloudresourcemanager.googleapis.com", "iam.googleapis.com", "serviceusage.googleapis.com", "stackdriver.googleapis.com" ]">[…]</code> |
|
||||
| [project_suffix](variables.tf#L119) | Suffix used only for project ids. | <code>string</code> | | <code>null</code> |
|
||||
| [region](variables.tf#L125) | Region used for regional resources. | <code>string</code> | | <code>"europe-west1"</code> |
|
||||
| [service_encryption_keys](variables.tf#L131) | Cloud KMS to use to encrypt different services. Key location should match service region. | <code title="object({ bq = string composer = string dataflow = string storage = string pubsub = string })">object({…})</code> | | <code>null</code> |
|
||||
| [project_services](variables.tf#L112) | List of core services enabled on all projects. | <code>list(string)</code> | | <code title="[ "cloudresourcemanager.googleapis.com", "iam.googleapis.com", "serviceusage.googleapis.com", "stackdriver.googleapis.com" ]">[…]</code> |
|
||||
| [project_suffix](variables.tf#L123) | Suffix used only for project ids. | <code>string</code> | | <code>null</code> |
|
||||
| [region](variables.tf#L129) | Region used for regional resources. | <code>string</code> | | <code>"europe-west1"</code> |
|
||||
| [service_encryption_keys](variables.tf#L135) | Cloud KMS to use to encrypt different services. Key location should match service region. | <code title="object({ bq = string composer = string dataflow = string storage = string pubsub = string })">object({…})</code> | | <code>null</code> |
|
||||
|
||||
## Outputs
|
||||
|
||||
| name | description | sensitive |
|
||||
|---|---|:---:|
|
||||
| [bigquery-datasets](outputs.tf#L17) | BigQuery datasets. | |
|
||||
| [demo_commands](outputs.tf#L93) | Demo commands. | |
|
||||
| [gcs-buckets](outputs.tf#L28) | GCS buckets. | |
|
||||
| [kms_keys](outputs.tf#L42) | Cloud MKS keys. | |
|
||||
| [projects](outputs.tf#L47) | GCP Projects informations. | |
|
||||
| [vpc_network](outputs.tf#L75) | VPC network. | |
|
||||
| [vpc_subnet](outputs.tf#L84) | VPC subnetworks. | |
|
||||
| [demo_commands](outputs.tf#L28) | Demo commands. | |
|
||||
| [gcs-buckets](outputs.tf#L41) | GCS buckets. | |
|
||||
| [kms_keys](outputs.tf#L55) | Cloud MKS keys. | |
|
||||
| [projects](outputs.tf#L60) | GCP Projects informations. | |
|
||||
| [vpc_network](outputs.tf#L88) | VPC network. | |
|
||||
| [vpc_subnet](outputs.tf#L97) | VPC subnetworks. | |
|
||||
|
||||
<!-- END TFDOC -->
|
||||
## TODOs
|
||||
|
|
|
@ -25,6 +25,19 @@ output "bigquery-datasets" {
|
|||
}
|
||||
}
|
||||
|
||||
output "demo_commands" {
|
||||
description = "Demo commands."
|
||||
value = {
|
||||
01 = "gsutil -i ${module.drop-sa-cs-0.email} cp demo/data/*.csv gs://${module.drop-cs-0.name}"
|
||||
02 = "gsutil -i ${module.orch-sa-cmp-0.email} cp demo/data/*.j* gs://${module.orch-cs-0.name}"
|
||||
03 = "gsutil -i ${module.orch-sa-cmp-0.email} cp demo/*.py ${google_composer_environment.orch-cmp-0.config[0].dag_gcs_prefix}/"
|
||||
04 = "Open ${google_composer_environment.orch-cmp-0.config.0.airflow_uri} and run uploaded DAG."
|
||||
05 = <<EOT
|
||||
bq query --project_id=${module.dwh-conf-project.project_id} --use_legacy_sql=false 'SELECT * EXCEPT (name, surname) FROM `${module.dwh-conf-project.project_id}.${module.dwh-conf-bq-0.dataset_id}.customer_purchase` LIMIT 1000'"
|
||||
EOT
|
||||
}
|
||||
}
|
||||
|
||||
output "gcs-buckets" {
|
||||
description = "GCS buckets."
|
||||
value = {
|
||||
|
@ -89,16 +102,3 @@ output "vpc_subnet" {
|
|||
transformation = local.transf_subnet
|
||||
}
|
||||
}
|
||||
|
||||
output "demo_commands" {
|
||||
description = "Demo commands."
|
||||
value = {
|
||||
01 = "gsutil -i ${module.drop-sa-cs-0.email} cp demo/data/*.csv gs://${module.drop-cs-0.name}"
|
||||
02 = "gsutil -i ${module.orch-sa-cmp-0.email} cp demo/data/*.j* gs://${module.orch-cs-0.name}"
|
||||
03 = "gsutil -i ${module.orch-sa-cmp-0.email} cp demo/*.py ${google_composer_environment.orch-cmp-0.config[0].dag_gcs_prefix}/"
|
||||
04 = "Open ${google_composer_environment.orch-cmp-0.config.0.airflow_uri} and run uploaded DAG."
|
||||
05 = <<EOT
|
||||
bq query --project_id=${module.dwh-conf-project.project_id} --use_legacy_sql=false 'SELECT * EXCEPT (name, surname) FROM `${module.dwh-conf-project.project_id}.${module.dwh-conf-bq-0.dataset_id}.customer_purchase` LIMIT 1000'"
|
||||
EOT
|
||||
}
|
||||
}
|
||||
|
|
|
@ -101,8 +101,12 @@ variable "organization_domain" {
|
|||
}
|
||||
|
||||
variable "prefix" {
|
||||
description = "Unique prefix used for resource names."
|
||||
description = "Prefix used for resource names."
|
||||
type = string
|
||||
validation {
|
||||
condition = var.prefix != ""
|
||||
error_message = "Prefix cannot be empty."
|
||||
}
|
||||
}
|
||||
|
||||
variable "project_services" {
|
||||
|
|
|
@ -47,12 +47,12 @@ You can now connect to the Vertex AI notbook to perform your data analysy.
|
|||
|
||||
| name | description | type | required | default |
|
||||
|---|---|:---:|:---:|:---:|
|
||||
| [prefix](variables.tf#L36) | Unique prefix used for resource names. Not used for project if 'project_create' is null. | <code>string</code> | ✓ | |
|
||||
| [project_id](variables.tf#L22) | Project id, references existing project if `project_create` is null. | <code>string</code> | ✓ | |
|
||||
| [prefix](variables.tf#L22) | Prefix used for resource names. | <code>string</code> | ✓ | |
|
||||
| [project_id](variables.tf#L40) | Project id, references existing project if `project_create` is null. | <code>string</code> | ✓ | |
|
||||
| [location](variables.tf#L16) | The location where resources will be deployed. | <code>string</code> | | <code>"EU"</code> |
|
||||
| [project_create](variables.tf#L27) | Provide values if project creation is needed, uses existing project if null. Parent format: folders/folder_id or organizations/org_id | <code title="object({ billing_account_id = string parent = string })">object({…})</code> | | <code>null</code> |
|
||||
| [region](variables.tf#L41) | The region where resources will be deployed. | <code>string</code> | | <code>"europe-west1"</code> |
|
||||
| [vpc_config](variables.tf#L57) | Parameters to create a VPC. | <code title="object({ ip_cidr_range = string })">object({…})</code> | | <code title="{ ip_cidr_range = "10.0.0.0/20" }">{…}</code> |
|
||||
| [project_create](variables.tf#L31) | Provide values if project creation is needed, uses existing project if null. Parent format: folders/folder_id or organizations/org_id | <code title="object({ billing_account_id = string parent = string })">object({…})</code> | | <code>null</code> |
|
||||
| [region](variables.tf#L45) | The region where resources will be deployed. | <code>string</code> | | <code>"europe-west1"</code> |
|
||||
| [vpc_config](variables.tf#L61) | Parameters to create a VPC. | <code title="object({ ip_cidr_range = string })">object({…})</code> | | <code title="{ ip_cidr_range = "10.0.0.0/20" }">{…}</code> |
|
||||
|
||||
## Outputs
|
||||
|
||||
|
|
|
@ -19,9 +19,13 @@ variable "location" {
|
|||
default = "EU"
|
||||
}
|
||||
|
||||
variable "project_id" {
|
||||
description = "Project id, references existing project if `project_create` is null."
|
||||
variable "prefix" {
|
||||
description = "Prefix used for resource names."
|
||||
type = string
|
||||
validation {
|
||||
condition = var.prefix != ""
|
||||
error_message = "Prefix cannot be empty."
|
||||
}
|
||||
}
|
||||
|
||||
variable "project_create" {
|
||||
|
@ -33,8 +37,8 @@ variable "project_create" {
|
|||
default = null
|
||||
}
|
||||
|
||||
variable "prefix" {
|
||||
description = "Unique prefix used for resource names. Not used for project if 'project_create' is null."
|
||||
variable "project_id" {
|
||||
description = "Project id, references existing project if `project_create` is null."
|
||||
type = string
|
||||
}
|
||||
|
||||
|
|
|
@ -193,14 +193,14 @@ The above command will delete the associated resources so there will be no billa
|
|||
|
||||
| name | description | type | required | default |
|
||||
|---|---|:---:|:---:|:---:|
|
||||
| [prefix](variables.tf#L36) | Unique prefix used for resource names. Not used for project if 'project_create' is null. | <code>string</code> | ✓ | |
|
||||
| [project_id](variables.tf#L50) | Project id, references existing project if `project_create` is null. | <code>string</code> | ✓ | |
|
||||
| [prefix](variables.tf#L36) | Prefix used for resource names. | <code>string</code> | ✓ | |
|
||||
| [project_id](variables.tf#L54) | Project id, references existing project if `project_create` is null. | <code>string</code> | ✓ | |
|
||||
| [cmek_encryption](variables.tf#L15) | Flag to enable CMEK on GCP resources created. | <code>bool</code> | | <code>false</code> |
|
||||
| [data_eng_principals](variables.tf#L21) | Groups with Service Account Token creator role on service accounts in IAM format, eg 'group:group@domain.com'. | <code>list(string)</code> | | <code>[]</code> |
|
||||
| [network_config](variables.tf#L27) | Shared VPC network configurations to use. If null networks will be created in projects with preconfigured values. | <code title="object({ host_project = string subnet_self_link = string })">object({…})</code> | | <code>null</code> |
|
||||
| [project_create](variables.tf#L41) | Provide values if project creation is needed, uses existing project if null. Parent is in 'folders/nnn' or 'organizations/nnn' format. | <code title="object({ billing_account_id = string parent = string })">object({…})</code> | | <code>null</code> |
|
||||
| [region](variables.tf#L55) | The region where resources will be deployed. | <code>string</code> | | <code>"europe-west1"</code> |
|
||||
| [vpc_subnet_range](variables.tf#L61) | Ip range used for the VPC subnet created for the example. | <code>string</code> | | <code>"10.0.0.0/20"</code> |
|
||||
| [project_create](variables.tf#L45) | Provide values if project creation is needed, uses existing project if null. Parent is in 'folders/nnn' or 'organizations/nnn' format. | <code title="object({ billing_account_id = string parent = string })">object({…})</code> | | <code>null</code> |
|
||||
| [region](variables.tf#L59) | The region where resources will be deployed. | <code>string</code> | | <code>"europe-west1"</code> |
|
||||
| [vpc_subnet_range](variables.tf#L65) | Ip range used for the VPC subnet created for the example. | <code>string</code> | | <code>"10.0.0.0/20"</code> |
|
||||
|
||||
## Outputs
|
||||
|
||||
|
@ -208,10 +208,10 @@ The above command will delete the associated resources so there will be no billa
|
|||
|---|---|:---:|
|
||||
| [bq_tables](outputs.tf#L15) | Bigquery Tables. | |
|
||||
| [buckets](outputs.tf#L20) | GCS bucket Cloud KMS crypto keys. | |
|
||||
| [command_01_gcs](outputs.tf#L43) | gcloud command to copy data into the created bucket impersonating the service account. | |
|
||||
| [command_02_dataflow](outputs.tf#L48) | Command to run Dataflow template impersonating the service account. | |
|
||||
| [command_03_bq](outputs.tf#L69) | BigQuery command to query imported data. | |
|
||||
| [project_id](outputs.tf#L28) | Project id. | |
|
||||
| [service_accounts](outputs.tf#L33) | Service account. | |
|
||||
| [command_01_gcs](outputs.tf#L28) | gcloud command to copy data into the created bucket impersonating the service account. | |
|
||||
| [command_02_dataflow](outputs.tf#L33) | Command to run Dataflow template impersonating the service account. | |
|
||||
| [command_03_bq](outputs.tf#L54) | BigQuery command to query imported data. | |
|
||||
| [project_id](outputs.tf#L64) | Project id. | |
|
||||
| [service_accounts](outputs.tf#L69) | Service account. | |
|
||||
|
||||
<!-- END TFDOC -->
|
||||
|
|
|
@ -25,21 +25,6 @@ output "buckets" {
|
|||
}
|
||||
}
|
||||
|
||||
output "project_id" {
|
||||
description = "Project id."
|
||||
value = module.project.project_id
|
||||
}
|
||||
|
||||
output "service_accounts" {
|
||||
description = "Service account."
|
||||
value = {
|
||||
bq = module.service-account-bq.email
|
||||
df = module.service-account-df.email
|
||||
orch = module.service-account-orch.email
|
||||
landing = module.service-account-landing.email
|
||||
}
|
||||
}
|
||||
|
||||
output "command_01_gcs" {
|
||||
description = "gcloud command to copy data into the created bucket impersonating the service account."
|
||||
value = "gsutil -i ${module.service-account-landing.email} cp data-demo/* ${module.gcs-data.url}"
|
||||
|
@ -75,3 +60,18 @@ output "command_03_bq" {
|
|||
sql_limit = 1000
|
||||
})
|
||||
}
|
||||
|
||||
output "project_id" {
|
||||
description = "Project id."
|
||||
value = module.project.project_id
|
||||
}
|
||||
|
||||
output "service_accounts" {
|
||||
description = "Service account."
|
||||
value = {
|
||||
bq = module.service-account-bq.email
|
||||
df = module.service-account-df.email
|
||||
orch = module.service-account-orch.email
|
||||
landing = module.service-account-landing.email
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,8 +34,12 @@ variable "network_config" {
|
|||
}
|
||||
|
||||
variable "prefix" {
|
||||
description = "Unique prefix used for resource names. Not used for project if 'project_create' is null."
|
||||
description = "Prefix used for resource names."
|
||||
type = string
|
||||
validation {
|
||||
condition = var.prefix != ""
|
||||
error_message = "Prefix cannot be empty."
|
||||
}
|
||||
}
|
||||
|
||||
variable "project_create" {
|
||||
|
|
|
@ -35,32 +35,32 @@ and to `C:\GcpSetupLog.txt` file.
|
|||
|
||||
| name | description | type | required | default |
|
||||
|---|---|:---:|:---:|:---:|
|
||||
| [ad_domain_fqdn](variables.tf#L111) | Active Directory domain (FQDN) | <code>string</code> | ✓ | |
|
||||
| [ad_domain_netbios](variables.tf#L120) | Active Directory domain (NetBIOS) | <code>string</code> | ✓ | |
|
||||
| [network](variables.tf#L38) | Network to use in the project | <code>string</code> | ✓ | |
|
||||
| [project_id](variables.tf#L27) | Google Cloud project ID | <code>string</code> | ✓ | |
|
||||
| [sql_admin_password](variables.tf#L102) | Password for the SQL admin user to be created | <code>string</code> | ✓ | |
|
||||
| [subnetwork](variables.tf#L43) | Subnetwork to use in the project | <code>string</code> | ✓ | |
|
||||
| [always_on_groups](variables.tf#L135) | List of Always On Groups | <code>list(string)</code> | | <code>["bookshelf"]</code> |
|
||||
| [boot_disk_size](variables.tf#L90) | Boot disk size in GB | <code>number</code> | | <code>50</code> |
|
||||
| [cluster_name](variables.tf#L48) | Cluster name (prepended with prefix) | <code>string</code> | | <code>"cluster"</code> |
|
||||
| [data_disk_size](variables.tf#L96) | Database disk size in GB | <code>number</code> | | <code>200</code> |
|
||||
| [health_check_config](variables.tf#L147) | Health check configuration | <code title="object({ check_interval_sec = number, healthy_threshold = number, unhealthy_threshold = number, timeout_sec = number, })">…</code> | | <code title="{ check_interval_sec = 2 healthy_threshold = 1 unhealthy_threshold = 2 timeout_sec = 1 }">{…}</code> |
|
||||
| [health_check_port](variables.tf#L141) | Health check port | <code>number</code> | | <code>59997</code> |
|
||||
| [health_check_ranges](variables.tf#L60) | Health check ranges | <code>list(string)</code> | | <code>["35.191.0.0/16", "209.85.152.0/22", "209.85.204.0/22"]</code> |
|
||||
| [managed_ad_dn](variables.tf#L129) | Managed Active Directory domain (eg. OU=Cloud,DC=example,DC=com) | <code>string</code> | | <code>""</code> |
|
||||
| [node_image](variables.tf#L78) | SQL Server node machine image | <code>string</code> | | <code>"projects/windows-sql-cloud/global/images/family/sql-ent-2019-win-2019"</code> |
|
||||
| [node_instance_type](variables.tf#L66) | SQL Server database node instance type | <code>string</code> | | <code>"n2-standard-8"</code> |
|
||||
| [node_name](variables.tf#L162) | Node base name | <code>string</code> | | <code>"node"</code> |
|
||||
| [prefix](variables.tf#L15) | Prefix used for resources (for multiple clusters in a project) | <code>string</code> | | <code>"aog"</code> |
|
||||
| [project_create](variables.tf#L174) | Provide values if project creation is needed, uses existing project if null. Parent is in 'folders/nnn' or 'organizations/nnn' format. | <code title="object({ billing_account_id = string parent = string })">object({…})</code> | | <code>null</code> |
|
||||
| [region](variables.tf#L21) | Region for resources | <code>string</code> | | <code>"europe-west4"</code> |
|
||||
| [shared_vpc_project_id](variables.tf#L32) | Shared VPC project ID for firewall rules | <code>string</code> | | <code>null</code> |
|
||||
| [sql_client_cidrs](variables.tf#L54) | CIDR ranges that are allowed to connect to SQL Server | <code>list(string)</code> | | <code>["0.0.0.0/0"]</code> |
|
||||
| [vpc_ip_cidr_range](variables.tf#L183) | Ip range used in the subnet deployef in the Service Project. | <code>string</code> | | <code>"10.0.0.0/20"</code> |
|
||||
| [witness_image](variables.tf#L84) | SQL Server witness machine image | <code>string</code> | | <code>"projects/windows-cloud/global/images/family/windows-2019"</code> |
|
||||
| [witness_instance_type](variables.tf#L72) | SQL Server witness node instance type | <code>string</code> | | <code>"n2-standard-2"</code> |
|
||||
| [witness_name](variables.tf#L168) | Witness base name | <code>string</code> | | <code>"witness"</code> |
|
||||
| [ad_domain_fqdn](variables.tf#L15) | Active Directory domain (FQDN) | <code>string</code> | ✓ | |
|
||||
| [ad_domain_netbios](variables.tf#L24) | Active Directory domain (NetBIOS) | <code>string</code> | ✓ | |
|
||||
| [network](variables.tf#L90) | Network to use in the project | <code>string</code> | ✓ | |
|
||||
| [prefix](variables.tf#L113) | Prefix used for resource names. | <code>string</code> | ✓ | |
|
||||
| [project_id](variables.tf#L131) | Google Cloud project ID | <code>string</code> | ✓ | |
|
||||
| [sql_admin_password](variables.tf#L148) | Password for the SQL admin user to be created | <code>string</code> | ✓ | |
|
||||
| [subnetwork](variables.tf#L163) | Subnetwork to use in the project | <code>string</code> | ✓ | |
|
||||
| [always_on_groups](variables.tf#L33) | List of Always On Groups | <code>list(string)</code> | | <code>["bookshelf"]</code> |
|
||||
| [boot_disk_size](variables.tf#L39) | Boot disk size in GB | <code>number</code> | | <code>50</code> |
|
||||
| [cluster_name](variables.tf#L45) | Cluster name (prepended with prefix) | <code>string</code> | | <code>"cluster"</code> |
|
||||
| [data_disk_size](variables.tf#L51) | Database disk size in GB | <code>number</code> | | <code>200</code> |
|
||||
| [health_check_config](variables.tf#L57) | Health check configuration | <code title="object({ check_interval_sec = number, healthy_threshold = number, unhealthy_threshold = number, timeout_sec = number, })">…</code> | | <code title="{ check_interval_sec = 2 healthy_threshold = 1 unhealthy_threshold = 2 timeout_sec = 1 }">{…}</code> |
|
||||
| [health_check_port](variables.tf#L72) | Health check port | <code>number</code> | | <code>59997</code> |
|
||||
| [health_check_ranges](variables.tf#L78) | Health check ranges | <code>list(string)</code> | | <code>["35.191.0.0/16", "209.85.152.0/22", "209.85.204.0/22"]</code> |
|
||||
| [managed_ad_dn](variables.tf#L84) | Managed Active Directory domain (eg. OU=Cloud,DC=example,DC=com) | <code>string</code> | | <code>""</code> |
|
||||
| [node_image](variables.tf#L95) | SQL Server node machine image | <code>string</code> | | <code>"projects/windows-sql-cloud/global/images/family/sql-ent-2019-win-2019"</code> |
|
||||
| [node_instance_type](variables.tf#L101) | SQL Server database node instance type | <code>string</code> | | <code>"n2-standard-8"</code> |
|
||||
| [node_name](variables.tf#L107) | Node base name | <code>string</code> | | <code>"node"</code> |
|
||||
| [project_create](variables.tf#L122) | Provide values if project creation is needed, uses existing project if null. Parent is in 'folders/nnn' or 'organizations/nnn' format. | <code title="object({ billing_account_id = string parent = string })">object({…})</code> | | <code>null</code> |
|
||||
| [region](variables.tf#L136) | Region for resources | <code>string</code> | | <code>"europe-west4"</code> |
|
||||
| [shared_vpc_project_id](variables.tf#L142) | Shared VPC project ID for firewall rules | <code>string</code> | | <code>null</code> |
|
||||
| [sql_client_cidrs](variables.tf#L157) | CIDR ranges that are allowed to connect to SQL Server | <code>list(string)</code> | | <code>["0.0.0.0/0"]</code> |
|
||||
| [vpc_ip_cidr_range](variables.tf#L168) | Ip range used in the subnet deployef in the Service Project. | <code>string</code> | | <code>"10.0.0.0/20"</code> |
|
||||
| [witness_image](variables.tf#L174) | SQL Server witness machine image | <code>string</code> | | <code>"projects/windows-cloud/global/images/family/windows-2019"</code> |
|
||||
| [witness_instance_type](variables.tf#L180) | SQL Server witness node instance type | <code>string</code> | | <code>"n2-standard-2"</code> |
|
||||
| [witness_name](variables.tf#L186) | Witness base name | <code>string</code> | | <code>"witness"</code> |
|
||||
|
||||
## Outputs
|
||||
|
||||
|
|
|
@ -30,8 +30,8 @@ locals {
|
|||
managed_ad_dn_path = var.managed_ad_dn != "" ? "-Path \"${var.managed_ad_dn}\"" : ""
|
||||
health_check_port = var.health_check_port
|
||||
sql_admin_password_secret = local._secret_parts[length(local._secret_parts) - 1]
|
||||
cluster_ip = module.ip-addresses.internal_addresses["${local.prefix}cluster"].address
|
||||
loadbalancer_ips = jsonencode({ for aog in var.always_on_groups : aog => module.ip-addresses.internal_addresses["${local.prefix}lb-${aog}"].address })
|
||||
cluster_ip = module.ip-addresses.internal_addresses["${var.prefix}-cluster"].address
|
||||
loadbalancer_ips = jsonencode({ for aog in var.always_on_groups : aog => module.ip-addresses.internal_addresses["${var.prefix}-lb-${aog}"].address })
|
||||
sql_cluster_name = local.cluster_netbios_name
|
||||
sql_cluster_full = local.cluster_full_name
|
||||
node_netbios_1 = local.node_netbios_names[0]
|
||||
|
@ -43,7 +43,7 @@ locals {
|
|||
_template_vars = merge(local._template_vars0, {
|
||||
functions = local._functions
|
||||
})
|
||||
_user_name = "${local.prefix}sqlserver"
|
||||
_user_name = "${var.prefix}-sqlserver"
|
||||
scripts = {
|
||||
for script in local._scripts :
|
||||
script => templatefile("${path.module}/scripts/${script}.ps1", local._template_vars)
|
||||
|
|
|
@ -14,14 +14,14 @@
|
|||
|
||||
locals {
|
||||
ad_user_password_secret = "${local.cluster_full_name}-password"
|
||||
cluster_full_name = "${local.prefix}${var.cluster_name}"
|
||||
cluster_full_name = "${var.prefix}-${var.cluster_name}"
|
||||
cluster_netbios_name = (
|
||||
length(local.cluster_full_name) > 15
|
||||
? substr(local.cluster_full_name, 0, 15)
|
||||
: local.cluster_full_name
|
||||
)
|
||||
network = module.vpc.self_link
|
||||
node_base = "${local.prefix}${var.node_name}"
|
||||
node_base = "${var.prefix}-${var.node_name}"
|
||||
node_prefix = (
|
||||
length(local.node_base) > 12
|
||||
? substr(local.node_base, 0, 12)
|
||||
|
@ -39,7 +39,6 @@ locals {
|
|||
(local.witness_netbios_name) = local.zones[length(local.zones) - 1]
|
||||
}
|
||||
)
|
||||
prefix = var.prefix != "" ? "${var.prefix}-" : ""
|
||||
subnetwork = (
|
||||
var.project_create != null
|
||||
? module.vpc.subnet_self_links["${var.region}/${var.subnetwork}"]
|
||||
|
@ -50,7 +49,7 @@ locals {
|
|||
? var.shared_vpc_project_id
|
||||
: module.project.project_id
|
||||
)
|
||||
witness_name = "${local.prefix}${var.witness_name}"
|
||||
witness_name = "${var.prefix}-${var.witness_name}"
|
||||
witness_netbios_name = (
|
||||
length(local.witness_name) > 15
|
||||
? substr(local.witness_name, 0, 15)
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
module "compute-service-account" {
|
||||
source = "../../../modules/iam-service-account"
|
||||
project_id = var.project_id
|
||||
name = format("%swsfc", local.prefix)
|
||||
name = "${var.prefix}-wsfc"
|
||||
|
||||
iam_project_roles = {
|
||||
(var.project_id) = [
|
||||
|
@ -35,7 +35,7 @@ module "compute-service-account" {
|
|||
module "witness-service-account" {
|
||||
source = "../../../modules/iam-service-account"
|
||||
project_id = var.project_id
|
||||
name = format("%swsfc-witness", local.prefix)
|
||||
name = "${var.prefix}-wsfc-witness"
|
||||
|
||||
iam_project_roles = {
|
||||
(var.project_id) = [
|
||||
|
|
|
@ -12,102 +12,6 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
variable "prefix" {
|
||||
description = "Prefix used for resources (for multiple clusters in a project)"
|
||||
type = string
|
||||
default = "aog"
|
||||
}
|
||||
|
||||
variable "region" {
|
||||
description = "Region for resources"
|
||||
type = string
|
||||
default = "europe-west4"
|
||||
}
|
||||
|
||||
variable "project_id" {
|
||||
description = "Google Cloud project ID"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "shared_vpc_project_id" {
|
||||
description = "Shared VPC project ID for firewall rules"
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "network" {
|
||||
description = "Network to use in the project"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "subnetwork" {
|
||||
description = "Subnetwork to use in the project"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "cluster_name" {
|
||||
description = "Cluster name (prepended with prefix)"
|
||||
type = string
|
||||
default = "cluster"
|
||||
}
|
||||
|
||||
variable "sql_client_cidrs" {
|
||||
description = "CIDR ranges that are allowed to connect to SQL Server"
|
||||
type = list(string)
|
||||
default = ["0.0.0.0/0"]
|
||||
}
|
||||
|
||||
variable "health_check_ranges" {
|
||||
description = "Health check ranges"
|
||||
type = list(string)
|
||||
default = ["35.191.0.0/16", "209.85.152.0/22", "209.85.204.0/22"]
|
||||
}
|
||||
|
||||
variable "node_instance_type" {
|
||||
description = "SQL Server database node instance type"
|
||||
type = string
|
||||
default = "n2-standard-8"
|
||||
}
|
||||
|
||||
variable "witness_instance_type" {
|
||||
description = "SQL Server witness node instance type"
|
||||
type = string
|
||||
default = "n2-standard-2"
|
||||
}
|
||||
|
||||
variable "node_image" {
|
||||
description = "SQL Server node machine image"
|
||||
type = string
|
||||
default = "projects/windows-sql-cloud/global/images/family/sql-ent-2019-win-2019"
|
||||
}
|
||||
|
||||
variable "witness_image" {
|
||||
description = "SQL Server witness machine image"
|
||||
type = string
|
||||
default = "projects/windows-cloud/global/images/family/windows-2019"
|
||||
}
|
||||
|
||||
variable "boot_disk_size" {
|
||||
description = "Boot disk size in GB"
|
||||
type = number
|
||||
default = 50
|
||||
}
|
||||
|
||||
variable "data_disk_size" {
|
||||
description = "Database disk size in GB"
|
||||
type = number
|
||||
default = 200
|
||||
}
|
||||
|
||||
variable "sql_admin_password" {
|
||||
description = "Password for the SQL admin user to be created"
|
||||
type = string
|
||||
validation {
|
||||
condition = length(var.sql_admin_password) > 0
|
||||
error_message = "SQL administrator password needs to be specified."
|
||||
}
|
||||
}
|
||||
|
||||
variable "ad_domain_fqdn" {
|
||||
description = "Active Directory domain (FQDN)"
|
||||
type = string
|
||||
|
@ -126,22 +30,28 @@ variable "ad_domain_netbios" {
|
|||
}
|
||||
}
|
||||
|
||||
variable "managed_ad_dn" {
|
||||
description = "Managed Active Directory domain (eg. OU=Cloud,DC=example,DC=com)"
|
||||
type = string
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "always_on_groups" {
|
||||
description = "List of Always On Groups"
|
||||
type = list(string)
|
||||
default = ["bookshelf"]
|
||||
}
|
||||
|
||||
variable "health_check_port" {
|
||||
description = "Health check port"
|
||||
variable "boot_disk_size" {
|
||||
description = "Boot disk size in GB"
|
||||
type = number
|
||||
default = 59997
|
||||
default = 50
|
||||
}
|
||||
|
||||
variable "cluster_name" {
|
||||
description = "Cluster name (prepended with prefix)"
|
||||
type = string
|
||||
default = "cluster"
|
||||
}
|
||||
|
||||
variable "data_disk_size" {
|
||||
description = "Database disk size in GB"
|
||||
type = number
|
||||
default = 200
|
||||
}
|
||||
|
||||
variable "health_check_config" {
|
||||
|
@ -159,16 +69,54 @@ variable "health_check_config" {
|
|||
}
|
||||
}
|
||||
|
||||
variable "health_check_port" {
|
||||
description = "Health check port"
|
||||
type = number
|
||||
default = 59997
|
||||
}
|
||||
|
||||
variable "health_check_ranges" {
|
||||
description = "Health check ranges"
|
||||
type = list(string)
|
||||
default = ["35.191.0.0/16", "209.85.152.0/22", "209.85.204.0/22"]
|
||||
}
|
||||
|
||||
variable "managed_ad_dn" {
|
||||
description = "Managed Active Directory domain (eg. OU=Cloud,DC=example,DC=com)"
|
||||
type = string
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "network" {
|
||||
description = "Network to use in the project"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "node_image" {
|
||||
description = "SQL Server node machine image"
|
||||
type = string
|
||||
default = "projects/windows-sql-cloud/global/images/family/sql-ent-2019-win-2019"
|
||||
}
|
||||
|
||||
variable "node_instance_type" {
|
||||
description = "SQL Server database node instance type"
|
||||
type = string
|
||||
default = "n2-standard-8"
|
||||
}
|
||||
|
||||
variable "node_name" {
|
||||
description = "Node base name"
|
||||
type = string
|
||||
default = "node"
|
||||
}
|
||||
|
||||
variable "witness_name" {
|
||||
description = "Witness base name"
|
||||
variable "prefix" {
|
||||
description = "Prefix used for resource names."
|
||||
type = string
|
||||
default = "witness"
|
||||
validation {
|
||||
condition = var.prefix != ""
|
||||
error_message = "Prefix cannot be empty."
|
||||
}
|
||||
}
|
||||
|
||||
variable "project_create" {
|
||||
|
@ -180,8 +128,63 @@ variable "project_create" {
|
|||
default = null
|
||||
}
|
||||
|
||||
variable "project_id" {
|
||||
description = "Google Cloud project ID"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "region" {
|
||||
description = "Region for resources"
|
||||
type = string
|
||||
default = "europe-west4"
|
||||
}
|
||||
|
||||
variable "shared_vpc_project_id" {
|
||||
description = "Shared VPC project ID for firewall rules"
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "sql_admin_password" {
|
||||
description = "Password for the SQL admin user to be created"
|
||||
type = string
|
||||
validation {
|
||||
condition = length(var.sql_admin_password) > 0
|
||||
error_message = "SQL administrator password needs to be specified."
|
||||
}
|
||||
}
|
||||
|
||||
variable "sql_client_cidrs" {
|
||||
description = "CIDR ranges that are allowed to connect to SQL Server"
|
||||
type = list(string)
|
||||
default = ["0.0.0.0/0"]
|
||||
}
|
||||
|
||||
variable "subnetwork" {
|
||||
description = "Subnetwork to use in the project"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "vpc_ip_cidr_range" {
|
||||
description = "Ip range used in the subnet deployef in the Service Project."
|
||||
type = string
|
||||
default = "10.0.0.0/20"
|
||||
}
|
||||
|
||||
variable "witness_image" {
|
||||
description = "SQL Server witness machine image"
|
||||
type = string
|
||||
default = "projects/windows-cloud/global/images/family/windows-2019"
|
||||
}
|
||||
|
||||
variable "witness_instance_type" {
|
||||
description = "SQL Server witness node instance type"
|
||||
type = string
|
||||
default = "n2-standard-2"
|
||||
}
|
||||
|
||||
variable "witness_name" {
|
||||
description = "Witness base name"
|
||||
type = string
|
||||
default = "witness"
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ locals {
|
|||
local.listeners,
|
||||
local.node_ips,
|
||||
{
|
||||
"${local.prefix}cluster" = {
|
||||
"${var.prefix}-cluster" = {
|
||||
region = var.region
|
||||
subnetwork = local.subnetwork
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ locals {
|
|||
k => v.address
|
||||
}
|
||||
listeners = {
|
||||
for aog in var.always_on_groups : "${local.prefix}lb-${aog}" => {
|
||||
for aog in var.always_on_groups : "${var.prefix}-lb-${aog}" => {
|
||||
region = var.region
|
||||
subnetwork = local.subnetwork
|
||||
}
|
||||
|
@ -83,7 +83,7 @@ module "firewall" {
|
|||
disabled = true
|
||||
}
|
||||
ingress_rules = {
|
||||
"${local.prefix}allow-all-between-wsfc-nodes" = {
|
||||
"${var.prefix}-allow-all-between-wsfc-nodes" = {
|
||||
description = "Allow all between WSFC nodes"
|
||||
sources = [module.compute-service-account.email]
|
||||
targets = [module.compute-service-account.email]
|
||||
|
@ -94,7 +94,7 @@ module "firewall" {
|
|||
{ protocol = "icmp" }
|
||||
]
|
||||
}
|
||||
"${local.prefix}allow-all-between-wsfc-witness" = {
|
||||
"${var.prefix}-allow-all-between-wsfc-witness" = {
|
||||
description = "Allow all between WSFC witness nodes"
|
||||
sources = [module.compute-service-account.email]
|
||||
targets = [module.witness-service-account.email]
|
||||
|
@ -105,7 +105,7 @@ module "firewall" {
|
|||
{ protocol = "icmp" }
|
||||
]
|
||||
}
|
||||
"${local.prefix}allow-sql-to-wsfc-nodes" = {
|
||||
"${var.prefix}-allow-sql-to-wsfc-nodes" = {
|
||||
description = "Allow SQL connections to WSFC nodes"
|
||||
targets = [module.compute-service-account.email]
|
||||
ranges = var.sql_client_cidrs
|
||||
|
@ -114,7 +114,7 @@ module "firewall" {
|
|||
{ protocol = "tcp", ports = [1433] },
|
||||
]
|
||||
}
|
||||
"${local.prefix}allow-health-check-to-wsfc-nodes" = {
|
||||
"${var.prefix}-allow-health-check-to-wsfc-nodes" = {
|
||||
description = "Allow health checks to WSFC nodes"
|
||||
targets = [module.compute-service-account.email]
|
||||
ranges = var.health_check_ranges
|
||||
|
@ -139,7 +139,7 @@ module "listener-ilb" {
|
|||
region = var.region
|
||||
name = "${var.prefix}-${each.value}-ilb"
|
||||
service_label = "${var.prefix}-${each.value}-ilb"
|
||||
address = local.internal_address_ips["${local.prefix}lb-${each.value}"]
|
||||
address = local.internal_address_ips["${var.prefix}-lb-${each.value}"]
|
||||
vpc_config = {
|
||||
network = local.network
|
||||
subnetwork = local.subnetwork
|
||||
|
|
|
@ -67,20 +67,17 @@ labels: # not required, defaults to {}, Example: {"a":"thisislabela","b":"thisis
|
|||
use_legacy_sql: bool # not required, defaults to false
|
||||
deletion_protection: bool # not required, defaults to false
|
||||
```
|
||||
|
||||
<!-- BEGIN TFDOC -->
|
||||
|
||||
## Variables
|
||||
|
||||
| name | description | type | required | default |
|
||||
|---|---|:---:|:---:|:---:|
|
||||
| [project_id](variables.tf#L27) | Project ID | <code>string</code> | ✓ | |
|
||||
| [project_id](variables.tf#L17) | Project ID | <code>string</code> | ✓ | |
|
||||
| [tables_dir](variables.tf#L22) | Relative path for the folder storing table data. | <code>string</code> | ✓ | |
|
||||
| [views_dir](variables.tf#L17) | Relative path for the folder storing view data. | <code>string</code> | ✓ | |
|
||||
| [views_dir](variables.tf#L27) | Relative path for the folder storing view data. | <code>string</code> | ✓ | |
|
||||
|
||||
<!-- END TFDOC -->
|
||||
|
||||
|
||||
## TODO
|
||||
|
||||
- [ ] add external table support
|
||||
|
|
|
@ -14,8 +14,8 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
variable "views_dir" {
|
||||
description = "Relative path for the folder storing view data."
|
||||
variable "project_id" {
|
||||
description = "Project ID"
|
||||
type = string
|
||||
}
|
||||
|
||||
|
@ -24,8 +24,7 @@ variable "tables_dir" {
|
|||
type = string
|
||||
}
|
||||
|
||||
variable "project_id" {
|
||||
description = "Project ID"
|
||||
variable "views_dir" {
|
||||
description = "Relative path for the folder storing view data."
|
||||
type = string
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# Google Cloud VPC Firewall Factory
|
||||
|
||||
This module allows creation and management of different types of firewall rules by defining them in well formatted `yaml` files.
|
||||
This module allows creation and management of different types of firewall rules by defining them in well formatted `yaml` files.
|
||||
|
||||
Yaml abstraction for FW rules can simplify users onboarding and also makes rules definition simpler and clearer comparing to HCL.
|
||||
|
||||
|
@ -79,10 +79,10 @@ rule-name: # descriptive name, naming convention is adjusted by the module
|
|||
destination_ranges: # list of destination ranges, should be specified only for `EGRESS` rule
|
||||
- 0.0.0.0/0
|
||||
source_tags: ['some-tag'] # list of source tags, should be specified only for `INGRESS` rule
|
||||
source_service_accounts: # list of source service accounts, should be specified only for `INGRESS` rule, can not be specified together with `source_tags` or `target_tags`
|
||||
source_service_accounts: # list of source service accounts, should be specified only for `INGRESS` rule, cannot be specified together with `source_tags` or `target_tags`
|
||||
- myapp@myproject-id.iam.gserviceaccount.com
|
||||
target_tags: ['some-tag'] # list of target tags
|
||||
target_service_accounts: # list of target service accounts, , can not be specified together with `source_tags` or `target_tags`
|
||||
target_service_accounts: # list of target service accounts, , cannot be specified together with `source_tags` or `target_tags`
|
||||
- myapp@myproject-id.iam.gserviceaccount.com
|
||||
```
|
||||
|
||||
|
|
|
@ -69,6 +69,7 @@ module "projects" {
|
|||
kms_service_agents = try(each.value.kms, {})
|
||||
labels = try(each.value.labels, {})
|
||||
org_policies = try(each.value.org_policies, {})
|
||||
prefix = each.value.prefix
|
||||
service_accounts = try(each.value.service_accounts, {})
|
||||
services = try(each.value.services, [])
|
||||
service_identities_iam = try(each.value.service_identities_iam, {})
|
||||
|
@ -109,9 +110,9 @@ vpc_host_project: project-example-host-project
|
|||
|
||||
# [opt] Billing account id - overrides default if set
|
||||
billing_account_id: 012345-67890A-BCDEF0
|
||||
|
||||
|
||||
# [opt] Billing alerts config - overrides default if set
|
||||
billing_alert:
|
||||
billing_alert:
|
||||
amount: 10
|
||||
thresholds:
|
||||
current:
|
||||
|
@ -119,42 +120,42 @@ billing_alert:
|
|||
- 0.8
|
||||
forecasted: []
|
||||
|
||||
# [opt] DNS zones to be created as children of the environment_dns_zone defined in defaults
|
||||
dns_zones:
|
||||
# [opt] DNS zones to be created as children of the environment_dns_zone defined in defaults
|
||||
dns_zones:
|
||||
- lorem
|
||||
- ipsum
|
||||
|
||||
# [opt] Contacts for billing alerts and important notifications
|
||||
essential_contacts:
|
||||
# [opt] Contacts for billing alerts and important notifications
|
||||
essential_contacts:
|
||||
- team-a-contacts@example.com
|
||||
|
||||
# Folder the project will be created as children of
|
||||
folder_id: folders/012345678901
|
||||
|
||||
# [opt] Authoritative IAM bindings in group => [roles] format
|
||||
group_iam:
|
||||
group_iam:
|
||||
test-team-foobar@fast-lab-0.gcp-pso-italy.net:
|
||||
- roles/compute.admin
|
||||
|
||||
# [opt] Authoritative IAM bindings in role => [principals] format
|
||||
# Generally used to grant roles to service accounts external to the project
|
||||
iam:
|
||||
iam:
|
||||
roles/compute.admin:
|
||||
- serviceAccount:service-account
|
||||
|
||||
# [opt] Service robots and keys they will be assigned as cryptoKeyEncrypterDecrypter
|
||||
# [opt] Service robots and keys they will be assigned as cryptoKeyEncrypterDecrypter
|
||||
# in service => [keys] format
|
||||
kms_service_agents:
|
||||
kms_service_agents:
|
||||
compute: [key1, key2]
|
||||
storage: [key1, key2]
|
||||
|
||||
# [opt] Labels for the project - merged with the ones defined in defaults
|
||||
labels:
|
||||
labels:
|
||||
environment: prod
|
||||
|
||||
# [opt] Org policy overrides defined at project level
|
||||
org_policies:
|
||||
constraints/compute.disableGuestAttributesAccess:
|
||||
constraints/compute.disableGuestAttributesAccess:
|
||||
enforce: true
|
||||
constraints/compute.trustedImageProjects:
|
||||
allow:
|
||||
|
@ -166,7 +167,7 @@ org_policies:
|
|||
|
||||
# [opt] Service account to create for the project and their roles on the project
|
||||
# in name => [roles] format
|
||||
service_accounts:
|
||||
service_accounts:
|
||||
another-service-account:
|
||||
- roles/compute.admin
|
||||
my-service-account:
|
||||
|
@ -179,37 +180,37 @@ service_accounts_iam:
|
|||
- roles/iam.serviceAccountTokenCreator:
|
||||
- group: app-team-1@example.com
|
||||
|
||||
# [opt] APIs to enable on the project.
|
||||
services:
|
||||
# [opt] APIs to enable on the project.
|
||||
services:
|
||||
- storage.googleapis.com
|
||||
- stackdriver.googleapis.com
|
||||
- compute.googleapis.com
|
||||
|
||||
# [opt] Roles to assign to the robots service accounts in robot => [roles] format
|
||||
services_iam:
|
||||
services_iam:
|
||||
compute:
|
||||
- roles/storage.objectViewer
|
||||
|
||||
# [opt] VPC setup.
|
||||
# If set enables the `compute.googleapis.com` service and configures
|
||||
# [opt] VPC setup.
|
||||
# If set enables the `compute.googleapis.com` service and configures
|
||||
# service project attachment
|
||||
vpc:
|
||||
vpc:
|
||||
|
||||
# [opt] If set, enables the container API
|
||||
gke_setup:
|
||||
gke_setup:
|
||||
|
||||
# Grants "roles/container.hostServiceAgentUser" to the container robot if set
|
||||
# Grants "roles/container.hostServiceAgentUser" to the container robot if set
|
||||
enable_host_service_agent: false
|
||||
|
||||
# Grants "roles/compute.securityAdmin" to the container robot if set
|
||||
# Grants "roles/compute.securityAdmin" to the container robot if set
|
||||
enable_security_admin: true
|
||||
|
||||
# Host project the project will be service project of
|
||||
# Host project the project will be service project of
|
||||
host_project: fast-prod-net-spoke-0
|
||||
|
||||
# [opt] Subnets in the host project where principals will be granted networkUser
|
||||
# in region/subnet-name => [principals]
|
||||
subnets_iam:
|
||||
# in region/subnet-name => [principals]
|
||||
subnets_iam:
|
||||
europe-west1/prod-default-ew1:
|
||||
- user:foobar@example.com
|
||||
- serviceAccount:service-account1@my-project.iam.gserviceaccount.com
|
||||
|
@ -221,7 +222,8 @@ vpc:
|
|||
| name | description | type | required | default |
|
||||
|---|---|:---:|:---:|:---:|
|
||||
| [billing_account_id](variables.tf#L17) | Billing account id. | <code>string</code> | ✓ | |
|
||||
| [project_id](variables.tf#L157) | Project id. | <code>string</code> | ✓ | |
|
||||
| [prefix](variables.tf#L151) | Prefix used for resource names. | <code>string</code> | ✓ | |
|
||||
| [project_id](variables.tf#L160) | Project id. | <code>string</code> | ✓ | |
|
||||
| [billing_alert](variables.tf#L22) | Billing alert configuration. | <code title="object({ amount = number thresholds = object({ current = list(number) forecasted = list(number) }) credit_treatment = string })">object({…})</code> | | <code>null</code> |
|
||||
| [defaults](variables.tf#L35) | Project factory default values. | <code title="object({ billing_account_id = string billing_alert = object({ amount = number thresholds = object({ current = list(number) forecasted = list(number) }) credit_treatment = string }) environment_dns_zone = string essential_contacts = list(string) labels = map(string) notification_channels = list(string) shared_vpc_self_link = string vpc_host_project = string })">object({…})</code> | | <code>null</code> |
|
||||
| [dns_zones](variables.tf#L57) | DNS private zones to create as child of var.defaults.environment_dns_zone. | <code>list(string)</code> | | <code>[]</code> |
|
||||
|
@ -234,15 +236,14 @@ vpc:
|
|||
| [kms_service_agents](variables.tf#L99) | KMS IAM configuration in as service => [key]. | <code>map(list(string))</code> | | <code>{}</code> |
|
||||
| [labels](variables.tf#L105) | Labels to be assigned at project level. | <code>map(string)</code> | | <code>{}</code> |
|
||||
| [org_policies](variables.tf#L111) | Org-policy overrides at project level. | <code title="map(object({ inherit_from_parent = optional(bool) # for list policies only. reset = optional(bool) allow = optional(object({ all = optional(bool) values = optional(list(string)) })) deny = optional(object({ all = optional(bool) values = optional(list(string)) })) enforce = optional(bool, true) # for boolean policies only. rules = optional(list(object({ allow = optional(object({ all = optional(bool) values = optional(list(string)) })) deny = optional(object({ all = optional(bool) values = optional(list(string)) })) enforce = optional(bool, true) # for boolean policies only. condition = object({ description = optional(string) expression = optional(string) location = optional(string) title = optional(string) }) })), []) }))">map(object({…}))</code> | | <code>{}</code> |
|
||||
| [prefix](variables.tf#L151) | Prefix used for the project id. | <code>string</code> | | <code>null</code> |
|
||||
| [service_accounts](variables.tf#L162) | Service accounts to be created, and roles assigned them on the project. | <code>map(list(string))</code> | | <code>{}</code> |
|
||||
| [service_accounts_additive](variables.tf#L168) | Service accounts to be created, and roles assigned them on the project additively. | <code>map(list(string))</code> | | <code>{}</code> |
|
||||
| [service_accounts_iam](variables.tf#L174) | IAM bindings on service account resources. Format is KEY => {ROLE => [MEMBERS]} | <code>map(map(list(string)))</code> | | <code>{}</code> |
|
||||
| [service_accounts_iam_additive](variables.tf#L181) | IAM additive bindings on service account resources. Format is KEY => {ROLE => [MEMBERS]} | <code>map(map(list(string)))</code> | | <code>{}</code> |
|
||||
| [service_identities_iam](variables.tf#L195) | Custom IAM settings for service identities in service => [role] format. | <code>map(list(string))</code> | | <code>{}</code> |
|
||||
| [service_identities_iam_additive](variables.tf#L202) | Custom additive IAM settings for service identities in service => [role] format. | <code>map(list(string))</code> | | <code>{}</code> |
|
||||
| [services](variables.tf#L188) | Services to be enabled for the project. | <code>list(string)</code> | | <code>[]</code> |
|
||||
| [vpc](variables.tf#L209) | VPC configuration for the project. | <code title="object({ host_project = string gke_setup = object({ enable_security_admin = bool enable_host_service_agent = bool }) subnets_iam = map(list(string)) })">object({…})</code> | | <code>null</code> |
|
||||
| [service_accounts](variables.tf#L165) | Service accounts to be created, and roles assigned them on the project. | <code>map(list(string))</code> | | <code>{}</code> |
|
||||
| [service_accounts_additive](variables.tf#L171) | Service accounts to be created, and roles assigned them on the project additively. | <code>map(list(string))</code> | | <code>{}</code> |
|
||||
| [service_accounts_iam](variables.tf#L177) | IAM bindings on service account resources. Format is KEY => {ROLE => [MEMBERS]} | <code>map(map(list(string)))</code> | | <code>{}</code> |
|
||||
| [service_accounts_iam_additive](variables.tf#L184) | IAM additive bindings on service account resources. Format is KEY => {ROLE => [MEMBERS]} | <code>map(map(list(string)))</code> | | <code>{}</code> |
|
||||
| [service_identities_iam](variables.tf#L191) | Custom IAM settings for service identities in service => [role] format. | <code>map(list(string))</code> | | <code>{}</code> |
|
||||
| [service_identities_iam_additive](variables.tf#L198) | Custom additive IAM settings for service identities in service => [role] format. | <code>map(list(string))</code> | | <code>{}</code> |
|
||||
| [services](variables.tf#L205) | Services to be enabled for the project. | <code>list(string)</code> | | <code>[]</code> |
|
||||
| [vpc](variables.tf#L212) | VPC configuration for the project. | <code title="object({ host_project = string gke_setup = object({ enable_security_admin = bool enable_host_service_agent = bool }) subnets_iam = map(list(string)) })">object({…})</code> | | <code>null</code> |
|
||||
|
||||
## Outputs
|
||||
|
||||
|
|
|
@ -29,11 +29,7 @@ locals {
|
|||
}
|
||||
_group_iam_bindings = distinct(flatten(values(var.group_iam)))
|
||||
_group_iam_additive_bindings = distinct(flatten(values(var.group_iam_additive)))
|
||||
_project_id = (
|
||||
var.prefix == null || var.prefix == ""
|
||||
? var.project_id
|
||||
: "${var.prefix}-${var.project_id}"
|
||||
)
|
||||
|
||||
_service_accounts_iam = {
|
||||
for r in local._service_accounts_iam_bindings : r => [
|
||||
for k, v in var.service_accounts :
|
||||
|
|
|
@ -25,4 +25,5 @@ labels:
|
|||
# [opt] Additional notification channels for billing
|
||||
notification_channels: []
|
||||
shared_vpc_self_link: projects/foo/networks/bar
|
||||
prefix: test
|
||||
vpc_host_project:
|
||||
|
|
|
@ -58,6 +58,9 @@ org_policies:
|
|||
deny:
|
||||
all: true
|
||||
|
||||
# [opt] Prefix - overrides default if set
|
||||
prefix: test1
|
||||
|
||||
# [opt] Service account to create for the project and their roles on the project
|
||||
# in name => [roles] format
|
||||
service_accounts:
|
||||
|
|
|
@ -149,9 +149,12 @@ variable "org_policies" {
|
|||
}
|
||||
|
||||
variable "prefix" {
|
||||
description = "Prefix used for the project id."
|
||||
description = "Prefix used for resource names."
|
||||
type = string
|
||||
default = null
|
||||
validation {
|
||||
condition = var.prefix != ""
|
||||
error_message = "Prefix cannot be empty."
|
||||
}
|
||||
}
|
||||
|
||||
variable "project_id" {
|
||||
|
@ -185,13 +188,6 @@ variable "service_accounts_iam_additive" {
|
|||
nullable = false
|
||||
}
|
||||
|
||||
variable "services" {
|
||||
description = "Services to be enabled for the project."
|
||||
type = list(string)
|
||||
default = []
|
||||
nullable = false
|
||||
}
|
||||
|
||||
variable "service_identities_iam" {
|
||||
description = "Custom IAM settings for service identities in service => [role] format."
|
||||
type = map(list(string))
|
||||
|
@ -206,6 +202,13 @@ variable "service_identities_iam_additive" {
|
|||
nullable = false
|
||||
}
|
||||
|
||||
variable "services" {
|
||||
description = "Services to be enabled for the project."
|
||||
type = list(string)
|
||||
default = []
|
||||
nullable = false
|
||||
}
|
||||
|
||||
variable "vpc" {
|
||||
description = "VPC configuration for the project."
|
||||
type = object({
|
||||
|
|
|
@ -107,21 +107,21 @@ Once done testing, you can clean up resources by running `terraform destroy`.
|
|||
|
||||
| name | description | type | required | default |
|
||||
|---|---|:---:|:---:|:---:|
|
||||
| [project_id](variables.tf#L26) | Project ID. | <code>string</code> | ✓ | |
|
||||
| [master_cidr_block](variables.tf#L49) | Master CIDR block. | <code>string</code> | | <code>"10.0.0.0/28"</code> |
|
||||
| [pods_cidr_block](variables.tf#L37) | Pods CIDR block. | <code>string</code> | | <code>"172.16.0.0/20"</code> |
|
||||
| [prefix](variables.tf#L31) | Prefix for resources created. | <code>string</code> | | <code>null</code> |
|
||||
| [project_create](variables.tf#L17) | Parameters for the creation of the new project. | <code title="object({ billing_account_id = string parent = string })">object({…})</code> | | <code>null</code> |
|
||||
| [region](variables.tf#L61) | Region. | <code>string</code> | | <code>"europe-west1"</code> |
|
||||
| [services_cidr_block](variables.tf#L43) | Services CIDR block. | <code>string</code> | | <code>"192.168.0.0/24"</code> |
|
||||
| [subnet_cidr_block](variables.tf#L55) | Subnet CIDR block. | <code>string</code> | | <code>"10.0.1.0/24"</code> |
|
||||
| [zone](variables.tf#L67) | Zone. | <code>string</code> | | <code>"europe-west1-c"</code> |
|
||||
| [prefix](variables.tf#L29) | Prefix used for resource names. | <code>string</code> | ✓ | |
|
||||
| [project_id](variables.tf#L47) | Project ID. | <code>string</code> | ✓ | |
|
||||
| [master_cidr_block](variables.tf#L17) | Master CIDR block. | <code>string</code> | | <code>"10.0.0.0/28"</code> |
|
||||
| [pods_cidr_block](variables.tf#L23) | Pods CIDR block. | <code>string</code> | | <code>"172.16.0.0/20"</code> |
|
||||
| [project_create](variables.tf#L38) | Parameters for the creation of the new project. | <code title="object({ billing_account_id = string parent = string })">object({…})</code> | | <code>null</code> |
|
||||
| [region](variables.tf#L52) | Region. | <code>string</code> | | <code>"europe-west1"</code> |
|
||||
| [services_cidr_block](variables.tf#L58) | Services CIDR block. | <code>string</code> | | <code>"192.168.0.0/24"</code> |
|
||||
| [subnet_cidr_block](variables.tf#L64) | Subnet CIDR block. | <code>string</code> | | <code>"10.0.1.0/24"</code> |
|
||||
| [zone](variables.tf#L70) | Zone. | <code>string</code> | | <code>"europe-west1-c"</code> |
|
||||
|
||||
## Outputs
|
||||
|
||||
| name | description | sensitive |
|
||||
|---|---|:---:|
|
||||
| [app_repo_url](outputs.tf#L22) | App source repository url. | |
|
||||
| [image_repo_url](outputs.tf#L17) | Image source repository url. | |
|
||||
| [app_repo_url](outputs.tf#L17) | App source repository url. | |
|
||||
| [image_repo_url](outputs.tf#L22) | Image source repository url. | |
|
||||
|
||||
<!-- END TFDOC -->
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
*/
|
||||
|
||||
locals {
|
||||
prefix = (var.prefix == null || var.prefix == "") ? "" : "${var.prefix}-"
|
||||
k8s_ns = "apis"
|
||||
k8s_sa = "storage-api-sa"
|
||||
image = (
|
||||
|
@ -60,7 +59,7 @@ module "project" {
|
|||
module "vpc" {
|
||||
source = "../../../modules/net-vpc"
|
||||
project_id = module.project.project_id
|
||||
name = "${local.prefix}vpc"
|
||||
name = "${var.prefix}-vpc"
|
||||
subnets = [
|
||||
{
|
||||
ip_cidr_range = var.subnet_cidr_block
|
||||
|
@ -78,14 +77,14 @@ module "nat" {
|
|||
source = "../../../modules/net-cloudnat"
|
||||
project_id = module.project.project_id
|
||||
region = var.region
|
||||
name = "${local.prefix}nat"
|
||||
name = "${var.prefix}-nat"
|
||||
router_network = module.vpc.name
|
||||
}
|
||||
|
||||
module "cluster" {
|
||||
source = "../../../modules/gke-cluster"
|
||||
project_id = module.project.project_id
|
||||
name = "${local.prefix}cluster"
|
||||
name = "${var.prefix}-cluster"
|
||||
location = var.zone
|
||||
vpc_config = {
|
||||
master_ipv4_cidr_block = var.master_cidr_block
|
||||
|
@ -173,7 +172,7 @@ module "docker_artifact_registry" {
|
|||
project_id = module.project.project_id
|
||||
location = var.region
|
||||
format = "DOCKER"
|
||||
id = "${local.prefix}registry"
|
||||
id = "${var.prefix}-registry"
|
||||
iam = {
|
||||
"roles/artifactregistry.writer" = [module.image_cb_sa.iam_email]
|
||||
"roles/artifactregistry.reader" = [module.cluster_nodepool.service_account_iam_email]
|
||||
|
@ -189,7 +188,7 @@ module "image_cb_sa" {
|
|||
module "image_repo" {
|
||||
source = "../../../modules/source-repository"
|
||||
project_id = module.project.project_id
|
||||
name = "${local.prefix}image"
|
||||
name = "${var.prefix}-image"
|
||||
triggers = {
|
||||
image-trigger = {
|
||||
filename = "cloudbuild.yaml"
|
||||
|
@ -221,7 +220,7 @@ module "app_cb_sa" {
|
|||
module "app_repo" {
|
||||
source = "../../../modules/source-repository"
|
||||
project_id = module.project.project_id
|
||||
name = "${local.prefix}app"
|
||||
name = "${var.prefix}-app"
|
||||
triggers = {
|
||||
app-trigger = {
|
||||
filename = "cloudbuild.yaml"
|
||||
|
|
|
@ -14,12 +14,12 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
output "image_repo_url" {
|
||||
description = "Image source repository url."
|
||||
value = "ssh://<USER>@source.developers.google.com:2022/p/${module.project.project_id}/r/${module.image_repo.name}"
|
||||
}
|
||||
|
||||
output "app_repo_url" {
|
||||
description = "App source repository url."
|
||||
value = "ssh://<USER>@source.developers.google.com:2022/p/${module.project.project_id}/r/${module.app_repo.name}"
|
||||
}
|
||||
|
||||
output "image_repo_url" {
|
||||
description = "Image source repository url."
|
||||
value = "ssh://<USER>@source.developers.google.com:2022/p/${module.project.project_id}/r/${module.image_repo.name}"
|
||||
}
|
||||
|
|
|
@ -14,6 +14,27 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
variable "master_cidr_block" {
|
||||
description = "Master CIDR block."
|
||||
type = string
|
||||
default = "10.0.0.0/28"
|
||||
}
|
||||
|
||||
variable "pods_cidr_block" {
|
||||
description = "Pods CIDR block."
|
||||
type = string
|
||||
default = "172.16.0.0/20"
|
||||
}
|
||||
|
||||
variable "prefix" {
|
||||
description = "Prefix used for resource names."
|
||||
type = string
|
||||
validation {
|
||||
condition = var.prefix != ""
|
||||
error_message = "Prefix cannot be empty."
|
||||
}
|
||||
}
|
||||
|
||||
variable "project_create" {
|
||||
description = "Parameters for the creation of the new project."
|
||||
type = object({
|
||||
|
@ -28,16 +49,10 @@ variable "project_id" {
|
|||
type = string
|
||||
}
|
||||
|
||||
variable "prefix" {
|
||||
description = "Prefix for resources created."
|
||||
variable "region" {
|
||||
description = "Region."
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "pods_cidr_block" {
|
||||
description = "Pods CIDR block."
|
||||
type = string
|
||||
default = "172.16.0.0/20"
|
||||
default = "europe-west1"
|
||||
}
|
||||
|
||||
variable "services_cidr_block" {
|
||||
|
@ -46,24 +61,12 @@ variable "services_cidr_block" {
|
|||
default = "192.168.0.0/24"
|
||||
}
|
||||
|
||||
variable "master_cidr_block" {
|
||||
description = "Master CIDR block."
|
||||
type = string
|
||||
default = "10.0.0.0/28"
|
||||
}
|
||||
|
||||
variable "subnet_cidr_block" {
|
||||
description = "Subnet CIDR block."
|
||||
type = string
|
||||
default = "10.0.1.0/24"
|
||||
}
|
||||
|
||||
variable "region" {
|
||||
description = "Region."
|
||||
type = string
|
||||
default = "europe-west1"
|
||||
}
|
||||
|
||||
variable "zone" {
|
||||
description = "Zone."
|
||||
type = string
|
||||
|
|
|
@ -64,14 +64,14 @@ Once done testing, you can clean up resources by running `terraform destroy`.
|
|||
| name | description | type | required | default |
|
||||
|---|---|:---:|:---:|:---:|
|
||||
| [billing_account_id](variables.tf#L17) | Billing account id. | <code>string</code> | ✓ | |
|
||||
| [fleet_project_id](variables.tf#L32) | Management Project ID. | <code>string</code> | ✓ | |
|
||||
| [host_project_id](variables.tf#L27) | Project ID. | <code>string</code> | ✓ | |
|
||||
| [mgmt_project_id](variables.tf#L37) | Management Project ID. | <code>string</code> | ✓ | |
|
||||
| [parent](variables.tf#L22) | Parent. | <code>string</code> | ✓ | |
|
||||
| [clusters_config](variables.tf#L54) | Clusters configuration. | <code title="map(object({ subnet_cidr_block = string master_cidr_block = string services_cidr_block = string pods_cidr_block = string }))">map(object({…}))</code> | | <code title="{ cluster-a = { subnet_cidr_block = "10.0.1.0/24" master_cidr_block = "10.16.0.0/28" services_cidr_block = "192.168.1.0/24" pods_cidr_block = "172.16.0.0/20" } cluster-b = { subnet_cidr_block = "10.0.2.0/24" master_cidr_block = "10.16.0.16/28" services_cidr_block = "192.168.2.0/24" pods_cidr_block = "172.16.16.0/20" } }">{…}</code> |
|
||||
| [istio_version](variables.tf#L98) | ASM version | <code>string</code> | | <code>"1.14.1-asm.3"</code> |
|
||||
| [mgmt_server_config](variables.tf#L78) | Mgmt server configuration | <code title="object({ disk_size = number disk_type = string image = string instance_type = string region = string zone = string })">object({…})</code> | | <code title="{ disk_size = 50 disk_type = "pd-ssd" image = "projects/ubuntu-os-cloud/global/images/family/ubuntu-2204-lts" instance_type = "n1-standard-2" region = "europe-west1" zone = "europe-west1-c" }">{…}</code> |
|
||||
| [mgmt_subnet_cidr_block](variables.tf#L42) | Management subnet CIDR block. | <code>string</code> | | <code>"10.0.0.0/28"</code> |
|
||||
| [region](variables.tf#L48) | Region. | <code>string</code> | | <code>"europe-west1"</code> |
|
||||
| [fleet_project_id](variables.tf#L46) | Management Project ID. | <code>string</code> | ✓ | |
|
||||
| [host_project_id](variables.tf#L51) | Project ID. | <code>string</code> | ✓ | |
|
||||
| [mgmt_project_id](variables.tf#L63) | Management Project ID. | <code>string</code> | ✓ | |
|
||||
| [parent](variables.tf#L94) | Parent. | <code>string</code> | ✓ | |
|
||||
| [clusters_config](variables.tf#L22) | Clusters configuration. | <code title="map(object({ subnet_cidr_block = string master_cidr_block = string services_cidr_block = string pods_cidr_block = string }))">map(object({…}))</code> | | <code title="{ cluster-a = { subnet_cidr_block = "10.0.1.0/24" master_cidr_block = "10.16.0.0/28" services_cidr_block = "192.168.1.0/24" pods_cidr_block = "172.16.0.0/20" } cluster-b = { subnet_cidr_block = "10.0.2.0/24" master_cidr_block = "10.16.0.16/28" services_cidr_block = "192.168.2.0/24" pods_cidr_block = "172.16.16.0/20" } }">{…}</code> |
|
||||
| [istio_version](variables.tf#L57) | ASM version | <code>string</code> | | <code>"1.14.1-asm.3"</code> |
|
||||
| [mgmt_server_config](variables.tf#L68) | Mgmt server configuration | <code title="object({ disk_size = number disk_type = string image = string instance_type = string region = string zone = string })">object({…})</code> | | <code title="{ disk_size = 50 disk_type = "pd-ssd" image = "projects/ubuntu-os-cloud/global/images/family/ubuntu-2204-lts" instance_type = "n1-standard-2" region = "europe-west1" zone = "europe-west1-c" }">{…}</code> |
|
||||
| [mgmt_subnet_cidr_block](variables.tf#L88) | Management subnet CIDR block. | <code>string</code> | | <code>"10.0.0.0/28"</code> |
|
||||
| [region](variables.tf#L99) | Region. | <code>string</code> | | <code>"europe-west1"</code> |
|
||||
|
||||
<!-- END TFDOC -->
|
||||
|
|
|
@ -19,38 +19,6 @@ variable "billing_account_id" {
|
|||
type = string
|
||||
}
|
||||
|
||||
variable "parent" {
|
||||
description = "Parent."
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "host_project_id" {
|
||||
description = "Project ID."
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "fleet_project_id" {
|
||||
description = "Management Project ID."
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "mgmt_project_id" {
|
||||
description = "Management Project ID."
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "mgmt_subnet_cidr_block" {
|
||||
description = "Management subnet CIDR block."
|
||||
type = string
|
||||
default = "10.0.0.0/28"
|
||||
}
|
||||
|
||||
variable "region" {
|
||||
description = "Region."
|
||||
type = string
|
||||
default = "europe-west1"
|
||||
}
|
||||
|
||||
variable "clusters_config" {
|
||||
description = "Clusters configuration."
|
||||
type = map(object({
|
||||
|
@ -75,6 +43,28 @@ variable "clusters_config" {
|
|||
}
|
||||
}
|
||||
|
||||
variable "fleet_project_id" {
|
||||
description = "Management Project ID."
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "host_project_id" {
|
||||
description = "Project ID."
|
||||
type = string
|
||||
}
|
||||
|
||||
|
||||
variable "istio_version" {
|
||||
description = "ASM version"
|
||||
type = string
|
||||
default = "1.14.1-asm.3"
|
||||
}
|
||||
|
||||
variable "mgmt_project_id" {
|
||||
description = "Management Project ID."
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "mgmt_server_config" {
|
||||
description = "Mgmt server configuration"
|
||||
type = object({
|
||||
|
@ -95,8 +85,19 @@ variable "mgmt_server_config" {
|
|||
}
|
||||
}
|
||||
|
||||
variable "istio_version" {
|
||||
description = "ASM version"
|
||||
variable "mgmt_subnet_cidr_block" {
|
||||
description = "Management subnet CIDR block."
|
||||
type = string
|
||||
default = "1.14.1-asm.3"
|
||||
default = "10.0.0.0/28"
|
||||
}
|
||||
|
||||
variable "parent" {
|
||||
description = "Parent."
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "region" {
|
||||
description = "Region."
|
||||
type = string
|
||||
default = "europe-west1"
|
||||
}
|
||||
|
|
|
@ -247,9 +247,9 @@ module "gke" {
|
|||
|---|---|:---:|:---:|:---:|
|
||||
| [billing_account_id](variables.tf#L17) | Billing account id. | <code>string</code> | ✓ | |
|
||||
| [folder_id](variables.tf#L132) | Folder used for the GKE project in folders/nnnnnnnnnnn format. | <code>string</code> | ✓ | |
|
||||
| [prefix](variables.tf#L179) | Prefix used for resources that need unique names. | <code>string</code> | ✓ | |
|
||||
| [project_id](variables.tf#L184) | ID of the project that will contain all the clusters. | <code>string</code> | ✓ | |
|
||||
| [vpc_config](variables.tf#L196) | Shared VPC project and VPC details. | <code title="object({ host_project_id = string vpc_self_link = string })">object({…})</code> | ✓ | |
|
||||
| [prefix](variables.tf#L179) | Prefix used for resource names. | <code>string</code> | ✓ | |
|
||||
| [project_id](variables.tf#L188) | ID of the project that will contain all the clusters. | <code>string</code> | ✓ | |
|
||||
| [vpc_config](variables.tf#L200) | Shared VPC project and VPC details. | <code title="object({ host_project_id = string vpc_self_link = string })">object({…})</code> | ✓ | |
|
||||
| [clusters](variables.tf#L22) | Clusters configuration. Refer to the gke-cluster module for type details. | <code title="map(object({ cluster_autoscaling = optional(any) description = optional(string) enable_addons = optional(any, { horizontal_pod_autoscaling = true, http_load_balancing = true }) enable_features = optional(any, { workload_identity = true }) issue_client_certificate = optional(bool, false) labels = optional(map(string)) location = string logging_config = optional(list(string), ["SYSTEM_COMPONENTS"]) maintenance_config = optional(any, { daily_window_start_time = "03:00" recurring_window = null maintenance_exclusion = [] }) max_pods_per_node = optional(number, 110) min_master_version = optional(string) monitoring_config = optional(object({ enable_components = optional(list(string), ["SYSTEM_COMPONENTS"]) managed_prometheus = optional(bool) })) node_locations = optional(list(string)) private_cluster_config = optional(any) release_channel = optional(string) vpc_config = object({ subnetwork = string network = optional(string) secondary_range_blocks = optional(object({ pods = string services = string })) secondary_range_names = optional(object({ pods = string services = string }), { pods = "pods", services = "services" }) master_authorized_ranges = optional(map(string)) master_ipv4_cidr_block = optional(string) }) }))">map(object({…}))</code> | | <code>{}</code> |
|
||||
| [fleet_configmanagement_clusters](variables.tf#L70) | Config management features enabled on specific sets of member clusters, in config name => [cluster name] format. | <code>map(list(string))</code> | | <code>{}</code> |
|
||||
| [fleet_configmanagement_templates](variables.tf#L77) | Sets of config management configurations that can be applied to member clusters, in config name => {options} format. | <code title="map(object({ binauthz = bool config_sync = object({ git = object({ gcp_service_account_email = string https_proxy = string policy_dir = string secret_type = string sync_branch = string sync_repo = string sync_rev = string sync_wait_secs = number }) prevent_drift = string source_format = string }) hierarchy_controller = object({ enable_hierarchical_resource_quota = bool enable_pod_tree_labels = bool }) policy_controller = object({ audit_interval_seconds = number exemptable_namespaces = list(string) log_denies_enabled = bool referential_rules_enabled = bool template_library_installed = bool }) version = string }))">map(object({…}))</code> | | <code>{}</code> |
|
||||
|
@ -259,14 +259,14 @@ module "gke" {
|
|||
| [iam](variables.tf#L144) | Project-level authoritative IAM bindings for users and service accounts in {ROLE => [MEMBERS]} format. | <code>map(list(string))</code> | | <code>{}</code> |
|
||||
| [labels](variables.tf#L151) | Project-level labels. | <code>map(string)</code> | | <code>{}</code> |
|
||||
| [nodepools](variables.tf#L157) | Nodepools configuration. Refer to the gke-nodepool module for type details. | <code title="map(map(object({ gke_version = optional(string) labels = optional(map(string), {}) max_pods_per_node = optional(number) name = optional(string) node_config = optional(any, { disk_type = "pd-balanced" }) node_count = optional(map(number), { initial = 1 }) node_locations = optional(list(string)) nodepool_config = optional(any) pod_range = optional(any) reservation_affinity = optional(any) service_account = optional(any) sole_tenant_nodegroup = optional(string) tags = optional(list(string)) taints = optional(list(any)) })))">map(map(object({…})))</code> | | <code>{}</code> |
|
||||
| [project_services](variables.tf#L189) | Additional project services to enable. | <code>list(string)</code> | | <code>[]</code> |
|
||||
| [project_services](variables.tf#L193) | Additional project services to enable. | <code>list(string)</code> | | <code>[]</code> |
|
||||
|
||||
## Outputs
|
||||
|
||||
| name | description | sensitive |
|
||||
|---|---|:---:|
|
||||
| [cluster_ids](outputs.tf#L22) | Cluster ids. | |
|
||||
| [clusters](outputs.tf#L17) | Cluster resources. | |
|
||||
| [cluster_ids](outputs.tf#L17) | Cluster ids. | |
|
||||
| [clusters](outputs.tf#L24) | Cluster resources. | |
|
||||
| [project_id](outputs.tf#L29) | GKE project id. | |
|
||||
|
||||
<!-- END TFDOC -->
|
||||
|
|
|
@ -14,11 +14,6 @@
|
|||
|
||||
# tfdoc:file:description Output variables.
|
||||
|
||||
output "clusters" {
|
||||
description = "Cluster resources."
|
||||
value = module.gke-cluster
|
||||
}
|
||||
|
||||
output "cluster_ids" {
|
||||
description = "Cluster ids."
|
||||
value = {
|
||||
|
@ -26,6 +21,11 @@ output "cluster_ids" {
|
|||
}
|
||||
}
|
||||
|
||||
output "clusters" {
|
||||
description = "Cluster resources."
|
||||
value = module.gke-cluster
|
||||
}
|
||||
|
||||
output "project_id" {
|
||||
description = "GKE project id."
|
||||
value = module.gke-project-0.project_id
|
||||
|
|
|
@ -177,8 +177,12 @@ variable "nodepools" {
|
|||
}
|
||||
|
||||
variable "prefix" {
|
||||
description = "Prefix used for resources that need unique names."
|
||||
description = "Prefix used for resource names."
|
||||
type = string
|
||||
validation {
|
||||
condition = var.prefix != ""
|
||||
error_message = "Prefix cannot be empty."
|
||||
}
|
||||
}
|
||||
|
||||
variable "project_id" {
|
||||
|
|
|
@ -26,11 +26,11 @@ in the [`validator/`](validator/) subdirectory, which can be integrated as part
|
|||
| name | description | type | required | default |
|
||||
|---|---|:---:|:---:|:---:|
|
||||
| [billing_account_id](variables.tf#L15) | Billing account id used as default for new projects. | <code>string</code> | ✓ | |
|
||||
| [prefix](variables.tf#L29) | Prefix used for resources that need unique names. | <code>string</code> | ✓ | |
|
||||
| [root_node](variables.tf#L50) | Hierarchy node where projects will be created, 'organizations/org_id' or 'folders/folder_id'. | <code>string</code> | ✓ | |
|
||||
| [prefix](variables.tf#L29) | Prefix used for resource names. | <code>string</code> | ✓ | |
|
||||
| [root_node](variables.tf#L54) | Hierarchy node where projects will be created, 'organizations/org_id' or 'folders/folder_id'. | <code>string</code> | ✓ | |
|
||||
| [ip_ranges](variables.tf#L20) | Subnet IP CIDR ranges. | <code>map(string)</code> | | <code title="{ prod = "10.0.16.0/24" dev = "10.0.32.0/24" }">{…}</code> |
|
||||
| [project_services](variables.tf#L34) | Service APIs enabled by default in new projects. | <code>list(string)</code> | | <code title="[ "container.googleapis.com", "dns.googleapis.com", "stackdriver.googleapis.com", ]">[…]</code> |
|
||||
| [region](variables.tf#L44) | Region used. | <code>string</code> | | <code>"europe-west1"</code> |
|
||||
| [project_services](variables.tf#L38) | Service APIs enabled by default in new projects. | <code>list(string)</code> | | <code title="[ "container.googleapis.com", "dns.googleapis.com", "stackdriver.googleapis.com", ]">[…]</code> |
|
||||
| [region](variables.tf#L48) | Region used. | <code>string</code> | | <code>"europe-west1"</code> |
|
||||
|
||||
## Outputs
|
||||
|
||||
|
|
|
@ -27,8 +27,12 @@ variable "ip_ranges" {
|
|||
}
|
||||
|
||||
variable "prefix" {
|
||||
description = "Prefix used for resources that need unique names."
|
||||
description = "Prefix used for resource names."
|
||||
type = string
|
||||
validation {
|
||||
condition = var.prefix != ""
|
||||
error_message = "Prefix cannot be empty."
|
||||
}
|
||||
}
|
||||
|
||||
variable "project_services" {
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
# Network filtering with Squid with isolated VPCs using Private Service Connect
|
||||
|
||||
This blueprint shows how to deploy a filtering HTTP proxy to restrict Internet access. Here we show one way to do this using isolated VPCs and Private Service Connect:
|
||||
|
||||
- The `app` subnet hosts the consumer VMs that will have their Internet access tightly controlled by a non-caching filtering forward proxy.
|
||||
- The `proxy` subnet hosts a Cloud NAT instance and a [Squid](http://www.squid-cache.org/) server.
|
||||
- The `psc` subnet is reserved for the Private Service Connect.
|
||||
|
||||
The reason for using Privat Service Connect in this setup is to have a common proxy setup between all environments without having to share a VPC between projects. This allows us to enforce the `compute.vmExternalIpAccess` [organization policy](https://cloud.google.com/resource-manager/docs/organization-policy/org-policy-constraints), which prevents the service projects from having external IPs, thus forcing all outbound Internet connections through the proxy.
|
||||
|
||||
To allow Internet connectivity to the proxy subnet, a Cloud NAT instance is configured to allow usage from [that subnet only](https://cloud.google.com/nat/docs/using-nat#specify_subnet_ranges_for_nat). All other subnets are not allowed to use the Cloud NAT instance.
|
||||
|
||||
To simplify the usage of the proxy, a Cloud DNS private zone is created in each consumer VPC and the IP address of the proxy is exposed with the FQDN `proxy.internal`. In addition, system-wide `http_proxy` and `https_proxy` environment variables and an APT configuration are rolled out via a [startup script](startup.sh).
|
||||
<!-- BEGIN TFDOC -->
|
||||
|
||||
## Variables
|
||||
|
||||
| name | description | type | required | default |
|
||||
|---|---|:---:|:---:|:---:|
|
||||
| [prefix](variables.tf#L44) | Prefix used for resource names. | <code>string</code> | ✓ | |
|
||||
| [project_id](variables.tf#L70) | Project id used for all resources. | <code>string</code> | ✓ | |
|
||||
| [allowed_domains](variables.tf#L17) | List of domains allowed by the squid proxy. | <code>list(string)</code> | | <code title="[ ".google.com", ".github.com", ".fastlydns.net", ".debian.org" ]">[…]</code> |
|
||||
| [cidrs](variables.tf#L28) | CIDR ranges for subnets. | <code>map(string)</code> | | <code title="{ app = "10.0.0.0/24" proxy = "10.0.2.0/28" psc = "10.0.3.0/28" }">{…}</code> |
|
||||
| [nat_logging](variables.tf#L38) | Enables Cloud NAT logging if not null, value is one of 'ERRORS_ONLY', 'TRANSLATIONS_ONLY', 'ALL'. | <code>string</code> | | <code>"ERRORS_ONLY"</code> |
|
||||
| [project_create](variables.tf#L53) | Set to non null if project needs to be created. | <code title="object({ billing_account = string parent = string })">object({…})</code> | | <code>null</code> |
|
||||
| [region](variables.tf#L75) | Default region for resources. | <code>string</code> | | <code>"europe-west1"</code> |
|
||||
|
||||
<!-- END TFDOC -->
|
|
@ -0,0 +1,105 @@
|
|||
/**
|
||||
* Copyright 2022 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
###############################################################################
|
||||
# Consumer project and VPC #
|
||||
###############################################################################
|
||||
|
||||
module "vpc-consumer" {
|
||||
source = "../../../modules/net-vpc"
|
||||
project_id = module.project.project_id
|
||||
name = "${var.prefix}-app"
|
||||
subnets = [
|
||||
{
|
||||
name = "${var.prefix}-app"
|
||||
ip_cidr_range = var.cidrs.app
|
||||
region = var.region
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Test VM #
|
||||
###############################################################################
|
||||
|
||||
module "test-vm-consumer" {
|
||||
source = "../../../modules/compute-vm"
|
||||
project_id = module.project.project_id
|
||||
zone = "${var.region}-b"
|
||||
name = "${var.prefix}-test-vm"
|
||||
instance_type = "e2-micro"
|
||||
tags = ["ssh"]
|
||||
network_interfaces = [{
|
||||
network = module.vpc-consumer.self_link
|
||||
subnetwork = module.vpc-consumer.subnet_self_links["${var.region}/${var.prefix}-app"]
|
||||
nat = false
|
||||
addresses = null
|
||||
}]
|
||||
boot_disk = {
|
||||
image = "debian-cloud/debian-10"
|
||||
type = "pd-standard"
|
||||
size = 10
|
||||
}
|
||||
service_account_create = true
|
||||
metadata = {
|
||||
startup-script = templatefile("${path.module}/startup.sh", { proxy_url = "http://proxy.internal:3128" })
|
||||
}
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# PSC Consuner #
|
||||
###############################################################################
|
||||
|
||||
resource "google_compute_address" "psc_endpoint_address" {
|
||||
name = "${var.prefix}-psc-proxy-address"
|
||||
project = module.project.project_id
|
||||
address_type = "INTERNAL"
|
||||
subnetwork = module.vpc-consumer.subnet_self_links["${var.region}/${var.prefix}-app"]
|
||||
region = var.region
|
||||
}
|
||||
|
||||
resource "google_compute_forwarding_rule" "psc_ilb_consumer" {
|
||||
name = "${var.prefix}-psc-proxy-fw-rule"
|
||||
project = module.project.project_id
|
||||
region = var.region
|
||||
target = google_compute_service_attachment.service_attachment.id
|
||||
load_balancing_scheme = ""
|
||||
network = module.vpc-consumer.self_link
|
||||
ip_address = google_compute_address.psc_endpoint_address.id
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# DNS and Firewall #
|
||||
###############################################################################
|
||||
|
||||
module "private-dns" {
|
||||
source = "../../../modules/dns"
|
||||
project_id = module.project.project_id
|
||||
type = "private"
|
||||
name = "${var.prefix}-internal"
|
||||
domain = "internal."
|
||||
client_networks = [module.vpc-consumer.self_link]
|
||||
recordsets = {
|
||||
"A squid" = { ttl = 60, records = [google_compute_address.psc_endpoint_address.address] }
|
||||
"CNAME proxy" = { ttl = 3600, records = ["squid.internal."] }
|
||||
}
|
||||
}
|
||||
|
||||
module "firewall-consumer" {
|
||||
source = "../../../modules/net-vpc-firewall"
|
||||
project_id = module.project.project_id
|
||||
network = module.vpc-consumer.name
|
||||
}
|
|
@ -0,0 +1,218 @@
|
|||
/**
|
||||
* Copyright 2022 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
###############################################################################
|
||||
# Host project and VPC resources #
|
||||
###############################################################################
|
||||
|
||||
module "project" {
|
||||
source = "../../../modules/project"
|
||||
project_create = var.project_create != null
|
||||
billing_account = try(var.project_create.billing_account, null)
|
||||
parent = try(var.project_create.parent, null)
|
||||
name = var.project_id
|
||||
services = [
|
||||
"dns.googleapis.com",
|
||||
"compute.googleapis.com",
|
||||
"logging.googleapis.com",
|
||||
"monitoring.googleapis.com"
|
||||
]
|
||||
}
|
||||
|
||||
module "vpc" {
|
||||
source = "../../../modules/net-vpc"
|
||||
project_id = module.project.project_id
|
||||
name = "${var.prefix}-vpc"
|
||||
subnets = [
|
||||
{
|
||||
name = "proxy"
|
||||
ip_cidr_range = var.cidrs.proxy
|
||||
region = var.region
|
||||
}
|
||||
]
|
||||
subnets_psc = [
|
||||
{
|
||||
name = "psc"
|
||||
ip_cidr_range = var.cidrs.psc
|
||||
region = var.region
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
module "firewall" {
|
||||
source = "../../../modules/net-vpc-firewall"
|
||||
project_id = module.project.project_id
|
||||
network = module.vpc.name
|
||||
ingress_rules = {
|
||||
allow-ingress-squid = {
|
||||
description = "Allow squid ingress traffic"
|
||||
source_ranges = [
|
||||
var.cidrs.psc, "35.191.0.0/16", "130.211.0.0/22"
|
||||
]
|
||||
targets = [module.service-account-squid.email]
|
||||
use_service_accounts = true
|
||||
rules = [{
|
||||
protocol = "tcp"
|
||||
ports = [3128]
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module "nat" {
|
||||
source = "../../../modules/net-cloudnat"
|
||||
project_id = module.project.project_id
|
||||
region = var.region
|
||||
name = "default"
|
||||
router_network = module.vpc.name
|
||||
config_source_subnets = "LIST_OF_SUBNETWORKS"
|
||||
# 64512/11 = 5864 . 11 is the number of usable IPs in the proxy subnet
|
||||
config_min_ports_per_vm = 5864
|
||||
subnetworks = [
|
||||
{
|
||||
self_link = module.vpc.subnet_self_links["${var.region}/proxy"]
|
||||
config_source_ranges = ["ALL_IP_RANGES"]
|
||||
secondary_ranges = null
|
||||
}
|
||||
]
|
||||
logging_filter = var.nat_logging
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# PSC resources #
|
||||
###############################################################################
|
||||
|
||||
resource "google_compute_service_attachment" "service_attachment" {
|
||||
name = "psc"
|
||||
project = module.project.project_id
|
||||
region = var.region
|
||||
enable_proxy_protocol = true
|
||||
connection_preference = "ACCEPT_MANUAL"
|
||||
nat_subnets = [module.vpc.subnets_psc["${var.region}/psc"].self_link]
|
||||
target_service = module.squid-ilb.forwarding_rule_self_link
|
||||
consumer_accept_lists {
|
||||
project_id_or_num = module.project.project_id
|
||||
connection_limit = 10
|
||||
}
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Squid resources #
|
||||
###############################################################################
|
||||
|
||||
module "service-account-squid" {
|
||||
source = "../../../modules/iam-service-account"
|
||||
project_id = module.project.project_id
|
||||
name = "svc-squid"
|
||||
iam_project_roles = {
|
||||
(module.project.project_id) = [
|
||||
"roles/logging.logWriter",
|
||||
"roles/monitoring.metricWriter",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
module "cos-squid" {
|
||||
source = "../../../modules/cloud-config-container/squid"
|
||||
allow = var.allowed_domains
|
||||
clients = [var.cidrs.app]
|
||||
squid_config = "${path.module}/squid.conf"
|
||||
config_variables = {
|
||||
psc_cidr = var.cidrs.psc
|
||||
}
|
||||
}
|
||||
|
||||
module "squid-vm" {
|
||||
source = "../../../modules/compute-vm"
|
||||
project_id = module.project.project_id
|
||||
zone = "${var.region}-b"
|
||||
name = "squid-vm"
|
||||
instance_type = "e2-medium"
|
||||
create_template = true
|
||||
network_interfaces = [{
|
||||
network = module.vpc.self_link
|
||||
subnetwork = module.vpc.subnet_self_links["${var.region}/proxy"]
|
||||
}]
|
||||
boot_disk = {
|
||||
image = "cos-cloud/cos-stable"
|
||||
}
|
||||
service_account = module.service-account-squid.email
|
||||
service_account_scopes = ["https://www.googleapis.com/auth/cloud-platform"]
|
||||
metadata = {
|
||||
user-data = module.cos-squid.cloud_config
|
||||
google-logging-enabled = true
|
||||
}
|
||||
}
|
||||
|
||||
module "squid-mig" {
|
||||
source = "../../../modules/compute-mig"
|
||||
project_id = module.project.project_id
|
||||
location = "${var.region}-b"
|
||||
name = "squid-mig"
|
||||
instance_template = module.squid-vm.template.self_link
|
||||
target_size = 1
|
||||
auto_healing_policies = {
|
||||
initial_delay_sec = 60
|
||||
}
|
||||
autoscaler_config = {
|
||||
max_replicas = 10
|
||||
min_replicas = 1
|
||||
cooldown_period = 30
|
||||
scaling_signals = {
|
||||
cpu_utilization = {
|
||||
target = 0.65
|
||||
}
|
||||
}
|
||||
}
|
||||
health_check_config = {
|
||||
enable_logging = true
|
||||
tcp = {
|
||||
port = 3128
|
||||
proxy_header = "PROXY_V1"
|
||||
}
|
||||
}
|
||||
update_policy = {
|
||||
minimal_action = "REPLACE"
|
||||
type = "PROACTIVE"
|
||||
max_surge = {
|
||||
fixed = 3
|
||||
}
|
||||
min_ready_sec = 60
|
||||
}
|
||||
}
|
||||
|
||||
module "squid-ilb" {
|
||||
source = "../../../modules/net-ilb"
|
||||
project_id = module.project.project_id
|
||||
region = var.region
|
||||
name = "squid-ilb"
|
||||
ports = [3128]
|
||||
service_label = "squid-ilb"
|
||||
vpc_config = {
|
||||
network = module.vpc.self_link
|
||||
subnetwork = module.vpc.subnet_self_links["${var.region}/proxy"]
|
||||
}
|
||||
backends = [{
|
||||
group = module.squid-mig.group_manager.instance_group
|
||||
}]
|
||||
health_check_config = {
|
||||
enable_logging = true
|
||||
tcp = {
|
||||
port = 3128
|
||||
proxy_header = "PROXY_V1"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
# bind to port 3128 and require PROXY protocol
|
||||
http_port 0.0.0.0:3128 require-proxy-header
|
||||
|
||||
# only proxy, don't cache
|
||||
cache deny all
|
||||
|
||||
# redirect all logs to /dev/stdout
|
||||
logfile_rotate 0
|
||||
cache_log stdio:/dev/stdout
|
||||
access_log stdio:/dev/stdout
|
||||
cache_store_log stdio:/dev/stdout
|
||||
|
||||
pid_filename /var/run/squid/squid.pid
|
||||
|
||||
acl ssl_ports port 443
|
||||
acl safe_ports port 80
|
||||
acl safe_ports port 443
|
||||
acl CONNECT method CONNECT
|
||||
acl to_metadata dst 169.254.169.254
|
||||
acl from_healthchecks src 130.211.0.0/22 35.191.0.0/16
|
||||
acl psc src ${psc_cidr}
|
||||
|
||||
# read client CIDR ranges from clients.txt
|
||||
acl clients src "/etc/squid/clients.txt"
|
||||
|
||||
# read allowed domains from allowlist.txt
|
||||
acl allowlist dstdomain "/etc/squid/allowlist.txt"
|
||||
|
||||
# read denied domains from denylist.txt
|
||||
acl denylist dstdomain "/etc/squid/denylist.txt"
|
||||
|
||||
# allow PROXY protocol from the PSC subnet
|
||||
proxy_protocol_access allow psc
|
||||
|
||||
# allow PROXY protocol from the LB health checks
|
||||
proxy_protocol_access allow from_healthchecks
|
||||
|
||||
# deny access to anything other than ports 80 and 443
|
||||
http_access deny !safe_ports
|
||||
|
||||
# deny CONNECT if connection is not using ssl
|
||||
http_access deny CONNECT !ssl_ports
|
||||
|
||||
# deny acccess to cachemgr
|
||||
http_access deny manager
|
||||
|
||||
# deny access to localhost through the proxy
|
||||
http_access deny to_localhost
|
||||
|
||||
# deny access to the local metadata server through the proxy
|
||||
http_access deny to_metadata
|
||||
|
||||
# deny connection from allowed clients to any denied domains
|
||||
http_access deny clients denylist
|
||||
|
||||
# allow connection from allowed clients only to the allowed domains
|
||||
http_access allow clients allowlist
|
||||
|
||||
# deny everything else
|
||||
http_access ${default_action} all
|
|
@ -0,0 +1,26 @@
|
|||
# Copyright 2022 Google LLC
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
cat <<EOF > /etc/apt/apt.conf.d/proxy.conf
|
||||
Acquire {
|
||||
HTTP::proxy "${proxy_url}";
|
||||
HTTPS::proxy "${proxy_url}";
|
||||
}
|
||||
EOF
|
||||
|
||||
cat <<EOF > /etc/profile.d/proxy.sh
|
||||
export http_proxy="${proxy_url}"
|
||||
export https_proxy="${proxy_url}"
|
||||
export no_proxy="127.0.0.1,localhost"
|
||||
EOF
|
|
@ -0,0 +1,79 @@
|
|||
/**
|
||||
* Copyright 2022 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
variable "allowed_domains" {
|
||||
description = "List of domains allowed by the squid proxy."
|
||||
type = list(string)
|
||||
default = [
|
||||
".google.com",
|
||||
".github.com",
|
||||
".fastlydns.net",
|
||||
".debian.org"
|
||||
]
|
||||
}
|
||||
|
||||
variable "cidrs" {
|
||||
description = "CIDR ranges for subnets."
|
||||
type = map(string)
|
||||
default = {
|
||||
app = "10.0.0.0/24"
|
||||
proxy = "10.0.2.0/28"
|
||||
psc = "10.0.3.0/28"
|
||||
}
|
||||
}
|
||||
|
||||
variable "nat_logging" {
|
||||
description = "Enables Cloud NAT logging if not null, value is one of 'ERRORS_ONLY', 'TRANSLATIONS_ONLY', 'ALL'."
|
||||
type = string
|
||||
default = "ERRORS_ONLY"
|
||||
}
|
||||
|
||||
variable "prefix" {
|
||||
description = "Prefix used for resource names."
|
||||
type = string
|
||||
validation {
|
||||
condition = var.prefix != ""
|
||||
error_message = "Prefix cannot be empty."
|
||||
}
|
||||
}
|
||||
|
||||
variable "project_create" {
|
||||
description = "Set to non null if project needs to be created."
|
||||
type = object({
|
||||
billing_account = string
|
||||
parent = string
|
||||
})
|
||||
default = null
|
||||
validation {
|
||||
condition = (
|
||||
var.project_create == null
|
||||
? true
|
||||
: can(regex("(organizations|folders)/[0-9]+", var.project_create.parent))
|
||||
)
|
||||
error_message = "Project parent must be of the form folders/folder_id or organizations/organization_id."
|
||||
}
|
||||
}
|
||||
|
||||
variable "project_id" {
|
||||
description = "Project id used for all resources."
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "region" {
|
||||
description = "Default region for resources."
|
||||
type = string
|
||||
default = "europe-west1"
|
||||
}
|
|
@ -21,13 +21,13 @@ You can optionally deploy the Squid server as [Managed Instance Group](https://c
|
|||
| name | description | type | required | default |
|
||||
|---|---|:---:|:---:|:---:|
|
||||
| [billing_account](variables.tf#L26) | Billing account id used as default for new projects. | <code>string</code> | ✓ | |
|
||||
| [prefix](variables.tf#L52) | Prefix used for resources that need unique names. | <code>string</code> | ✓ | |
|
||||
| [root_node](variables.tf#L63) | Root node for the new hierarchy, either 'organizations/org_id' or 'folders/folder_id'. | <code>string</code> | ✓ | |
|
||||
| [prefix](variables.tf#L52) | Prefix used for resource names. | <code>string</code> | ✓ | |
|
||||
| [root_node](variables.tf#L67) | Root node for the new hierarchy, either 'organizations/org_id' or 'folders/folder_id'. | <code>string</code> | ✓ | |
|
||||
| [allowed_domains](variables.tf#L17) | List of domains allowed by the squid proxy. | <code>list(string)</code> | | <code title="[ ".google.com", ".github.com" ]">[…]</code> |
|
||||
| [cidrs](variables.tf#L31) | CIDR ranges for subnets. | <code>map(string)</code> | | <code title="{ apps = "10.0.0.0/24" proxy = "10.0.1.0/28" }">{…}</code> |
|
||||
| [mig](variables.tf#L40) | Enables the creation of an autoscaling managed instance group of squid instances. | <code>bool</code> | | <code>false</code> |
|
||||
| [nat_logging](variables.tf#L46) | Enables Cloud NAT logging if not null, value is one of 'ERRORS_ONLY', 'TRANSLATIONS_ONLY', 'ALL'. | <code>string</code> | | <code>"ERRORS_ONLY"</code> |
|
||||
| [region](variables.tf#L57) | Default region for resources. | <code>string</code> | | <code>"europe-west1"</code> |
|
||||
| [region](variables.tf#L61) | Default region for resources. | <code>string</code> | | <code>"europe-west1"</code> |
|
||||
|
||||
## Outputs
|
||||
|
||||
|
|
|
@ -50,8 +50,12 @@ variable "nat_logging" {
|
|||
}
|
||||
|
||||
variable "prefix" {
|
||||
description = "Prefix used for resources that need unique names."
|
||||
description = "Prefix used for resource names."
|
||||
type = string
|
||||
validation {
|
||||
condition = var.prefix != ""
|
||||
error_message = "Prefix cannot be empty."
|
||||
}
|
||||
}
|
||||
|
||||
variable "region" {
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue