Merge pull request #984 from apichick/apigee
Apigee module and blueprint
This commit is contained in:
commit
ddd47b0095
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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#L54) | Environment groups (NAME => [HOSTNAMES]). | <code>map(list(string))</code> | ✓ | |
|
||||
| [environments](variables.tf#L60) | 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#L76) | 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#L32) | Project ID. | <code>string</code> | ✓ | |
|
||||
| [psc_config](variables.tf#L104) | PSC configuration. | <code>map(string)</code> | ✓ | |
|
||||
| [datastore_name](variables.tf#L97) | Datastore | <code>string</code> | | <code>"gcs"</code> |
|
||||
| [organization](variables.tf#L38) | 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#L90) | Bucket path. | <code>string</code> | | <code>"/analytics"</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> |
|
||||
| [vpc_create](variables.tf#L26) | 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,12 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
variable "analytics_region" {
|
||||
type = string
|
||||
default = "europe-west1"
|
||||
}
|
||||
|
||||
variable "network" {
|
||||
type = string
|
||||
default = "apigee-vpc"
|
||||
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 "project_create" {
|
||||
description = "Parameters for the creation of the new project."
|
||||
type = object({
|
||||
billing_account_id = string
|
||||
parent = string
|
||||
})
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "vpc_create" {
|
||||
description = "Boolean flag indicating whether the VPC should be created or not."
|
||||
type = bool
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "project_id" {
|
||||
description = "Project ID."
|
||||
type = 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 "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 "path" {
|
||||
description = "Bucket path."
|
||||
type = string
|
||||
default = "/analytics"
|
||||
nullable = false
|
||||
}
|
||||
|
||||
variable "datastore_name" {
|
||||
description = "Datastore"
|
||||
type = string
|
||||
nullable = false
|
||||
default = "gcs"
|
||||
}
|
||||
|
||||
variable "psc_config" {
|
||||
description = "PSC configuration."
|
||||
type = map(string)
|
||||
nullable = false
|
||||
}
|
|
@ -78,8 +78,7 @@ These modules are used in the examples included in this repository. If you are u
|
|||
## Development
|
||||
|
||||
- [API Gateway](./api-gateway)
|
||||
- [Apigee Organization](./apigee-organization)
|
||||
- [Apigee X Instance](./apigee-x-instance)
|
||||
- [Apigee](./apigee)
|
||||
- [Artifact Registry](./artifact-registry)
|
||||
- [Container Registry](./container-registry)
|
||||
- [Cloud Source Repository](./source-repository)
|
||||
|
|
|
@ -1,143 +0,0 @@
|
|||
# Google Apigee Organization Module
|
||||
|
||||
This module allows managing a single Apigee organization and its environments and environmentgroups.
|
||||
|
||||
## Examples
|
||||
|
||||
### Apigee X Evaluation Organization
|
||||
|
||||
```hcl
|
||||
module "apigee-organization" {
|
||||
source = "./fabric/modules/apigee-organization"
|
||||
project_id = "my-project"
|
||||
analytics_region = "us-central1"
|
||||
runtime_type = "CLOUD"
|
||||
authorized_network = "my-vpc"
|
||||
apigee_environments = {
|
||||
eval1 = {
|
||||
api_proxy_type = "PROGRAMMABLE"
|
||||
deployment_type = "PROXY"
|
||||
}
|
||||
eval2 = {
|
||||
api_proxy_type = "CONFIGURABLE"
|
||||
deployment_type = "ARCHIVE"
|
||||
}
|
||||
}
|
||||
apigee_envgroups = {
|
||||
eval = {
|
||||
environments = [
|
||||
"eval1",
|
||||
"eval2"
|
||||
]
|
||||
hostnames = [
|
||||
"eval.api.example.com"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
# tftest modules=1 resources=6
|
||||
```
|
||||
|
||||
### Apigee X Paid Organization
|
||||
|
||||
```hcl
|
||||
module "apigee-organization" {
|
||||
source = "./fabric/modules/apigee-organization"
|
||||
project_id = "my-project"
|
||||
analytics_region = "us-central1"
|
||||
runtime_type = "CLOUD"
|
||||
authorized_network = "my-vpc"
|
||||
database_encryption_key = "my-data-key"
|
||||
apigee_environments = {
|
||||
dev1 = {
|
||||
api_proxy_type = "PROGRAMMABLE"
|
||||
deployment_type = "PROXY"
|
||||
}
|
||||
dev2 = {
|
||||
api_proxy_type = "CONFIGURABLE"
|
||||
deployment_type = "ARCHIVE"
|
||||
}
|
||||
test1 = {}
|
||||
test2 = {}
|
||||
}
|
||||
apigee_envgroups = {
|
||||
dev = {
|
||||
environments = [
|
||||
"dev1",
|
||||
"dev2"
|
||||
]
|
||||
hostnames = [
|
||||
"dev.api.example.com"
|
||||
]
|
||||
}
|
||||
test = {
|
||||
environments = [
|
||||
"test1",
|
||||
"test2"
|
||||
]
|
||||
hostnames = [
|
||||
"test.api.example.com"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
# tftest modules=1 resources=11
|
||||
```
|
||||
|
||||
### Apigee hybrid Organization
|
||||
|
||||
```hcl
|
||||
module "apigee-organization" {
|
||||
source = "./fabric/modules/apigee-organization"
|
||||
project_id = "my-project"
|
||||
analytics_region = "us-central1"
|
||||
runtime_type = "HYBRID"
|
||||
apigee_environments = {
|
||||
eval1 = {
|
||||
api_proxy_type = "PROGRAMMABLE"
|
||||
deployment_type = "PROXY"
|
||||
}
|
||||
eval2 = {}
|
||||
}
|
||||
apigee_envgroups = {
|
||||
eval = {
|
||||
environments = [
|
||||
"eval1",
|
||||
"eval2"
|
||||
]
|
||||
hostnames = [
|
||||
"eval.api.example.com"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
# tftest modules=1 resources=6
|
||||
```
|
||||
<!-- BEGIN TFDOC -->
|
||||
|
||||
## Variables
|
||||
|
||||
| name | description | type | required | default |
|
||||
|---|---|:---:|:---:|:---:|
|
||||
| [analytics_region](variables.tf#L17) | Analytics Region for the Apigee Organization (immutable). See https://cloud.google.com/apigee/docs/api-platform/get-started/install-cli. | <code>string</code> | ✓ | |
|
||||
| [project_id](variables.tf#L72) | Project ID to host this Apigee organization (will also become the Apigee Org name). | <code>string</code> | ✓ | |
|
||||
| [runtime_type](variables.tf#L77) | Apigee runtime type. Must be `CLOUD` or `HYBRID`. | <code>string</code> | ✓ | |
|
||||
| [apigee_envgroups](variables.tf#L22) | Apigee Environment Groups. | <code title="map(object({ environments = list(string) hostnames = list(string) }))">map(object({…}))</code> | | <code>{}</code> |
|
||||
| [apigee_environments](variables.tf#L31) | Apigee Environment Names. | <code title="map(object({ api_proxy_type = optional(string, "API_PROXY_TYPE_UNSPECIFIED") deployment_type = optional(string, "DEPLOYMENT_TYPE_UNSPECIFIED") }))">map(object({…}))</code> | | <code>{}</code> |
|
||||
| [authorized_network](variables.tf#L48) | VPC network self link (requires service network peering enabled (Used in Apigee X only). | <code>string</code> | | <code>null</code> |
|
||||
| [billing_type](variables.tf#L86) | Billing type of the Apigee organization. | <code>string</code> | | <code>null</code> |
|
||||
| [database_encryption_key](variables.tf#L54) | Cloud KMS key self link (e.g. `projects/foo/locations/us/keyRings/bar/cryptoKeys/baz`) used for encrypting the data that is stored and replicated across runtime instances (immutable, used in Apigee X only). | <code>string</code> | | <code>null</code> |
|
||||
| [description](variables.tf#L60) | Description of the Apigee Organization. | <code>string</code> | | <code>"Apigee Organization created by tf module"</code> |
|
||||
| [display_name](variables.tf#L66) | Display Name of the Apigee Organization. | <code>string</code> | | <code>null</code> |
|
||||
|
||||
## Outputs
|
||||
|
||||
| name | description | sensitive |
|
||||
|---|---|:---:|
|
||||
| [envs](outputs.tf#L17) | Apigee Environments. | |
|
||||
| [org](outputs.tf#L22) | Apigee Organization. | |
|
||||
| [org_ca_certificate](outputs.tf#L27) | Apigee organization CA certificate. | |
|
||||
| [org_id](outputs.tf#L32) | Apigee Organization ID. | |
|
||||
| [subscription_type](outputs.tf#L37) | Apigee subscription type. | |
|
||||
|
||||
<!-- END TFDOC -->
|
|
@ -1,66 +0,0 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
locals {
|
||||
env_pairs = flatten([
|
||||
for env_name, env in var.apigee_environments : {
|
||||
api_proxy_type = env.api_proxy_type
|
||||
deployment_type = env.deployment_type
|
||||
env_name = env_name
|
||||
}
|
||||
])
|
||||
|
||||
env_envgroup_pairs = flatten([
|
||||
for eg_name, eg in var.apigee_envgroups : [
|
||||
for e in eg.environments : {
|
||||
envgroup = eg_name
|
||||
env = e
|
||||
}
|
||||
]
|
||||
])
|
||||
}
|
||||
|
||||
resource "google_apigee_organization" "apigee_org" {
|
||||
project_id = var.project_id
|
||||
analytics_region = var.analytics_region
|
||||
display_name = var.display_name
|
||||
description = var.description
|
||||
runtime_type = var.runtime_type
|
||||
billing_type = var.billing_type
|
||||
authorized_network = var.authorized_network
|
||||
runtime_database_encryption_key_name = var.database_encryption_key
|
||||
}
|
||||
|
||||
resource "google_apigee_environment" "apigee_env" {
|
||||
for_each = { for env in local.env_pairs : env.env_name => env }
|
||||
api_proxy_type = each.value.api_proxy_type
|
||||
deployment_type = each.value.deployment_type
|
||||
name = each.key
|
||||
org_id = google_apigee_organization.apigee_org.id
|
||||
}
|
||||
|
||||
resource "google_apigee_envgroup" "apigee_envgroup" {
|
||||
for_each = var.apigee_envgroups
|
||||
org_id = google_apigee_organization.apigee_org.id
|
||||
name = each.key
|
||||
hostnames = each.value.hostnames
|
||||
}
|
||||
|
||||
resource "google_apigee_envgroup_attachment" "env_to_envgroup_attachment" {
|
||||
for_each = { for pair in local.env_envgroup_pairs : "${pair.envgroup}-${pair.env}" => pair }
|
||||
envgroup_id = google_apigee_envgroup.apigee_envgroup[each.value.envgroup].id
|
||||
environment = google_apigee_environment.apigee_env[each.value.env].name
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
output "envs" {
|
||||
description = "Apigee Environments."
|
||||
value = google_apigee_environment.apigee_env
|
||||
}
|
||||
|
||||
output "org" {
|
||||
description = "Apigee Organization."
|
||||
value = google_apigee_organization.apigee_org
|
||||
}
|
||||
|
||||
output "org_ca_certificate" {
|
||||
description = "Apigee organization CA certificate."
|
||||
value = google_apigee_organization.apigee_org.ca_certificate
|
||||
}
|
||||
|
||||
output "org_id" {
|
||||
description = "Apigee Organization ID."
|
||||
value = google_apigee_organization.apigee_org.id
|
||||
}
|
||||
|
||||
output "subscription_type" {
|
||||
description = "Apigee subscription type."
|
||||
value = google_apigee_organization.apigee_org.subscription_type
|
||||
}
|
|
@ -1,90 +0,0 @@
|
|||
/**
|
||||
* 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 "analytics_region" {
|
||||
description = "Analytics Region for the Apigee Organization (immutable). See https://cloud.google.com/apigee/docs/api-platform/get-started/install-cli."
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "apigee_envgroups" {
|
||||
description = "Apigee Environment Groups."
|
||||
type = map(object({
|
||||
environments = list(string)
|
||||
hostnames = list(string)
|
||||
}))
|
||||
default = {}
|
||||
}
|
||||
|
||||
variable "apigee_environments" {
|
||||
description = "Apigee Environment Names."
|
||||
type = map(object({
|
||||
api_proxy_type = optional(string, "API_PROXY_TYPE_UNSPECIFIED")
|
||||
deployment_type = optional(string, "DEPLOYMENT_TYPE_UNSPECIFIED")
|
||||
}))
|
||||
default = {}
|
||||
validation {
|
||||
condition = alltrue([for k, v in var.apigee_environments : contains(["API_PROXY_TYPE_UNSPECIFIED", "PROGRAMMABLE", "CONFIGURABLE"], v.api_proxy_type)])
|
||||
error_message = "Allowed values for api_proxy_type \"API_PROXY_TYPE_UNSPECIFIED\", \"PROGRAMMABLE\" or \"CONFIGURABLE\"."
|
||||
}
|
||||
validation {
|
||||
condition = alltrue([for k, v in var.apigee_environments : contains(["DEPLOYMENT_TYPE_UNSPECIFIED", "PROXY", "ARCHIVE"], v.deployment_type)])
|
||||
error_message = "Allowed values for deployment_type \"DEPLOYMENT_TYPE_UNSPECIFIED\", \"PROXY\" or \"ARCHIVE\"."
|
||||
}
|
||||
}
|
||||
|
||||
variable "authorized_network" {
|
||||
description = "VPC network self link (requires service network peering enabled (Used in Apigee X only)."
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "database_encryption_key" {
|
||||
description = "Cloud KMS key self link (e.g. `projects/foo/locations/us/keyRings/bar/cryptoKeys/baz`) used for encrypting the data that is stored and replicated across runtime instances (immutable, used in Apigee X only)."
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "description" {
|
||||
description = "Description of the Apigee Organization."
|
||||
type = string
|
||||
default = "Apigee Organization created by tf module"
|
||||
}
|
||||
|
||||
variable "display_name" {
|
||||
description = "Display Name of the Apigee Organization."
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "project_id" {
|
||||
description = "Project ID to host this Apigee organization (will also become the Apigee Org name)."
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "runtime_type" {
|
||||
description = "Apigee runtime type. Must be `CLOUD` or `HYBRID`."
|
||||
type = string
|
||||
validation {
|
||||
condition = contains(["CLOUD", "HYBRID"], var.runtime_type)
|
||||
error_message = "Allowed values for runtime_type \"CLOUD\" or \"HYBRID\"."
|
||||
}
|
||||
}
|
||||
|
||||
variable "billing_type" {
|
||||
description = "Billing type of the Apigee organization."
|
||||
type = string
|
||||
default = null
|
||||
}
|
|
@ -1,70 +0,0 @@
|
|||
# Google Apigee X Instance Module
|
||||
|
||||
This module allows managing a single Apigee X instance and its environment attachments.
|
||||
|
||||
## Examples
|
||||
|
||||
### Apigee X Evaluation Instance
|
||||
|
||||
```hcl
|
||||
module "apigee-x-instance" {
|
||||
source = "./fabric/modules/apigee-x-instance"
|
||||
name = "my-us-instance"
|
||||
region = "us-central1"
|
||||
ip_range = "10.0.0.0/22"
|
||||
|
||||
apigee_org_id = "my-project"
|
||||
apigee_environments = [
|
||||
"eval1",
|
||||
"eval2"
|
||||
]
|
||||
}
|
||||
# tftest modules=1 resources=3
|
||||
```
|
||||
|
||||
### Apigee X Paid Instance
|
||||
|
||||
```hcl
|
||||
module "apigee-x-instance" {
|
||||
source = "./fabric/modules/apigee-x-instance"
|
||||
name = "my-us-instance"
|
||||
region = "us-central1"
|
||||
ip_range = "10.0.0.0/22"
|
||||
disk_encryption_key = "my-disk-key"
|
||||
|
||||
apigee_org_id = "my-project"
|
||||
apigee_environments = [
|
||||
"dev1",
|
||||
"dev2",
|
||||
"test1",
|
||||
"test2"
|
||||
]
|
||||
}
|
||||
# tftest modules=1 resources=5
|
||||
```
|
||||
<!-- BEGIN TFDOC -->
|
||||
|
||||
## Variables
|
||||
|
||||
| name | description | type | required | default |
|
||||
|---|---|:---:|:---:|:---:|
|
||||
| [apigee_org_id](variables.tf#L32) | Apigee Organization ID. | <code>string</code> | ✓ | |
|
||||
| [name](variables.tf#L55) | Apigee instance name. | <code>string</code> | ✓ | |
|
||||
| [region](variables.tf#L60) | Compute region. | <code>string</code> | ✓ | |
|
||||
| [apigee_envgroups](variables.tf#L17) | Apigee Environment Groups. | <code title="map(object({ environments = list(string) hostnames = list(string) }))">map(object({…}))</code> | | <code>{}</code> |
|
||||
| [apigee_environments](variables.tf#L26) | Apigee Environment Names. | <code>list(string)</code> | | <code>[]</code> |
|
||||
| [consumer_accept_list](variables.tf#L37) | List of projects (id/number) that can privately connect to the service attachment. | <code>list(string)</code> | | <code>null</code> |
|
||||
| [disk_encryption_key](variables.tf#L49) | Customer Managed Encryption Key (CMEK) self link (e.g. `projects/foo/locations/us/keyRings/bar/cryptoKeys/baz`) used for disk and volume encryption (required for PAID Apigee Orgs only). | <code>string</code> | | <code>null</code> |
|
||||
| [ip_range](variables.tf#L43) | Input: Customer-provided CIDR blocks of length 22 (e.g. `10.0.0.0/22`) Output: Main and Support CIDR (e.g. `10.0.0.0/22,10.1.0.0/28`). | <code>string</code> | | <code>null</code> |
|
||||
|
||||
## Outputs
|
||||
|
||||
| name | description | sensitive |
|
||||
|---|---|:---:|
|
||||
| [endpoint](outputs.tf#L17) | Internal endpoint of the Apigee instance. | |
|
||||
| [id](outputs.tf#L22) | Apigee instance ID. | |
|
||||
| [instance](outputs.tf#L27) | Apigee instance. | |
|
||||
| [port](outputs.tf#L32) | Port number of the internal endpoint of the Apigee instance. | |
|
||||
| [service_attachment](outputs.tf#L37) | Resource name of the service attachment created for this Apigee instance. | |
|
||||
|
||||
<!-- END TFDOC -->
|
|
@ -1,30 +0,0 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
resource "google_apigee_instance" "apigee_instance" {
|
||||
org_id = var.apigee_org_id
|
||||
name = var.name
|
||||
location = var.region
|
||||
ip_range = var.ip_range
|
||||
disk_encryption_key_name = var.disk_encryption_key
|
||||
consumer_accept_list = var.consumer_accept_list
|
||||
}
|
||||
|
||||
resource "google_apigee_instance_attachment" "apigee_instance_attchment" {
|
||||
for_each = toset(var.apigee_environments)
|
||||
instance_id = google_apigee_instance.apigee_instance.id
|
||||
environment = each.key
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
/**
|
||||
* 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.
|
||||
* limitations under the License.
|
||||
* See the License for the specific language governing permissions and
|
||||
*/
|
||||
|
||||
output "endpoint" {
|
||||
description = "Internal endpoint of the Apigee instance."
|
||||
value = google_apigee_instance.apigee_instance.host
|
||||
}
|
||||
|
||||
output "id" {
|
||||
description = "Apigee instance ID."
|
||||
value = google_apigee_instance.apigee_instance.id
|
||||
}
|
||||
|
||||
output "instance" {
|
||||
description = "Apigee instance."
|
||||
value = google_apigee_instance.apigee_instance
|
||||
}
|
||||
|
||||
output "port" {
|
||||
description = "Port number of the internal endpoint of the Apigee instance."
|
||||
value = google_apigee_instance.apigee_instance.port
|
||||
}
|
||||
|
||||
output "service_attachment" {
|
||||
description = "Resource name of the service attachment created for this Apigee instance."
|
||||
value = google_apigee_instance.apigee_instance.service_attachment
|
||||
}
|
|
@ -1,63 +0,0 @@
|
|||
/**
|
||||
* 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 "apigee_envgroups" {
|
||||
description = "Apigee Environment Groups."
|
||||
type = map(object({
|
||||
environments = list(string)
|
||||
hostnames = list(string)
|
||||
}))
|
||||
default = {}
|
||||
}
|
||||
|
||||
variable "apigee_environments" {
|
||||
description = "Apigee Environment Names."
|
||||
type = list(string)
|
||||
default = []
|
||||
}
|
||||
|
||||
variable "apigee_org_id" {
|
||||
description = "Apigee Organization ID."
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "consumer_accept_list" {
|
||||
description = "List of projects (id/number) that can privately connect to the service attachment."
|
||||
type = list(string)
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "ip_range" {
|
||||
description = "Input: Customer-provided CIDR blocks of length 22 (e.g. `10.0.0.0/22`) Output: Main and Support CIDR (e.g. `10.0.0.0/22,10.1.0.0/28`)."
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "disk_encryption_key" {
|
||||
description = "Customer Managed Encryption Key (CMEK) self link (e.g. `projects/foo/locations/us/keyRings/bar/cryptoKeys/baz`) used for disk and volume encryption (required for PAID Apigee Orgs only)."
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "name" {
|
||||
description = "Apigee instance name."
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "region" {
|
||||
description = "Compute region."
|
||||
type = string
|
||||
}
|
|
@ -0,0 +1,162 @@
|
|||
# Apigee
|
||||
|
||||
This module simplifies the creation of a Apigee resources (organization, environment groups, environment group attachments, environments, instances and instance attachments).
|
||||
|
||||
## Example
|
||||
|
||||
### All resources (CLOUD)
|
||||
|
||||
```hcl
|
||||
module "apigee" {
|
||||
source = "./fabric/modules/apigee"
|
||||
project_id = "my-project"
|
||||
organization = {
|
||||
display_name = "My Organization"
|
||||
description = "My Organization"
|
||||
authorized_network = "my-vpc"
|
||||
runtime_type = "CLOUD"
|
||||
billing_type = "PAYG"
|
||||
database_encryption_key = "123456789"
|
||||
analytics_region = "europe-west1"
|
||||
}
|
||||
envgroups = {
|
||||
test = ["test.example.com"]
|
||||
prod = ["prod.example.com"]
|
||||
}
|
||||
environments = {
|
||||
apis-test = {
|
||||
display_name = "APIs test"
|
||||
description = "APIs Test"
|
||||
envgroups = ["test"]
|
||||
}
|
||||
apis-prod = {
|
||||
display_name = "APIs prod"
|
||||
description = "APIs prod"
|
||||
envgroups = ["prod"]
|
||||
iam = {
|
||||
"roles/viewer" = ["group:devops@myorg.com"]
|
||||
}
|
||||
}
|
||||
}
|
||||
instances = {
|
||||
instance-test-ew1 = {
|
||||
region = "europe-west1"
|
||||
environments = ["apis-test"]
|
||||
psa_ip_cidr_range = "10.0.4.0/22"
|
||||
}
|
||||
instance-prod-ew1 = {
|
||||
region = "europe-west1"
|
||||
environments = ["apis-prod"]
|
||||
psa_ip_cidr_range = "10.0.4.0/22"
|
||||
}
|
||||
}
|
||||
}
|
||||
# tftest modules=1 resources=12
|
||||
```
|
||||
|
||||
### All resources (HYBRID control plane)
|
||||
|
||||
```hcl
|
||||
module "apigee" {
|
||||
source = "./fabric/modules/apigee"
|
||||
project_id = "my-project"
|
||||
organization = {
|
||||
display_name = "My Organization"
|
||||
description = "My Organization"
|
||||
runtime_type = "HYBRID"
|
||||
analytics_region = "europe-west1"
|
||||
}
|
||||
envgroups = {
|
||||
test = ["test.example.com"]
|
||||
prod = ["prod.example.com"]
|
||||
}
|
||||
environments = {
|
||||
apis-test = {
|
||||
display_name = "APIs test"
|
||||
description = "APIs Test"
|
||||
envgroups = ["test"]
|
||||
}
|
||||
apis-prod = {
|
||||
display_name = "APIs prod"
|
||||
description = "APIs prod"
|
||||
envgroups = ["prod"]
|
||||
iam = {
|
||||
"roles/viewer" = ["group:devops@myorg.com"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
# tftest modules=1 resources=8
|
||||
```
|
||||
|
||||
### New environment group in an existing organization
|
||||
|
||||
```hcl
|
||||
module "apigee" {
|
||||
source = "./fabric/modules/apigee"
|
||||
project_id = "my-project"
|
||||
envgroups = {
|
||||
test = ["test.example.com"]
|
||||
}
|
||||
}
|
||||
# tftest modules=1 resources=1
|
||||
```
|
||||
|
||||
### New environment in an existing environment group
|
||||
|
||||
```hcl
|
||||
module "apigee" {
|
||||
source = "./fabric/modules/apigee"
|
||||
project_id = "my-project"
|
||||
environments = {
|
||||
apis-test = {
|
||||
display_name = "APIs test"
|
||||
description = "APIs Test"
|
||||
envgroups = ["test"]
|
||||
}
|
||||
}
|
||||
}
|
||||
# tftest modules=1 resources=2
|
||||
```
|
||||
|
||||
### New instance attached to an existing environment
|
||||
|
||||
```hcl
|
||||
module "apigee" {
|
||||
source = "./fabric/modules/apigee"
|
||||
project_id = "my-project"
|
||||
instances = {
|
||||
instance-test-ew1 = {
|
||||
region = "europe-west1"
|
||||
environments = ["apis-test"]
|
||||
psa_ip_cidr_range = "10.0.4.0/22"
|
||||
}
|
||||
}
|
||||
}
|
||||
# tftest modules=1 resources=2
|
||||
```
|
||||
<!-- BEGIN TFDOC -->
|
||||
|
||||
## Variables
|
||||
|
||||
| name | description | type | required | default |
|
||||
|---|---|:---:|:---:|:---:|
|
||||
| [project_id](variables.tf#L17) | Project ID. | <code>string</code> | ✓ | |
|
||||
| [envgroups](variables.tf#L36) | Environment groups (NAME => [HOSTNAMES]). | <code>map(list(string))</code> | | <code>null</code> |
|
||||
| [environments](variables.tf#L42) | Environments. | <code title="map(object({ display_name = optional(string) description = optional(string, "Terraform-managed") 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> | | <code>null</code> |
|
||||
| [instances](variables.tf#L58) | Instance. | <code title="map(object({ display_name = optional(string) description = optional(string, "Terraform-managed") region = string environments = list(string) psa_ip_cidr_range = string disk_encryption_key = optional(string) consumer_accept_list = optional(list(string)) }))">map(object({…}))</code> | | <code>null</code> |
|
||||
| [organization](variables.tf#L22) | Apigee organization. If set to null the organization must already exist. | <code title="object({ display_name = optional(string) description = optional(string, "Terraform-managed") authorized_network = optional(string) runtime_type = optional(string, "CLOUD") billing_type = optional(string) database_encryption_key = optional(string) analytics_region = optional(string, "europe-west1") })">object({…})</code> | | <code>null</code> |
|
||||
|
||||
## Outputs
|
||||
|
||||
| name | description | sensitive |
|
||||
|---|---|:---:|
|
||||
| [envgroups](outputs.tf#L32) | Environment groups. | |
|
||||
| [environments](outputs.tf#L37) | Environment. | |
|
||||
| [instances](outputs.tf#L42) | Instances | |
|
||||
| [org_id](outputs.tf#L22) | Organization ID. | |
|
||||
| [org_name](outputs.tf#L27) | Organization name. | |
|
||||
| [organization](outputs.tf#L17) | Organization. | |
|
||||
| [service_attachments](outputs.tf#L47) | Service attachments. | |
|
||||
|
||||
<!-- END TFDOC -->
|
|
@ -0,0 +1,106 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
locals {
|
||||
org_id = try(google_apigee_organization.organization[0].id, "organizations/${var.project_id}")
|
||||
envgroups = coalesce(var.envgroups, {})
|
||||
environments = coalesce(var.environments, {})
|
||||
instances = coalesce(var.instances, {})
|
||||
}
|
||||
|
||||
resource "google_apigee_organization" "organization" {
|
||||
count = var.organization == null ? 0 : 1
|
||||
analytics_region = var.organization.analytics_region
|
||||
project_id = var.project_id
|
||||
authorized_network = var.organization.authorized_network
|
||||
billing_type = var.organization.billing_type
|
||||
runtime_type = var.organization.runtime_type
|
||||
runtime_database_encryption_key_name = var.organization.database_encryption_key
|
||||
}
|
||||
|
||||
resource "google_apigee_envgroup" "envgroups" {
|
||||
for_each = local.envgroups
|
||||
name = each.key
|
||||
hostnames = each.value
|
||||
org_id = local.org_id
|
||||
}
|
||||
|
||||
resource "google_apigee_environment" "environments" {
|
||||
for_each = local.environments
|
||||
name = each.key
|
||||
display_name = each.value.display_name
|
||||
description = each.value.description
|
||||
dynamic "node_config" {
|
||||
for_each = try(each.value.node_config, null) != null ? [""] : []
|
||||
content {
|
||||
min_node_count = node_config.min_node_count
|
||||
max_node_count = node_config.max_node_count
|
||||
current_aggregate_node_count = node_config.current_aggregate_node_count
|
||||
}
|
||||
}
|
||||
org_id = local.org_id
|
||||
}
|
||||
|
||||
resource "google_apigee_envgroup_attachment" "envgroup_attachments" {
|
||||
for_each = merge(concat([for k1, v1 in local.environments : {
|
||||
for v2 in v1.envgroups : "${k1}-${v2}" => {
|
||||
environment = k1
|
||||
envgroup = v2
|
||||
}
|
||||
}])...)
|
||||
envgroup_id = try(google_apigee_envgroup.envgroups[each.value.envgroup].id, each.value.envgroup)
|
||||
environment = google_apigee_environment.environments[each.value.environment].name
|
||||
}
|
||||
|
||||
resource "google_apigee_environment_iam_binding" "binding" {
|
||||
for_each = merge(concat([for k1, v1 in local.environments : {
|
||||
for k2, v2 in coalesce(v1.iam, {}) : "${k1}-${k2}" => {
|
||||
environment = "${k1}"
|
||||
role = k2
|
||||
members = v2
|
||||
}
|
||||
}])...)
|
||||
org_id = local.org_id
|
||||
env_id = google_apigee_environment.environments[each.value.environment].name
|
||||
role = each.value.role
|
||||
members = each.value.members
|
||||
}
|
||||
|
||||
resource "google_apigee_instance" "instances" {
|
||||
for_each = local.instances
|
||||
name = each.key
|
||||
display_name = each.value.display_name
|
||||
description = each.value.description
|
||||
location = each.value.region
|
||||
org_id = local.org_id
|
||||
ip_range = each.value.psa_ip_cidr_range
|
||||
disk_encryption_key_name = each.value.disk_encryption_key
|
||||
consumer_accept_list = each.value.consumer_accept_list
|
||||
}
|
||||
|
||||
resource "google_apigee_instance_attachment" "instance_attachments" {
|
||||
for_each = merge(concat([for k1, v1 in local.instances : {
|
||||
for v2 in v1.environments :
|
||||
"${k1}-${v2}" => {
|
||||
instance = k1
|
||||
environment = v2
|
||||
}
|
||||
}])...)
|
||||
instance_id = google_apigee_instance.instances[each.value.instance].id
|
||||
environment = try(google_apigee_environment.environments[each.value.environment].name,
|
||||
"${local.org_id}/environments/${each.value.environment}")
|
||||
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
output "organization" {
|
||||
description = "Organization."
|
||||
value = try(google_apigee_organization.organization[0], null)
|
||||
}
|
||||
|
||||
output "org_id" {
|
||||
description = "Organization ID."
|
||||
value = local.org_id
|
||||
}
|
||||
|
||||
output "org_name" {
|
||||
description = "Organization name."
|
||||
value = try(google_apigee_organization.organization[0].name, var.project_id)
|
||||
}
|
||||
|
||||
output "envgroups" {
|
||||
description = "Environment groups."
|
||||
value = try(google_apigee_envgroup.envgroups, null)
|
||||
}
|
||||
|
||||
output "environments" {
|
||||
description = "Environment."
|
||||
value = try(google_apigee_environment.environments, null)
|
||||
}
|
||||
|
||||
output "instances" {
|
||||
description = "Instances"
|
||||
value = try(google_apigee_instance.instances, null)
|
||||
}
|
||||
|
||||
output "service_attachments" {
|
||||
description = "Service attachments."
|
||||
value = { for k, v in google_apigee_instance.instances : k => v.service_attachment }
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
/**
|
||||
* 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 "project_id" {
|
||||
description = "Project ID."
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "organization" {
|
||||
description = "Apigee organization. If set to null the organization must already exist."
|
||||
type = object({
|
||||
display_name = optional(string)
|
||||
description = optional(string, "Terraform-managed")
|
||||
authorized_network = optional(string)
|
||||
runtime_type = optional(string, "CLOUD")
|
||||
billing_type = optional(string)
|
||||
database_encryption_key = optional(string)
|
||||
analytics_region = optional(string, "europe-west1")
|
||||
})
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "envgroups" {
|
||||
description = "Environment groups (NAME => [HOSTNAMES])."
|
||||
type = map(list(string))
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "environments" {
|
||||
description = "Environments."
|
||||
type = map(object({
|
||||
display_name = optional(string)
|
||||
description = optional(string, "Terraform-managed")
|
||||
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)
|
||||
}))
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "instances" {
|
||||
description = "Instance."
|
||||
type = map(object({
|
||||
display_name = optional(string)
|
||||
description = optional(string, "Terraform-managed")
|
||||
region = string
|
||||
environments = list(string)
|
||||
psa_ip_cidr_range = string
|
||||
disk_encryption_key = optional(string)
|
||||
consumer_accept_list = optional(list(string))
|
||||
}))
|
||||
default = null
|
||||
}
|
|
@ -25,6 +25,7 @@ locals {
|
|||
"dataflow" : ["dataflow", "compute"]
|
||||
}
|
||||
_service_accounts_robot_services = {
|
||||
apigee = "service-%s@gcp-sa-apigee"
|
||||
artifactregistry = "service-%s@gcp-sa-artifactregistry"
|
||||
bq = "bq-%s@bigquery-encryption"
|
||||
cloudasset = "service-%s@gcp-sa-cloudasset"
|
||||
|
@ -67,6 +68,7 @@ locals {
|
|||
}
|
||||
)
|
||||
service_accounts_jit_services = [
|
||||
"apigee.googleapis.com",
|
||||
"artifactregistry.googleapis.com",
|
||||
"cloudasset.googleapis.com",
|
||||
"gkehub.googleapis.com",
|
||||
|
|
|
@ -14,19 +14,15 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
module "apigee-x-instance" {
|
||||
source = "../../../../modules/apigee-x-instance"
|
||||
name = var.name
|
||||
region = var.region
|
||||
ip_range = var.ip_range
|
||||
|
||||
apigee_org_id = "my-project"
|
||||
apigee_environments = [
|
||||
"eval1",
|
||||
"eval2"
|
||||
]
|
||||
consumer_accept_list = [
|
||||
"project1",
|
||||
"project2"
|
||||
]
|
||||
module "test" {
|
||||
source = "../../../../../blueprints/cloud-operations/apigee"
|
||||
project_create = var.project_create
|
||||
project_id = var.project_id
|
||||
organization = var.organization
|
||||
envgroups = var.envgroups
|
||||
environments = var.environments
|
||||
instances = var.instances
|
||||
path = var.path
|
||||
datastore_name = var.datastore_name
|
||||
psc_config = var.psc_config
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
project_create = {
|
||||
billing_account_id = "12345-12345-12345"
|
||||
parent = "folders/123456789"
|
||||
}
|
||||
project_id = "my-project"
|
||||
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,124 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* 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 "project_create" {
|
||||
description = "Parameters for the creation of the new project."
|
||||
type = object({
|
||||
billing_account_id = string
|
||||
parent = string
|
||||
})
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "vpc_create" {
|
||||
description = "Boolean flag indicating whether the VPC should be created or not."
|
||||
type = bool
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "project_id" {
|
||||
description = "Project ID."
|
||||
type = 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 "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 "path" {
|
||||
description = "Bucket path."
|
||||
type = string
|
||||
default = "/analytics"
|
||||
nullable = false
|
||||
}
|
||||
|
||||
variable "datastore_name" {
|
||||
description = "Datastore"
|
||||
type = string
|
||||
nullable = false
|
||||
default = "gcs"
|
||||
}
|
||||
|
||||
variable "psc_config" {
|
||||
description = "PSC configuration."
|
||||
type = map(string)
|
||||
nullable = false
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
# 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.
|
||||
|
||||
import collections
|
||||
|
||||
def test_blueprint(recursive_e2e_plan_runner):
|
||||
"Test that all blueprint resources are created."
|
||||
count_modules, count_resources = recursive_e2e_plan_runner(tf_var_file='test.regular.tfvars')
|
||||
assert count_modules == 10
|
||||
assert count_resources == 60
|
|
@ -74,11 +74,11 @@ def plan_runner(_plan_runner):
|
|||
def e2e_plan_runner(_plan_runner):
|
||||
"Returns a function to run Terraform plan on an end-to-end fixture."
|
||||
|
||||
def run_plan(fixture_path=None, targets=None, refresh=True,
|
||||
include_bare_resources=False, **tf_vars):
|
||||
def run_plan(fixture_path=None, tf_var_file=None, targets=None,
|
||||
refresh=True, include_bare_resources=False, **tf_vars):
|
||||
"Runs Terraform plan on an end-to-end module using defaults, returns data."
|
||||
plan = _plan_runner(fixture_path, targets=targets, refresh=refresh,
|
||||
**tf_vars)
|
||||
plan = _plan_runner(fixture_path, tf_var_file=tf_var_file, targets=targets,
|
||||
refresh=refresh, **tf_vars)
|
||||
# skip the fixture
|
||||
root_module = plan.root_module['child_modules'][0]
|
||||
modules = dict((mod['address'], mod['resources'])
|
||||
|
@ -106,12 +106,12 @@ def recursive_e2e_plan_runner(_plan_runner):
|
|||
for module in new_modules:
|
||||
walk_plan(module, modules, resources)
|
||||
|
||||
def run_plan(fixture_path=None, targets=None, refresh=True,
|
||||
def run_plan(fixture_path=None, tf_var_file=None, targets=None, refresh=True,
|
||||
include_bare_resources=False, compute_sums=True, tmpdir=True,
|
||||
**tf_vars):
|
||||
"Runs Terraform plan on a root module using defaults, returns data."
|
||||
plan = _plan_runner(fixture_path, targets=targets, refresh=refresh,
|
||||
tmpdir=tmpdir, **tf_vars)
|
||||
plan = _plan_runner(fixture_path, tf_var_file=tf_var_file, targets=targets,
|
||||
refresh=refresh, tmpdir=tmpdir, **tf_vars)
|
||||
modules = []
|
||||
resources = []
|
||||
walk_plan(plan.root_module, modules, resources)
|
||||
|
|
|
@ -14,17 +14,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
variable "name" {
|
||||
type = string
|
||||
default = "my-test-instance"
|
||||
module "test" {
|
||||
source = "../../../../modules/apigee"
|
||||
project_id = var.project_id
|
||||
organization = var.organization
|
||||
envgroups = var.envgroups
|
||||
environments = var.environments
|
||||
instances = var.instances
|
||||
}
|
||||
|
||||
variable "region" {
|
||||
type = string
|
||||
default = "europe-west1"
|
||||
}
|
||||
|
||||
variable "ip_range" {
|
||||
type = string
|
||||
default = "10.0.0.0/22,10.1.0.0/28"
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
project_id = "my-project"
|
||||
organization = {
|
||||
display_name = "My Organization"
|
||||
description = "My Organization"
|
||||
authorized_network = "my-vpc"
|
||||
runtime_type = "CLOUD"
|
||||
billing_type = "Pay-as-you-go"
|
||||
database_encryption_key = "123456789"
|
||||
analytics_region = "europe-west1"
|
||||
}
|
||||
envgroups = {
|
||||
test = ["test.example.com"]
|
||||
prod = ["prod.example.com"]
|
||||
}
|
||||
environments = {
|
||||
apis-test = {
|
||||
display_name = "APIs test"
|
||||
description = "APIs Test"
|
||||
envgroups = ["test"]
|
||||
}
|
||||
apis-prod = {
|
||||
display_name = "APIs prod"
|
||||
description = "APIs prod"
|
||||
envgroups = ["prod"]
|
||||
iam = {
|
||||
"roles/viewer" = ["group:devops@myorg.com"]
|
||||
}
|
||||
}
|
||||
}
|
||||
instances = {
|
||||
instance-test-ew1 = {
|
||||
region = "europe-west1"
|
||||
environments = ["apis-test"]
|
||||
psa_ip_cidr_range = "10.0.4.0/22"
|
||||
}
|
||||
instance-prod-ew1 = {
|
||||
region = "europe-west1"
|
||||
environments = ["apis-prod"]
|
||||
psa_ip_cidr_range = "10.0.4.0/22"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
project_id = "my-project"
|
||||
environments = {
|
||||
apis-test = {
|
||||
display_name = "APIs test"
|
||||
description = "APIs Test"
|
||||
envgroups = ["test"]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
project_id = "my-project"
|
||||
envgroups = {
|
||||
test = ["test.example.com"]
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
project_id = "my-project"
|
||||
instances = {
|
||||
instance-test-ew1 = {
|
||||
region = "europe-west1"
|
||||
environments = ["apis-test"]
|
||||
psa_ip_cidr_range = "10.0.4.0/22"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
project_id = "my-project"
|
||||
organization = {
|
||||
display_name = "My Organization"
|
||||
description = "My Organization"
|
||||
authorized_network = "my-vpc"
|
||||
runtime_type = "CLOUD"
|
||||
billing_type = "PAYG"
|
||||
database_encryption_key = "123456789"
|
||||
analytics_region = "europe-west1"
|
||||
}
|
||||
envgroups = {
|
||||
test = ["test.example.com"]
|
||||
prod = ["prod.example.com"]
|
||||
}
|
||||
environments = {
|
||||
apis-test = {
|
||||
display_name = "APIs test"
|
||||
description = "APIs Test"
|
||||
envgroups = ["test"]
|
||||
}
|
||||
apis-prod = {
|
||||
display_name = "APIs prod"
|
||||
description = "APIs prod"
|
||||
envgroups = ["prod"]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
project_id = "my-project"
|
||||
organization = {
|
||||
display_name = "My Organization"
|
||||
description = "My Organization"
|
||||
authorized_network = "my-vpc"
|
||||
runtime_type = "CLOUD"
|
||||
billing_type = "PAYG"
|
||||
database_encryption_key = "123456789"
|
||||
analytics_region = "europe-west1"
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
/**
|
||||
* 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 "project_id" {
|
||||
description = "Project ID."
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "organization" {
|
||||
description = "Apigee organization"
|
||||
type = object({
|
||||
display_name = optional(string)
|
||||
description = optional(string, "Apigee Organization created by tf module")
|
||||
authorized_network = optional(string)
|
||||
runtime_type = optional(string, "CLOUD")
|
||||
billing_type = optional(string)
|
||||
database_encryption_key = optional(string)
|
||||
analytics_region = optional(string, "europe-west1")
|
||||
})
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "envgroups" {
|
||||
description = "Environment groups (NAME => [HOSTNAMES])."
|
||||
type = map(list(string))
|
||||
default = null
|
||||
}
|
||||
|
||||
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)
|
||||
}))
|
||||
default = null
|
||||
}
|
||||
|
||||
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))
|
||||
}))
|
||||
default = null
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
# 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.
|
||||
|
||||
import collections
|
||||
|
||||
def test_all(plan_runner):
|
||||
"Test that creates all resources."
|
||||
_, resources = plan_runner(tf_var_file='test.all.tfvars')
|
||||
counts = collections.Counter(f'{r["type"]}.{r["name"]}' for r in resources)
|
||||
assert counts == {
|
||||
'google_apigee_organization.organization': 1,
|
||||
'google_apigee_envgroup.envgroups': 2,
|
||||
'google_apigee_environment.environments': 2,
|
||||
'google_apigee_envgroup_attachment.envgroup_attachments': 2,
|
||||
'google_apigee_instance.instances': 2,
|
||||
'google_apigee_instance_attachment.instance_attachments': 2,
|
||||
'google_apigee_environment_iam_binding.binding': 1
|
||||
}
|
||||
|
||||
def test_organization_only(plan_runner):
|
||||
"Test that creates only an organization."
|
||||
_, resources = plan_runner(tf_var_file='test.organization_only.tfvars')
|
||||
counts = collections.Counter(f'{r["type"]}.{r["name"]}' for r in resources)
|
||||
assert counts == {
|
||||
'google_apigee_organization.organization': 1
|
||||
}
|
||||
|
||||
def test_envgroup_only(plan_runner):
|
||||
"Test that creates only an environment group in an existing organization."
|
||||
_, resources = plan_runner(tf_var_file='test.envgroup_only.tfvars')
|
||||
counts = collections.Counter(f'{r["type"]}.{r["name"]}' for r in resources)
|
||||
assert counts == {
|
||||
'google_apigee_envgroup.envgroups': 1,
|
||||
}
|
||||
|
||||
def test_env_only(plan_runner):
|
||||
"Test that creates an environment in an existing environment group."
|
||||
_, resources = plan_runner(tf_var_file='test.env_only.tfvars')
|
||||
counts = collections.Counter(f'{r["type"]}.{r["name"]}' for r in resources)
|
||||
assert counts == {
|
||||
'google_apigee_environment.environments': 1,
|
||||
'google_apigee_envgroup_attachment.envgroup_attachments': 1,
|
||||
}
|
||||
|
||||
def test_instance_only(plan_runner):
|
||||
"Test that creates only an instance."
|
||||
_, resources = plan_runner(tf_var_file='test.instance_only.tfvars')
|
||||
counts = collections.Counter(f'{r["type"]}.{r["name"]}' for r in resources)
|
||||
assert counts == {
|
||||
'google_apigee_instance.instances': 1,
|
||||
'google_apigee_instance_attachment.instance_attachments': 1
|
||||
}
|
||||
|
||||
def test_no_instances(plan_runner):
|
||||
"Test that creates everything but the instances."
|
||||
_, resources = plan_runner(tf_var_file='test.no_instances.tfvars')
|
||||
counts = collections.Counter(f'{r["type"]}.{r["name"]}' for r in resources)
|
||||
assert counts == {
|
||||
'google_apigee_organization.organization': 1,
|
||||
'google_apigee_envgroup.envgroups': 2,
|
||||
'google_apigee_environment.environments': 2,
|
||||
'google_apigee_envgroup_attachment.envgroup_attachments': 2,
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
/**
|
||||
* 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 "test" {
|
||||
source = "../../../../modules/apigee-organization"
|
||||
project_id = "my-project"
|
||||
analytics_region = var.analytics_region
|
||||
runtime_type = "CLOUD"
|
||||
billing_type = "EVALUATION"
|
||||
authorized_network = var.network
|
||||
apigee_environments = {
|
||||
eval1 = {
|
||||
api_proxy_type = "PROGRAMMABLE"
|
||||
deployment_type = "PROXY"
|
||||
}
|
||||
eval2 = {
|
||||
api_proxy_type = "CONFIGURABLE"
|
||||
deployment_type = "ARCHIVE"
|
||||
}
|
||||
eval3 = {}
|
||||
}
|
||||
apigee_envgroups = {
|
||||
eval = {
|
||||
environments = [
|
||||
"eval1",
|
||||
"eval2"
|
||||
]
|
||||
hostnames = [
|
||||
"eval.api.example.com"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
# 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.
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def resources(plan_runner):
|
||||
_, resources = plan_runner()
|
||||
return resources
|
||||
|
||||
|
||||
def test_resource_count(resources):
|
||||
"Test number of resources created."
|
||||
assert len(resources) == 7
|
||||
|
||||
|
||||
def test_envgroup_attachment(resources):
|
||||
"Test Apigee Envgroup Attachments."
|
||||
attachments = [r['values'] for r in resources if r['type']
|
||||
== 'google_apigee_envgroup_attachment']
|
||||
assert len(attachments) == 2
|
||||
assert set(a['environment'] for a in attachments) == set(['eval1', 'eval2'])
|
||||
|
||||
|
||||
def test_envgroup(resources):
|
||||
"Test env group."
|
||||
envgroups = [r['values'] for r in resources if r['type']
|
||||
== 'google_apigee_envgroup']
|
||||
assert len(envgroups) == 1
|
||||
assert envgroups[0]['name'] == 'eval'
|
||||
assert len(envgroups[0]['hostnames']) == 1
|
||||
assert envgroups[0]['hostnames'][0] == 'eval.api.example.com'
|
||||
|
||||
|
||||
def test_env(resources):
|
||||
"Test environments."
|
||||
envs = [r['values'] for r in resources if r['type']
|
||||
== 'google_apigee_environment']
|
||||
assert len(envs) == 3
|
||||
assert envs[0]['name'] == 'eval1'
|
||||
assert envs[0]['api_proxy_type'] == 'PROGRAMMABLE'
|
||||
assert envs[0]['deployment_type'] == 'PROXY'
|
||||
assert envs[1]['name'] == 'eval2'
|
||||
assert envs[1]['api_proxy_type'] == 'CONFIGURABLE'
|
||||
assert envs[1]['deployment_type'] == 'ARCHIVE'
|
||||
assert envs[2]['name'] == 'eval3'
|
||||
assert envs[2]['api_proxy_type'] == 'API_PROXY_TYPE_UNSPECIFIED'
|
||||
assert envs[2]['deployment_type'] == 'DEPLOYMENT_TYPE_UNSPECIFIED'
|
|
@ -1,55 +0,0 @@
|
|||
# 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.
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
@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_instance_attachment(resources):
|
||||
"Test Apigee Instance Attachments."
|
||||
attachments = [
|
||||
r['values']
|
||||
for r in resources
|
||||
if r['type'] == 'google_apigee_instance_attachment'
|
||||
]
|
||||
assert len(attachments) == 2
|
||||
assert set(a['environment'] for a in attachments) == set(['eval1', 'eval2'])
|
||||
|
||||
|
||||
def test_instance(resources):
|
||||
"Test Instance."
|
||||
instances = [
|
||||
r['values'] for r in resources if r['type'] == 'google_apigee_instance'
|
||||
]
|
||||
assert len(instances) == 1
|
||||
assert instances[0]['ip_range'] == '10.0.0.0/22,10.1.0.0/28'
|
||||
assert instances[0]['name'] == 'my-test-instance'
|
||||
assert instances[0]['location'] == 'europe-west1'
|
||||
|
||||
|
||||
def test_instance_consumer_accept_list(resources):
|
||||
instances = [
|
||||
r['values'] for r in resources if r['type'] == 'google_apigee_instance'
|
||||
]
|
||||
assert instances[0]['consumer_accept_list'] == ['project1', 'project2']
|
Loading…
Reference in New Issue