Merge pull request #292 from danistrebel/feature/apigee-module

Adding support for Apigee Organization and Instance creation
This commit is contained in:
Daniel Strebel
2021-08-05 16:41:44 +02:00
committed by GitHub
16 changed files with 722 additions and 0 deletions

View File

@@ -0,0 +1,125 @@
# 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 = "./modules/apigee-organization"
project_id = "my-project"
analytics_region = "us-central1"
runtime_type = "CLOUD"
authorized_network = "my-vpc"
apigee_environments = [
"eval1",
"eval2"
]
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 = "./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",
"dev2",
"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 = "./modules/apigee-organization"
project_id = "my-project"
analytics_region = "us-central1"
runtime_type = "HYBRID"
apigee_environments = [
"eval1",
"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 | Analytics Region for the Apigee Organization (immutable). See https://cloud.google.com/apigee/docs/api-platform/get-started/install-cli. | <code title="">string</code> | ✓ | |
| project_id | Project ID to host this Apigee organization (will also become the Apigee Org name). | <code title="">string</code> | ✓ | |
| runtime_type | None | <code title="string&#10;validation &#123;&#10;condition &#61; contains&#40;&#91;&#34;CLOUD&#34;, &#34;HYBRID&#34;&#93;, var.runtime_type&#41;&#10;error_message &#61; &#34;Allowed values for runtime_type &#92;&#34;CLOUD&#92;&#34; or &#92;&#34;HYBRID&#92;&#34;.&#34;&#10;&#125;">string</code> | ✓ | |
| *apigee_envgroups* | Apigee Environment Groups. | <code title="map&#40;object&#40;&#123;&#10;environments &#61; list&#40;string&#41;&#10;hostnames &#61; list&#40;string&#41;&#10;&#125;&#41;&#41;">map(object({...}))</code> | | <code title="">{}</code> |
| *apigee_environments* | Apigee Environment Names. | <code title="list&#40;string&#41;">list(string)</code> | | <code title="">[]</code> |
| *authorized_network* | VPC network self link (requires service network peering enabled (Used in Apigee X only). | <code title="">string</code> | | <code title="">null</code> |
| *database_encryption_key* | 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 title="">string</code> | | <code title="">null</code> |
| *description* | Description of the Apigee Organization. | <code title="">string</code> | | <code title="">Apigee Organization created by tf module</code> |
| *display_name* | Display Name of the Apigee Organization. | <code title="">string</code> | | <code title="">null</code> |
## Outputs
| name | description | sensitive |
|---|---|:---:|
| org | Apigee Organization. | |
| org_ca_certificate | Apigee organization CA certificate. | |
| org_id | Apigee Organization ID. | |
| subscription_type | Apigee subscription type. | |
<!-- END TFDOC -->

View File

@@ -0,0 +1,55 @@
/**
* Copyright 2021 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_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
authorized_network = var.authorized_network
runtime_database_encryption_key_name = var.database_encryption_key
}
resource "google_apigee_environment" "apigee_env" {
for_each = toset(var.apigee_environments)
org_id = google_apigee_organization.apigee_org.id
name = each.key
}
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
}

View File

@@ -0,0 +1,35 @@
/**
* Copyright 2021 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 "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
}

View File

@@ -0,0 +1,75 @@
/**
* Copyright 2021 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 "authorized_network" {
description = "VPC network self link (requires service network peering enabled (Used in Apigee X only)."
type = string
default = null
}
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 = list(string)
default = []
}
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" {
type = string
validation {
condition = contains(["CLOUD", "HYBRID"], var.runtime_type)
error_message = "Allowed values for runtime_type \"CLOUD\" or \"HYBRID\"."
}
}

View File

@@ -0,0 +1,67 @@
# 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 = "./modules/apigee-x-instance"
name = "my-us-instance"
region = "us-central1"
cidr_mask = 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 = "./modules/apigee-x-instance"
name = "my-us-instance"
region = "us-central1"
cidr_mask = 16
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 | Apigee Organization ID | <code title="">string</code> | ✓ | |
| cidr_mask | CIDR mask for the Apigee instance | <code title="number&#10;validation &#123;&#10;condition &#61; contains&#40;&#91;16, 20, 22&#93;, var.cidr_mask&#41;&#10;error_message &#61; &#34;Invalid CIDR mask; Allowed values for cidr_mask: &#91;16, 20, 22&#93;.&#34;&#10;&#125;">number</code> | ✓ | |
| name | Apigee instance name. | <code title="">string</code> | ✓ | |
| region | Compute region. | <code title="">string</code> | ✓ | |
| *apigee_envgroups* | Apigee Environment Groups. | <code title="map&#40;object&#40;&#123;&#10;environments &#61; list&#40;string&#41;&#10;hostnames &#61; list&#40;string&#41;&#10;&#125;&#41;&#41;">map(object({...}))</code> | | <code title="">{}</code> |
| *apigee_environments* | Apigee Environment Names. | <code title="list&#40;string&#41;">list(string)</code> | | <code title="">[]</code> |
| *disk_encryption_key* | 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 title="">string</code> | | <code title="">null</code> |
## Outputs
| name | description | sensitive |
|---|---|:---:|
| endpoint | Internal endpoint of the Apigee instance. | |
| id | Apigee instance ID. | |
| instance | Apigee instance. | |
| port | Port number of the internal endpoint of the Apigee instance. | |
<!-- END TFDOC -->

View File

@@ -0,0 +1,29 @@
/**
* Copyright 2021 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
peering_cidr_range = "SLASH_${var.cidr_mask}"
disk_encryption_key_name = var.disk_encryption_key
}
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
}

View File

@@ -0,0 +1,35 @@
/**
* Copyright 2021 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
}

View File

@@ -0,0 +1,60 @@
/**
* Copyright 2021 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 "cidr_mask" {
description = "CIDR mask for the Apigee instance"
type = number
validation {
condition = contains([16, 20, 22], var.cidr_mask)
error_message = "Invalid CIDR mask; Allowed values for cidr_mask: [16, 20, 22]."
}
}
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
}

View File

@@ -0,0 +1,13 @@
# Copyright 2021 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.

View File

@@ -0,0 +1,38 @@
/**
* Copyright 2021 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"
authorized_network = var.network
apigee_environments = [
"eval1",
"eval2"
]
apigee_envgroups = {
eval = {
environments = [
"eval1",
"eval2"
]
hostnames = [
"eval.api.example.com"
]
}
}
}

View File

@@ -0,0 +1,25 @@
/**
* Copyright 2021 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" {
type = string
default = "europe-west1"
}
variable "network" {
type = string
default = "apigee-vpc"
}

View File

@@ -0,0 +1,49 @@
# Copyright 2021 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 os
import pytest
FIXTURES_DIR = os.path.join(os.path.dirname(__file__), 'fixture')
@pytest.fixture
def resources(plan_runner):
_, resources = plan_runner(FIXTURES_DIR)
return resources
def test_resource_count(resources):
"Test number of resources created."
assert len(resources) == 6
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'

View File

@@ -0,0 +1,13 @@
# Copyright 2021 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.

View File

@@ -0,0 +1,28 @@
/**
* Copyright 2021 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 "apigee-x-instance" {
source = "../../../../modules/apigee-x-instance"
name = var.name
region = var.region
cidr_mask = 22
apigee_org_id = "my-project"
apigee_environments = [
"eval1",
"eval2"
]
}

View File

@@ -0,0 +1,25 @@
/**
* Copyright 2021 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 "name" {
type = string
default = "my-test-instance"
}
variable "region" {
type = string
default = "europe-west1"
}

View File

@@ -0,0 +1,50 @@
# Copyright 2021 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 os
import pytest
FIXTURES_DIR = os.path.join(os.path.dirname(__file__), 'fixture')
@pytest.fixture
def resources(plan_runner):
_, resources = plan_runner(FIXTURES_DIR)
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]['peering_cidr_range'] == 'SLASH_22'
assert instances[0]['name'] == 'my-test-instance'
assert instances[0]['location'] == 'europe-west1'