Skip to content

Adding the code for Part3 of the ACM GKE blog - enabling Config Connector and initializing GCP resources #980

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
b77a28f
Adding part 3
AlexBulankou Aug 17, 2021
d1d27a1
kpt changes
AlexBulankou Aug 17, 2021
a00eb9b
Reorganizing config root
AlexBulankou Aug 19, 2021
0ac9ff8
Reorganizing config-root
AlexBulankou Aug 19, 2021
68d10f8
Testing with a custom repo
AlexBulankou Aug 19, 2021
aa84d72
Updating config root
AlexBulankou Aug 19, 2021
65a3e87
Adding project info
AlexBulankou Aug 19, 2021
b55ab0b
Minor fix
AlexBulankou Aug 19, 2021
002818b
Minor IAM change
AlexBulankou Aug 19, 2021
c647207
Changing project
AlexBulankou Aug 19, 2021
d7ca0b4
Updating values before PR
AlexBulankou Aug 19, 2021
0696243
Headers
AlexBulankou Aug 19, 2021
bad73b3
Addressing feedback, fixing formatting
AlexBulankou Aug 20, 2021
4ce8528
Fixing trailing whitespace
AlexBulankou Aug 20, 2021
20009cd
Merge branch 'terraform-google-modules:master' into alexb-part3-20210816
AlexBulankou Aug 23, 2021
9db5f04
Update examples/acm-terraform-blog-part3/README.md
AlexBulankou Aug 23, 2021
a9ebece
Update examples/acm-terraform-blog-part3/README.md
AlexBulankou Aug 23, 2021
c1e093c
Update examples/acm-terraform-blog-part3/README.md
AlexBulankou Aug 23, 2021
a36b300
Update examples/acm-terraform-blog-part3/README.md
AlexBulankou Aug 23, 2021
4687c14
Update examples/acm-terraform-blog-part3/README.md
AlexBulankou Aug 23, 2021
7960546
Update examples/acm-terraform-blog-part3/README.md
AlexBulankou Aug 23, 2021
23a9fba
Addressing comments
AlexBulankou Aug 23, 2021
d81d538
Update examples/acm-terraform-blog-part3/config-root/Kptfile
AlexBulankou Aug 23, 2021
c837458
Update examples/acm-terraform-blog-part3/config-root/Kptfile
AlexBulankou Aug 23, 2021
f95c31c
Addressing comments
AlexBulankou Aug 23, 2021
519ff21
XMerge branch 'alexb-part3-20210816' of https://github.com/AlexBulank…
AlexBulankou Aug 23, 2021
f249eb9
Merge branch 'master' into alexb-part3-20210816
AlexBulankou Aug 26, 2021
465153b
Update examples/acm-terraform-blog-part3/README.md
AlexBulankou Aug 27, 2021
5211137
Update examples/acm-terraform-blog-part3/README.md
AlexBulankou Aug 27, 2021
0a2308a
Apply suggestions from code review
AlexBulankou Aug 27, 2021
d1414c9
Addressing comments
AlexBulankou Aug 27, 2021
c8ac2a8
Addressing comments
AlexBulankou Aug 28, 2021
cb5c4ed
Addressing comments
AlexBulankou Aug 29, 2021
fa06194
Merge branch 'master' into alexb-part3-20210816
AlexBulankou Aug 30, 2021
4960aea
Update examples/acm-terraform-blog-part3/README.md
morgante Sep 2, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions examples/acm-terraform-blog-part1/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@ Subsequent articles will discuss other aspects of ACM to manage your GCP infrast

# continue in /terraform directory
cd terraform

export TF_VAR_project=$PROJECT_ID
terraform init
terraform plan -var=project=$PROJECT_ID
terraform apply -var=project=$PROJECT_ID
terraform plan
terraform apply
```
NOTE: if you get an error due to default network not being present, run `gcloud compute networks create default --subnet-mode=auto` and retry the commands.

Expand Down
2 changes: 1 addition & 1 deletion examples/acm-terraform-blog-part1/terraform/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

resource "google_gke_hub_membership" "membership" {
provider = google-beta
membership_id = "membership-hub"
membership_id = "membership-hub-${module.gke.name}"
endpoint {
gke_cluster {
resource_link = "//container.googleapis.com/${module.gke.cluster_id}"
Expand Down
21 changes: 21 additions & 0 deletions examples/acm-terraform-blog-part1/terraform/terraform.tfvars
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* 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.
*/

region = "us-central1"
zone = "us-central1-c"
sync_repo = "https://github.com/terraform-google-modules/terraform-google-kubernetes-engine.git"
sync_branch = "master"
policy_dir = "examples/acm-terraform-blog-part1/config-root"
5 changes: 0 additions & 5 deletions examples/acm-terraform-blog-part1/terraform/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -22,29 +22,24 @@ variable "project" {
variable "region" {
type = string
description = "the GCP region where the cluster will be created"
default = "us-central1"
}

variable "zone" {
type = string
description = "the GCP zone in the region where the cluster will be created"
default = "us-central1-c"
}

variable "sync_repo" {
type = string
description = "git URL for the repo which will be sync'ed into the cluster via Config Management"
default = "https://github.com/terraform-google-modules/terraform-google-kubernetes-engine.git"
}

variable "sync_branch" {
type = string
description = "the git branch in the repo to sync"
default = "master"
}

variable "policy_dir" {
type = string
description = "the root directory in the repo branch that contains the resources."
default = "examples/acm-terraform-blog-part1/config-root"
}
6 changes: 3 additions & 3 deletions examples/acm-terraform-blog-part2/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ Subsequent articles will discuss other aspects of ACM to manage your GCP infrast

# continue in /terraform directory
cd terraform

export TF_VAR_project=$PROJECT_ID
terraform init
terraform plan -var=project=$PROJECT_ID
terraform apply -var=project=$PROJECT_ID
terraform plan
terraform apply
```
NOTE: if you get an error due to default network not being present, run `gcloud compute networks create default --subnet-mode=auto` and retry the commands.

Expand Down
2 changes: 1 addition & 1 deletion examples/acm-terraform-blog-part2/terraform/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

resource "google_gke_hub_membership" "membership" {
provider = google-beta
membership_id = "membership-hub"
membership_id = "membership-hub-${module.gke.name}"
endpoint {
gke_cluster {
resource_link = "//container.googleapis.com/${module.gke.cluster_id}"
Expand Down
21 changes: 21 additions & 0 deletions examples/acm-terraform-blog-part2/terraform/terraform.tfvars
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* 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.
*/

region = "us-central1"
zone = "us-central1-c"
sync_repo = "https://github.com/terraform-google-modules/terraform-google-kubernetes-engine.git"
sync_branch = "master"
policy_dir = "examples/acm-terraform-blog-part2/config-root"
5 changes: 0 additions & 5 deletions examples/acm-terraform-blog-part2/terraform/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -22,29 +22,24 @@ variable "project" {
variable "region" {
type = string
description = "the GCP region where the cluster will be created"
default = "us-central1"
}

variable "zone" {
type = string
description = "the GCP zone in the region where the cluster will be created"
default = "us-central1-c"
}

variable "sync_repo" {
type = string
description = "git URL for the repo which will be sync'ed into the cluster via Config Management"
default = "https://github.com/terraform-google-modules/terraform-google-kubernetes-engine.git"
}

variable "sync_branch" {
type = string
description = "the git branch in the repo to sync"
default = "master"
}

variable "policy_dir" {
type = string
description = "the root directory in the repo branch that contains the resources."
default = "examples/acm-terraform-blog-part1/config-root"
}
89 changes: 89 additions & 0 deletions examples/acm-terraform-blog-part3/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# Enable ACM features with Terraform - Part 3

This is part three of the tutorial to accompany a short series of blog articles explaining how to enable [Anthos Config Management (ACM)](https://cloud.google.com/anthos/config-management) with Terraform.

In the [first part](../acm-terraform-blog-part1), we explained how to use Terraform to create a cluster and manage its config from git via [Config Sync](https://cloud.google.com/anthos-config-management/docs/config-sync-overview).

In the [second part](../acm-terraform-blog-part2) we added guard rails for the cluster configuration via [Policy Controller](https://cloud.google.com/anthos-config-management/docs/concepts/policy-controller).

In this article we'll demonstrate how, using Config Connector, you can provision your GCP cloud resources following the same Kubernetes-native model.

## Provision GCP resources

1. Set the variable for the project from [part two](../acm-terraform-blog-part2). We will re-use that project but create a new cluster since we cleaned up at the end of the first section. If you are working in a different project, enable required GCP APIs, as described in [part one](../part1/README.md).

```bash
PROJECT_ID = [PROJECT_ID]
```
1. Note that [wordpress-bundle.yaml](./config-root/wordpress-bundle) was updated to use GCP MySQL database. Also we added [configconnector.yaml](./config-root/configconnector.yaml) to initialize the instance of Config Connector add-on on the cluster.

1. Use [kpt](https://kpt.dev) to customize the `config-root` directory that will be configured as the source of the objects installed on the cluster.

```bash
kpt fn eval --include-meta-resources --image gcr.io/kpt-fn/set-project-id:v0.1 ./config-root -- "project-id=$PROJECT_ID"
kpt fn render ./config-root
```
1. Submit the updated configuration into your branch.
1. Ensure that `sync_repo` and `sync_branch` variables are updated in [terraform.tfvars](./terraform/terraform.tfvars)
1. Before running Terraform, notice the changes in [gke.tf](./terraform/gke.tf):
- We are using the `[beta-public-cluster](../modules/beta-public-cluster)` module
- `config_connector` variable is set to true
- We are using `workload-identity` module to create a Google Service Account and connect it to a Kubernetes Service Account that is running in Config Connector `cnrm-system` namespace, allowing Config Connector to create GCP resource.
1. As as in the previous part, create the cluster using Terraform:

```bash
# obtain user access credentials to use for Terraform commands
gcloud auth application-default login

# continue in /terraform directory
cd terraform
export TF_VAR_project=$PROJECT_ID
terraform init
terraform plan
terraform apply
```
NOTE: if you get an error due to the default network not being present, run `gcloud compute networks create default --subnet-mode=auto` and retry the commands.

1. To verify things have synced and Policy Controller is installed, you can again use `gcloud` to check status:

```bash
gcloud alpha container hub config-management status --project $PROJECT_ID
```

As things initialize, you may see a few transient `error: KNV1021: No CustomResourceDefinition is defined` messages. This occurs when constraints from the repo are synced before Policy Controller has had a chance to load the appropriate template from the policy library. It will eventually reconcile.

After a short time, in addition to the `Status` showing as `SYNCED` and the `Last_Synced_Token` matching the repo, there should also be a value of `INSTALLED` for `Policy_Controller`.


1. Connect your kubectl instance to the newly created cluster:

```bash
# get values from cluster that was created
export CLUSTER_ZONE=$(terraform output -raw cluster_location)
export CLUSTER_NAME=$(terraform output -raw cluster_name)

# then get creditials for it
gcloud container clusters get-credentials $CLUSTER_NAME --zone $CLUSTER_ZONE --project $PROJECT_ID

```

1. Verify that Config Connector addon is installed and configured:
```bash
kubectl wait -n cnrm-system --for=condition=Ready pod --all
```

Note: The controller Pod can take several minutes to start. Once Config Connector is installed correctly, the output is similar to the following:

```bash
pod/cnrm-controller-manager-0 condition met
```
1. It will take a while for the SQL database to be created. You can check on the status:
```bash
kubectl describe sqlinstance -n wp
```

1. Finally, validate that Wordpress powered Cloud SQL database was created:

```bash
curl -L $( kubectl get service wordpress-external -n wp -o=json | \
jq -r '.status["loadBalancer"]["ingress"][0]["ip"]')
11 changes: 11 additions & 0 deletions examples/acm-terraform-blog-part3/config-root/Kptfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
apiVersion: kpt.dev/v1
kind: Kptfile
metadata:
name: WordPress powered by Google Cloud SQL
info:
description: create a WordPress in a container and connect it to a GCP-managed MySQL database
pipeline:
mutators:
- image: gcr.io/kpt-fn/apply-setters:v0.1
configMap:
project-id: ""
22 changes: 22 additions & 0 deletions examples/acm-terraform-blog-part3/config-root/audit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Copyright 2018 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.
apiVersion: config.gatekeeper.sh/v1alpha1
kind: Config
metadata:
name: config
namespace: "gatekeeper-system"
spec:
match:
- excludedNamespaces: ["kube-system", "kube-public", "kube-node-lease", "config-management-system", "config-management-monitoring", "gatekeeper-system", "resource-group-system"]
processes: ["audit"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Copyright 2018 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.
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRestrictRoleBindings
metadata: # kpt-merge: /restrict-clusteradmin-rolebindings
name: restrict-clusteradmin-rolebindings
annotations:
# This constraint is not certified by CIS.
description: "Restricts use of the cluster-admin role."
spec:
enforcementAction: dryrun # kpt-set: ${enforcementAction}
parameters:
allowedSubjects:
- name: "system:masters"
kind: "Group"
apiGroup: "rbac.authorization.k8s.io"
restrictedRole:
name: "cluster-admin"
kind: "ClusterRole"
apiGroup: "rbac.authorization.k8s.io"
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Copyright 2018 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.
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sProhibitRoleWildcardAccess
metadata: # kpt-merge: /prohibit-role-wildcard-access
name: prohibit-role-wildcard-access
annotations:
# This constraint is not certified by CIS.
description: "Restricts use of wildcards in Roles and ClusterRoles."
spec:
enforcementAction: dryrun # kpt-set: ${enforcementAction}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Copyright 2018 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.
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sPSPPrivilegedContainer
metadata: # kpt-merge: /psp-privileged-container
name: psp-privileged-container
annotations:
# This constraint is not certified by CIS.
description: "Restricts containers with `securityContext.privileged` set to `true`."
spec:
enforcementAction: dryrun # kpt-set: ${enforcementAction}
match:
kinds:
- apiGroups:
- ''
kinds:
- Pod
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Copyright 2018 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.
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sPSPHostNamespace
metadata: # kpt-merge: /psp-host-namespace
name: psp-host-namespace
annotations:
# This constraint is not certified by CIS.
description: "Prohibits containers from running with `hostPID` or `hostIPC` set to `true`."
spec:
enforcementAction: dryrun # kpt-set: ${enforcementAction}
match:
kinds:
- apiGroups: [""]
kinds: ["Pod"]
Loading