Allow GKE
Duration: 5 min | Persona: Org Admin
In this section, you will enable and grant the appropriate APIs in the Tenant project and the IAM role for the Tenant project’s service account. This will allow later this service account to provision the GKE cluster.
Define variables:
WORK_DIR=~/
source ${WORK_DIR}acm-workshop-variables.sh
Define roles
Define the container.admin
, iam.serviceAccountAdmin
, resourcemanager.projectIamAdmin
, iam.serviceAccountUser
and serviceusage.serviceUsageConsumer
roles with an IAMPolicyMember
resource for the Tenant project’s service account:
cat <<EOF > ${WORK_DIR}$HOST_PROJECT_DIR_NAME/projects/$TENANT_PROJECT_ID/container-admin.yaml
apiVersion: iam.cnrm.cloud.google.com/v1beta1
kind: IAMPolicyMember
metadata:
name: container-admin-${TENANT_PROJECT_ID}
namespace: config-control
annotations:
config.kubernetes.io/depends-on: iam.cnrm.cloud.google.com/namespaces/config-control/IAMServiceAccount/${TENANT_PROJECT_ID},resourcemanager.cnrm.cloud.google.com/namespaces/config-control/Project/${TENANT_PROJECT_ID}
spec:
memberFrom:
serviceAccountRef:
name: ${TENANT_PROJECT_ID}
role: roles/container.admin
resourceRef:
kind: Project
external: projects/${TENANT_PROJECT_ID}
EOF
cat <<EOF > ${WORK_DIR}$HOST_PROJECT_DIR_NAME/projects/$TENANT_PROJECT_ID/service-account-admin.yaml
apiVersion: iam.cnrm.cloud.google.com/v1beta1
kind: IAMPolicyMember
metadata:
name: service-account-admin-${TENANT_PROJECT_ID}
namespace: config-control
annotations:
config.kubernetes.io/depends-on: iam.cnrm.cloud.google.com/namespaces/config-control/IAMServiceAccount/${TENANT_PROJECT_ID},resourcemanager.cnrm.cloud.google.com/namespaces/config-control/Project/${TENANT_PROJECT_ID}
spec:
memberFrom:
serviceAccountRef:
name: ${TENANT_PROJECT_ID}
role: roles/iam.serviceAccountAdmin
resourceRef:
kind: Project
external: projects/${TENANT_PROJECT_ID}
EOF
cat <<EOF > ${WORK_DIR}$HOST_PROJECT_DIR_NAME/projects/$TENANT_PROJECT_ID/iam-admin.yaml
apiVersion: iam.cnrm.cloud.google.com/v1beta1
kind: IAMPolicyMember
metadata:
name: iam-admin-${TENANT_PROJECT_ID}
namespace: config-control
annotations:
config.kubernetes.io/depends-on: iam.cnrm.cloud.google.com/namespaces/config-control/IAMServiceAccount/${TENANT_PROJECT_ID},resourcemanager.cnrm.cloud.google.com/namespaces/config-control/Project/${TENANT_PROJECT_ID}
spec:
memberFrom:
serviceAccountRef:
name: ${TENANT_PROJECT_ID}
role: roles/resourcemanager.projectIamAdmin
resourceRef:
kind: Project
external: projects/${TENANT_PROJECT_ID}
EOF
cat <<EOF > ${WORK_DIR}$HOST_PROJECT_DIR_NAME/projects/$TENANT_PROJECT_ID/service-account-user.yaml
apiVersion: iam.cnrm.cloud.google.com/v1beta1
kind: IAMPolicyMember
metadata:
name: service-account-user-${TENANT_PROJECT_ID}
namespace: config-control
annotations:
config.kubernetes.io/depends-on: iam.cnrm.cloud.google.com/namespaces/config-control/IAMServiceAccount/${TENANT_PROJECT_ID},resourcemanager.cnrm.cloud.google.com/namespaces/config-control/Project/${TENANT_PROJECT_ID}
spec:
memberFrom:
serviceAccountRef:
name: ${TENANT_PROJECT_ID}
role: roles/iam.serviceAccountUser
resourceRef:
kind: Project
external: projects/${TENANT_PROJECT_ID}
EOF
cat <<EOF > ${WORK_DIR}$HOST_PROJECT_DIR_NAME/projects/$TENANT_PROJECT_ID/serviceusage-consumer.yaml
apiVersion: iam.cnrm.cloud.google.com/v1beta1
kind: IAMPolicyMember
metadata:
name: serviceusage-consumer-${TENANT_PROJECT_ID}
namespace: config-control
annotations:
config.kubernetes.io/depends-on: iam.cnrm.cloud.google.com/namespaces/config-control/IAMServiceAccount/${TENANT_PROJECT_ID},resourcemanager.cnrm.cloud.google.com/namespaces/config-control/Project/${TENANT_PROJECT_ID}
spec:
memberFrom:
serviceAccountRef:
name: ${TENANT_PROJECT_ID}
role: roles/serviceusage.serviceUsageConsumer
resourceRef:
kind: Project
external: projects/${TENANT_PROJECT_ID}
EOF
Define APIs
Define the Cloud Resources Manager API Service
resource for the Tenant project:
cat <<EOF > ${WORK_DIR}$HOST_PROJECT_DIR_NAME/projects/$TENANT_PROJECT_ID/cloudresourcemanager-service.yaml
apiVersion: serviceusage.cnrm.cloud.google.com/v1beta1
kind: Service
metadata:
annotations:
cnrm.cloud.google.com/deletion-policy: "abandon"
cnrm.cloud.google.com/disable-dependent-services: "false"
config.kubernetes.io/depends-on: resourcemanager.cnrm.cloud.google.com/namespaces/config-control/Project/${TENANT_PROJECT_ID}
name: ${TENANT_PROJECT_ID}-cloudresourcemanager
namespace: config-control
spec:
projectRef:
name: ${TENANT_PROJECT_ID}
resourceID: cloudresourcemanager.googleapis.com
EOF
Define the GKE API Service
resource for the Tenant project:
cat <<EOF > ${WORK_DIR}$HOST_PROJECT_DIR_NAME/projects/$TENANT_PROJECT_ID/container-service.yaml
apiVersion: serviceusage.cnrm.cloud.google.com/v1beta1
kind: Service
metadata:
annotations:
cnrm.cloud.google.com/deletion-policy: "abandon"
cnrm.cloud.google.com/disable-dependent-services: "false"
config.kubernetes.io/depends-on: resourcemanager.cnrm.cloud.google.com/namespaces/config-control/Project/${TENANT_PROJECT_ID}
name: ${TENANT_PROJECT_ID}-container
namespace: config-control
spec:
projectRef:
name: ${TENANT_PROJECT_ID}
resourceID: container.googleapis.com
EOF
Define the DNS API Service
resource for the Tenant project in order to leverage the Cloud DNS feature of GKE:
cat <<EOF > ${WORK_DIR}$HOST_PROJECT_DIR_NAME/projects/$TENANT_PROJECT_ID/dns-service.yaml
apiVersion: serviceusage.cnrm.cloud.google.com/v1beta1
kind: Service
metadata:
annotations:
cnrm.cloud.google.com/deletion-policy: "abandon"
cnrm.cloud.google.com/disable-dependent-services: "false"
config.kubernetes.io/depends-on: resourcemanager.cnrm.cloud.google.com/namespaces/config-control/Project/${TENANT_PROJECT_ID}
name: ${TENANT_PROJECT_ID}-dns
namespace: config-control
spec:
projectRef:
name: ${TENANT_PROJECT_ID}
resourceID: dns.googleapis.com
EOF
Later in the workshop, you can optionally leverage the GKE Security Posture features (Scan workloads configurations and Scan container images for known vulnerabilities) in order to scan the configurations of your GKE workloads. Define the GKE Security Posture API Service
resource for the Tenant project:
cat <<EOF > ${WORK_DIR}$HOST_PROJECT_DIR_NAME/projects/$TENANT_PROJECT_ID/containersecurity-service.yaml
apiVersion: serviceusage.cnrm.cloud.google.com/v1beta1
kind: Service
metadata:
annotations:
cnrm.cloud.google.com/deletion-policy: "abandon"
cnrm.cloud.google.com/disable-dependent-services: "false"
config.kubernetes.io/depends-on: resourcemanager.cnrm.cloud.google.com/namespaces/config-control/Project/${TENANT_PROJECT_ID}
name: ${TENANT_PROJECT_ID}-containersecurity
namespace: config-control
spec:
projectRef:
name: ${TENANT_PROJECT_ID}
resourceID: containersecurity.googleapis.com
EOF
Deploy Kubernetes manifests
cd ${WORK_DIR}$HOST_PROJECT_DIR_NAME/
git add . && git commit -m "Allow GKE and GKE Security Posture for Tenant project" && git push origin main
Check deployments
graph TD; IAMPolicyMember-.->IAMServiceAccount IAMPolicyMember-.->Project IAMPolicyMember-.->IAMServiceAccount IAMPolicyMember-.->Project IAMPolicyMember-.->IAMServiceAccount IAMPolicyMember-.->Project IAMPolicyMember-.->IAMServiceAccount IAMPolicyMember-.->Project IAMPolicyMember-.->IAMServiceAccount IAMPolicyMember-.->Project Service-.->Project Service-.->Project Service-.->Project
List the Kubernetes resources managed by Config Sync in Config Controller for the Host project configs repository:
Run this command and click on this link:
echo -e "https://console.cloud.google.com/kubernetes/config_management/packages?project=${HOST_PROJECT_ID}"
Wait until you see the Sync status
column as Synced
and the Reconcile status
column as Current
.
Run this command:
gcloud alpha anthos config sync repo describe \
--project $HOST_PROJECT_ID \
--managed-resources all \
--sync-name root-sync \
--sync-namespace config-management-system
Wait and re-run this command above until you see "status": "SYNCED"
. All the managed_resources
listed should have STATUS: Current
too.
List the GitHub runs for the Host project configs repository:
cd ${WORK_DIR}$HOST_PROJECT_DIR_NAME && gh run list
List the Google Cloud resources created:
gcloud services list \
--enabled \
--project ${TENANT_PROJECT_ID} \
| grep -E 'container'
gcloud projects get-iam-policy $TENANT_PROJECT_ID \
--filter="bindings.members:${TENANT_PROJECT_SA_EMAIL}" \
--flatten="bindings[].members" \
--format="table(bindings.role)"
Wait and re-run this command above until you see the resources created.