Skip to content

Commit e07c63d

Browse files
authored
Merge pull request #324 from terraform-google-modules/feature/acm
Add submodule to set up ACM
2 parents 67bd2c8 + f8d02c1 commit e07c63d

File tree

27 files changed

+492
-13
lines changed

27 files changed

+492
-13
lines changed

.kitchen.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ suites:
8585
backend: local
8686
controls:
8787
- gcloud
88+
- acm
8889
- name: gcp
8990
backend: gcp
9091
controls:

autogen/main.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ locals {
9292
cluster_output_zones = local.cluster_output_regional_zones
9393

9494
{% if private_cluster %}
95-
cluster_output_endpoint = var.deploy_using_private_endpoint ? google_container_cluster.primary.private_cluster_config.0.private_endpoint : google_container_cluster.primary.endpoint
95+
cluster_output_endpoint = var.deploy_using_private_endpoint ? google_container_cluster.primary.private_cluster_config.0.private_endpoint : google_container_cluster.primary.private_cluster_config.0.public_endpoint
9696
{% else %}
9797
cluster_output_endpoint = google_container_cluster.primary.endpoint
9898
{% endif %}

build/int.cloudbuild.yaml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414

1515
timeout: 12600s
1616
steps:
17+
- id: download acm
18+
name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS'
19+
args: ['/bin/bash', '-c', 'source /usr/local/bin/task_helper_functions.sh && download_acm']
1720
- id: prepare
1821
name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS'
1922
args: ['/bin/bash', '-c', 'source /usr/local/bin/task_helper_functions.sh && prepare_environment']
@@ -306,6 +309,6 @@ tags:
306309
- 'integration'
307310
substitutions:
308311
_DOCKER_IMAGE_DEVELOPER_TOOLS: 'cft/developer-tools'
309-
_DOCKER_TAG_VERSION_DEVELOPER_TOOLS: '0.4.6'
312+
_DOCKER_TAG_VERSION_DEVELOPER_TOOLS: '0.5.4'
310313
options:
311314
machineType: 'N1_HIGHCPU_8'

build/lint.cloudbuild.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,4 @@ tags:
2424
- 'lint'
2525
substitutions:
2626
_DOCKER_IMAGE_DEVELOPER_TOOLS: 'cft/developer-tools'
27-
_DOCKER_TAG_VERSION_DEVELOPER_TOOLS: '0.4.6'
27+
_DOCKER_TAG_VERSION_DEVELOPER_TOOLS: '0.5.4'

examples/simple_zonal/README.md renamed to examples/simple_zonal_with_acm/README.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,22 @@
11
# Simple Zonal Cluster
22

3-
This example illustrates how to create a simple cluster.
3+
This example illustrates how to create a simple cluster and install [Anthos Config Management](https://cloud.google.com/anthos-config-management/docs/).
4+
5+
It incorporates the standard cluster module and the [ACM install module](../../modules/acm).
46

57
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
68
## Inputs
79

810
| Name | Description | Type | Default | Required |
911
|------|-------------|:----:|:-----:|:-----:|
12+
| acm\_policy\_dir | Subfolder containing configs in ACM Git repo | string | `"foo-corp"` | no |
13+
| acm\_sync\_branch | Anthos config management Git branch | string | `"1.0.0"` | no |
14+
| acm\_sync\_repo | Anthos config management Git repo | string | `"[email protected]:GoogleCloudPlatform/csp-config-management.git"` | no |
1015
| cluster\_name\_suffix | A suffix to append to the default cluster name | string | `""` | no |
1116
| ip\_range\_pods | The secondary ip range to use for pods | string | n/a | yes |
1217
| ip\_range\_services | The secondary ip range to use for pods | string | n/a | yes |
1318
| network | The VPC network to host the cluster in | string | n/a | yes |
19+
| operator\_path | Path to the operator yaml config. If unset, will download from GCS releases. | string | `"null"` | no |
1420
| project\_id | The project ID to host the cluster in | string | n/a | yes |
1521
| region | The region to host the cluster in | string | n/a | yes |
1622
| subnetwork | The subnetwork to host the cluster in | string | n/a | yes |
@@ -20,6 +26,7 @@ This example illustrates how to create a simple cluster.
2026

2127
| Name | Description |
2228
|------|-------------|
29+
| acm\_git\_creds\_public | Public key of SSH keypair to allow the Anthos Operator to authenticate to your Git repository. |
2330
| ca\_certificate | |
2431
| client\_token | |
2532
| cluster\_name | Cluster name |

examples/simple_zonal_with_acm/acm.tf

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/**
2+
* Copyright 2018 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
module "acm" {
18+
source = "../../modules/acm"
19+
project_id = var.project_id
20+
location = module.gke.location
21+
cluster_name = module.gke.name
22+
sync_repo = var.acm_sync_repo
23+
sync_branch = var.acm_sync_branch
24+
policy_dir = var.acm_policy_dir
25+
cluster_endpoint = module.gke.endpoint
26+
operator_path = var.operator_path
27+
}

examples/simple_zonal/outputs.tf renamed to examples/simple_zonal_with_acm/outputs.tf

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,8 @@ output "service_account" {
3333
value = module.gke.service_account
3434
}
3535

36+
output "acm_git_creds_public" {
37+
description = "Public key of SSH keypair to allow the Anthos Operator to authenticate to your Git repository."
38+
value = module.acm.git_creds_public
39+
}
40+

examples/simple_zonal/variables.tf renamed to examples/simple_zonal_with_acm/variables.tf

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,26 @@ variable "ip_range_services" {
4848
description = "The secondary ip range to use for pods"
4949
}
5050

51+
variable "acm_sync_repo" {
52+
description = "Anthos config management Git repo"
53+
type = string
54+
default = "[email protected]:GoogleCloudPlatform/csp-config-management.git"
55+
}
56+
57+
variable "acm_sync_branch" {
58+
description = "Anthos config management Git branch"
59+
type = string
60+
default = "1.0.0"
61+
}
62+
63+
variable "acm_policy_dir" {
64+
description = "Subfolder containing configs in ACM Git repo"
65+
type = string
66+
default = "foo-corp"
67+
}
68+
69+
variable "operator_path" {
70+
description = "Path to the operator yaml config. If unset, will download from GCS releases."
71+
type = string
72+
default = null
73+
}

modules/acm/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# This fill will be always downloaded by terraform local-exec command from gc bucket
2+
config-management-operator.yaml
3+
/terraform.tfvars

modules/acm/README.md

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# Terraform Kubernetes Engine ACM Submodule
2+
3+
This module installs [Anthos Config Management](https://cloud.google.com/anthos-config-management/docs/) (ACM) in a Kubernetes cluster.
4+
5+
Specifically, this module automates the following steps for [installing ACM](https://cloud.google.com/anthos-config-management/docs/how-to/installing):
6+
1. Installing the ACM Operator on your cluster.
7+
2. Generating an SSH key for accessing Git and providing it to the Operator
8+
3. Configuring the Operator to connect to your ACM repository
9+
10+
## Usage
11+
12+
There is a [full example](../../examples/simple_zonal) provided. Simple usage is as follows:
13+
14+
```tf
15+
module "acm" {
16+
source = "terraform-google-modules/kubernetes-engine/google//modules/acm"
17+
18+
project_id = "my-project-id"
19+
cluster_name = "my-cluster-name"
20+
location = module.gke.location
21+
cluster_endpoint = module.gke.endpoint
22+
23+
sync_repo = "[email protected]:GoogleCloudPlatform/csp-config-management.git"
24+
sync_branch = "1.0.0"
25+
policy_dir = "foo-corp"
26+
}
27+
```
28+
29+
To deploy this config:
30+
1. Run `terraform apply`
31+
2. Inspect the `git_creds_public` [output](#outputs) to retrieve the public key used for accessing Git. Whitelist this key for access to your Git repo. Instructions for some popular Git hosting providers are included for convenience:
32+
33+
* [Cloud Souce Repositories](https://cloud.google.com/source-repositories/docs/authentication#ssh)
34+
* [Bitbucket](https://confluence.atlassian.com/bitbucket/set-up-an-ssh-key-728138079.html)
35+
* [GitHub](https://help.github.com/articles/adding-a-new-ssh-key-to-your-github-account/)
36+
* [Gitlab](https://docs.gitlab.com/ee/ssh/)
37+
38+
## Whitelisting
39+
Note that installing Anthos Config Management [requires](https://cloud.google.com/anthos-config-management/docs/how-to/installing#local_environment) an active Anthos license.
40+
By default, this module will attempt to download the ACM operator from Google directly—meaning your Terraform service account needs to be whitelisted for ACM access. If this is an issue, you can predownload the operator yourself then set the `operator_path` variable to point to the file location.
41+
42+
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
43+
## Inputs
44+
45+
| Name | Description | Type | Default | Required |
46+
|------|-------------|:----:|:-----:|:-----:|
47+
| cluster\_endpoint | Kubernetes cluster endpoint. | string | n/a | yes |
48+
| cluster\_name | The unique name to identify the cluster in ACM. | string | n/a | yes |
49+
| create\_ssh\_key | Controls whether a key will be generated for Git authentication | bool | `"true"` | no |
50+
| enable\_policy\_controller | Whether to enable the ACM Policy Controller on the cluster | bool | `"true"` | no |
51+
| install\_template\_library | Whether to install the default Policy Controller template library | bool | `"true"` | no |
52+
| location | The location (zone or region) this cluster has been created in. | string | n/a | yes |
53+
| operator\_path | Path to the operator yaml config. If unset, will download from GCS releases. | string | `"null"` | no |
54+
| policy\_dir | Subfolder containing configs in ACM Git repo | string | n/a | yes |
55+
| project\_id | The project in which the resource belongs. | string | n/a | yes |
56+
| sync\_branch | ACM repo Git branch | string | `"master"` | no |
57+
| sync\_repo | ACM Git repo address | string | n/a | yes |
58+
59+
## Outputs
60+
61+
| Name | Description |
62+
|------|-------------|
63+
| git\_creds\_public | Public key of SSH keypair to allow the Anthos Operator to authenticate to your Git repository. |
64+
65+
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->

modules/acm/main.tf

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
/**
2+
* Copyright 2018 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
locals {
18+
cluster_endpoint = "https://${var.cluster_endpoint}"
19+
token = data.google_client_config.default.access_token
20+
cluster_ca_certificate = data.google_container_cluster.primary.master_auth.0.cluster_ca_certificate
21+
private_key = var.create_ssh_key ? tls_private_key.git_creds[0].private_key_pem : ""
22+
download_operator = var.operator_path == null ? true : false
23+
operator_path = local.download_operator ? "${path.module}/config-management-operator.yaml" : var.operator_path
24+
}
25+
26+
data "google_container_cluster" "primary" {
27+
name = var.cluster_name
28+
project = var.project_id
29+
location = var.location
30+
}
31+
32+
data "google_client_config" "default" {
33+
}
34+
35+
resource "tls_private_key" "git_creds" {
36+
count = var.create_ssh_key ? 1 : 0
37+
algorithm = "RSA"
38+
rsa_bits = 4096
39+
}
40+
41+
resource "null_resource" "acm_operator_config" {
42+
count = local.download_operator ? 1 : 0
43+
44+
provisioner "local-exec" {
45+
command = "gsutil cp gs://config-management-release/released/latest/config-management-operator.yaml ${path.module}/config-management-operator.yaml"
46+
}
47+
48+
provisioner "local-exec" {
49+
when = destroy
50+
command = "rm -f ${path.module}/config-management-operator.yaml"
51+
}
52+
}
53+
54+
resource "null_resource" "acm_operator" {
55+
provisioner "local-exec" {
56+
command = "${path.module}/scripts/kubectl_wrapper.sh ${local.cluster_endpoint} ${local.token} ${local.cluster_ca_certificate} kubectl apply -f ${local.operator_path}"
57+
}
58+
59+
provisioner "local-exec" {
60+
when = destroy
61+
command = "${path.module}/scripts/kubectl_wrapper.sh ${local.cluster_endpoint} ${local.token} ${local.cluster_ca_certificate} kubectl delete -f ${local.operator_path}"
62+
}
63+
64+
depends_on = [
65+
null_resource.acm_operator_config,
66+
data.google_client_config.default,
67+
data.google_container_cluster.primary,
68+
]
69+
}
70+
71+
resource "null_resource" "git_creds_secret" {
72+
count = var.create_ssh_key ? 1 : 0
73+
74+
provisioner "local-exec" {
75+
command = "${path.module}/scripts/kubectl_wrapper.sh ${local.cluster_endpoint} ${local.token} ${local.cluster_ca_certificate} kubectl create secret generic git-creds -n=config-management-system --from-literal=ssh='${local.private_key}'"
76+
}
77+
78+
provisioner "local-exec" {
79+
when = destroy
80+
command = "${path.module}/scripts/kubectl_wrapper.sh ${local.cluster_endpoint} ${local.token} ${local.cluster_ca_certificate} kubectl delete secret git-creds -n=config-management-system"
81+
}
82+
83+
depends_on = [
84+
null_resource.acm_operator
85+
]
86+
}
87+
88+
data "template_file" "acm_config" {
89+
template = file("${path.module}/templates/acm-config.yml.tpl")
90+
91+
vars = {
92+
cluster_name = var.cluster_name
93+
sync_repo = var.sync_repo
94+
sync_branch = var.sync_branch
95+
policy_dir = var.policy_dir
96+
secret_type = var.create_ssh_key ? "ssh" : "none"
97+
enable_policy_controller = var.enable_policy_controller ? "true" : "false"
98+
install_template_library = var.install_template_library ? "true" : "false"
99+
}
100+
}
101+
102+
resource "null_resource" "acm_config" {
103+
triggers = {
104+
config = data.template_file.acm_config.rendered
105+
}
106+
107+
provisioner "local-exec" {
108+
command = "echo '${data.template_file.acm_config.rendered}' | ${path.module}/scripts/kubectl_wrapper.sh ${local.cluster_endpoint} ${local.token} ${local.cluster_ca_certificate} kubectl apply -f -"
109+
}
110+
111+
provisioner "local-exec" {
112+
when = destroy
113+
command = "echo '${data.template_file.acm_config.rendered}' | ${path.module}/scripts/kubectl_wrapper.sh ${local.cluster_endpoint} ${local.token} ${local.cluster_ca_certificate} kubectl delete -f -"
114+
}
115+
116+
depends_on = [
117+
null_resource.acm_operator,
118+
null_resource.git_creds_secret,
119+
]
120+
}
121+

modules/acm/outputs.tf

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/**
2+
* Copyright 2018 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
output "git_creds_public" {
18+
description = "Public key of SSH keypair to allow the Anthos Operator to authenticate to your Git repository."
19+
value = var.create_ssh_key ? tls_private_key.git_creds.*.public_key_openssh : null
20+
}
21+

0 commit comments

Comments
 (0)