Set Up and Configure a Google Cloud Environment— Google Challenge Lab Walkthrough
This is a walkthrough of the challenge lab from the Set Up and Configure a Cloud Environment in Google Cloud quest. It tests your ability to:
- Create and configure VPCs and subnets
- Set up a bastion host
- Set up Cloud SQL
- Deploy a GKE cluster
- Deploy an application to the cluster and connect it to the Cloud SQL instance
- Create an uptime check
- Manage access
Intro to Challenge Labs
Google provides an online learning platform called Google Cloud Skills Boost, formerly known as QwikLabs. On this platform, you can follow training courses aligned to learning paths, to particular products, or for particular solutions.
One type of learning experience on this platform is called a quest. This is where you complete a number of guided hands-on labs, and then finally complete a Challenge Lab. The challenge lab differs from the other labs in that goals are specified, but very little guidance on how to achieve the goals is given.
I occasionally create walkthroughs of these challenge labs. The goal is not to help you cheat your way through the challenge labs! But rather:
- To show you what I believe to be an ideal route through the lab.
- To help you with particular gotchas or blockers that are preventing you from completing the lab on your own.
If you’re looking for help with challenge lab, then you’ve come to the right place. But I strongly urge you to work your way through the quest first, and to try the lab on your own, before reading further!
With all these labs, there are always many ways to go about solving the problem. I generally like to solve them using the Cloud Shell, since I can then document a more repeatable and programmatic approach. But of course, you can use the Cloud Console too.
Overview of this Lab
This was fun. There’s quite a bit to do in the time allotted.
We’re going to build this environment:
Objectives
- Create a development VPC with three subnets.
- Create a production VPC with three subnets.
- Create a bastion that is connected to both VPCs.
- Create a development Cloud SQL Instance and connect and prepare the WordPress environment.
- Create a Kubernetes cluster in the development VPC for WordPress.
- Prepare the Kubernetes cluster for the WordPress environment.
- Create a WordPress deployment using the supplied configuration.
- Enable an uptime check in Cloud Monitoring.
- Provide access for an additional engineer.
We’re also given some standards to follow. As with all challenge labs, it’s important to adhere to the standards, otherwise the lab won’t recognise step completion.
- Create all resources in the specified region and zone, unless otherwise directed.
- Naming is normally
team-resource
, e.g. an instance could be namedkraken-webserver1
- Allocate cost effective resource sizes. Use compute machines of type
e2-medium
unless told otherwise.
My Approach
Although the tasks are not particularly difficult, I found it quite challenging to get this done in time. I finished it with about 16 seconds to spare! Of course, I spent a lot of that time documenting my approach, capturing screenshots, etc. So if I did it again using the automation I built along the way, I’m sure I would do it much more quickly.
One of the challenges is that provisioning of Cloud SQL and of GKE takes quite a bit of time.
As usual, I try to automate with Cloud CLI as much as possible. Of course, you can use the Console if you prefer.
Prep
Let’s start by defining some variables we can use throughout this challenge. Do this from the Cloud Shell:
gcloud auth list
region=us-east1
zone=us-east1-b
# Dev network
vpc_dev=griffin-dev-vpc
sn_dev_wp=griffin-dev-wp
sn_dev_wp_cidr=192.168.16.0/20
sn_dev_mgmt=griffin-dev-mgmt
sn_dev_mgmt_cidr=192.168.32.0/20
# Prod network
vpc_prod=griffin-prod-vpc
sn_prod_wp=griffin-prod-wp
sn_prod_wp_cidr=192.168.48.0/20
sn_prod_mgmt=griffin-prod-mgmt
sn_prod_mgmt_cidr=192.168.64.0/20
# default machine size
mach=e2-medium
# Dev GKE cluster name
gke=griffin-dev
# The user we need to give access to.
user2=supply-your-user-email
gcloud config set compute/region $region
gcloud config set compute/zone $zone
Substitute for any variables you’ve been given, in your instance of the challenge.
Setup the Networks
Here we have to create two VPC networks: one for Dev
and one for Prod
. Both will contain two subnets.
# First, the Dev network
gcloud compute networks create $vpc_dev --subnet-mode=custom --mtu=1460 --bgp-routing-mode=regional
gcloud compute networks subnets create $sn_dev_wp \
--range=$sn_dev_wp_cidr --stack-type=IPV4_ONLY \
--network=$vpc_dev --region=$region
gcloud compute networks subnets create $sn_dev_mgmt \
--range=$sn_dev_mgmt_cidr --stack-type=IPV4_ONLY \
--network=$vpc_dev --region=$region
# Then the Prod network
gcloud compute networks create $vpc_prod --subnet-mode=custom --mtu=1460 --bgp-routing-mode=regional
gcloud compute networks subnets create $sn_prod_wp \
--range=$sn_prod_wp_cidr --stack-type=IPV4_ONLY \
--network=$vpc_prod --region=$region
gcloud compute networks subnets create $sn_prod_mgmt \
--range=$sn_prod_mgmt_cidr --stack-type=IPV4_ONLY \
--network=$vpc_prod --region=$region
# And firewall rules, so we can connect to our bastion
gcloud compute firewall-rules create fw-ssh-dev --network $vpc_dev --allow tcp:22,tcp:3389,icmp
gcloud compute firewall-rules create fw-ssh-prod --network $vpc_prod --allow tcp:22,tcp:3389,icmp
Create the Bastion Host
The purpose of a bastion host is to allow specific inbound connectivity to your network, but without directly exposing your internal resources. For example, to provide SSH connectivity to a private instance.
The important thing to note here is that this bastion host needs to connect to both VPCs. So you need to configure two network interfaces.
gcloud compute instances create bastion \
--project=$prj \
--zone=$zone \
--machine-type=$mach \
--network-interface=network-tier=PREMIUM,stack-type=IPV4_ONLY,subnet=$sn_dev_mgmt \
--network-interface=network-tier=PREMIUM,stack-type=IPV4_ONLY,subnet=$sn_prod_mgmt \
--metadata=enable-oslogin=true \
--scopes=https://www.googleapis.com/auth/devstorage.read_only,https://www.googleapis.com/auth/logging.write,https://www.googleapis.com/auth/monitoring.write,https://www.googleapis.com/auth/servicecontrol,https://www.googleapis.com/auth/service.management.readonly,https://www.googleapis.com/auth/trace.append
Setup a CloudSQL MySQL Instance
First, I create a regional (highly available) Cloud SQL instance and connect to it from Cloud Shell:
gcloud sql instances create griffin-dev-db \
--database-version=MYSQL_8_0_31 \
--tier=db-n1-standard-1 \
--region=$region \
--edition=enterprise \
--root-password=<whatever!>
# Now connect to it (from Cloud Shell)
gcloud sql connect griffin-dev-db --user=root --quiet
Now we’ll run some DB setup, as given in the instructions:
CREATE DATABASE wordpress;
CREATE USER "wp_user"@"%" IDENTIFIED BY "stormwind_rules";
GRANT ALL PRIVILEGES ON wordpress.* TO "wp_user"@"%";
FLUSH PRIVILEGES;
Finally, exit from the SQL client back to Cloud Shell:
exit
Setup Google Kubernetes Engine (GKE)
We’re told we need a 2-node zonal cluster, provisioned in the dev
VPC.
gcloud container clusters create $gke \
--network=$vpc_dev --subnetwork=$sn_dev_wp \
--num-nodes=2 \
--zone $zone \
--machine-type=$mach \
--scopes "https://www.googleapis.com/auth/projecthosting,storage-rw"
It takes about 5 minutes to provision the GKE cluster.
Now we need to download some pre-prepared yaml
files, which we’ll copy from a GCS bucket. I create a clean directory to store these files:
mkdir wp && cd $_
gsutil cp gs://cloud-training/gsp321/wp-k8s/* .
Now we’re told to edit wp-env.yaml
and substitute the username and password provided, in the Secret
.
So the final yaml looks like this:
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: wordpress-volumeclaim
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 200Gi
---
apiVersion: v1
kind: Secret
metadata:
name: database
type: Opaque
stringData:
username: wp_user
password: stormwind_rules
Then we need to generate a service account key and use it to create a Kubernetes secret for the Cloud SQL instance credentials. We’re told how to do this:
gcloud iam service-accounts keys create key.json \
--iam-account=cloud-sql-proxy@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com
kubectl create secret generic cloudsql-instance-credentials \
--from-file key.json
Now we’re ready to apply our wp-env.yaml
, in order to create our PVC and secret:
kubectl apply -f wp-env.yaml
Next, we need to update wp-deployment.yaml
and replace YOUR_SQL_INSTANCE
with our instance connection name. It will be in the format <project>:region:griffin-dev-db
.
Now we can create the deployment
and the service
:
kubectl apply -f wp-deployment.yaml
kubectl apply -f wp-service.yaml
You can check the status of the service and its associated load balancer creation:
kubectl get services
Here’s a useful command for retrieving the external IP address of the newly created LB:
kubectl get svc wordpress -o=jsonpath="{.status.loadBalancer.ingress[0].ip}"
Fire up this IP address in the browser to check that WordPress is running.
I don’t think you need to explicitly set up a firewall rule to access the LB, but just in case you do:
gcloud compute firewall-rules create wp-service-lb-fw \
--direction=INGRESS \
--network=$vpc_dev \
--allow tcp:80 --source-ranges="0.0.0.0/0" \
--destination-ranges="<enter-ip>/32"
Set Up an Uptime Check in Cloud Monitoring
We’re told to create an uptime check. I’ll do this in the Console. Navigate to Monitoring. Create an Uptime Check. Configure it as follows:
- Check type: HTTP.
- Resource type: URL.
- Hostname: provide the LB external IP address.
- Path:
/
And create.
Grant Access to User 2
We’re told that make User 2 an Editor of our project.
I do this by exporting the existing IAM policy, adding the new user to it, and then applying the new policy. From Cloud Shell:
cd ..
gcloud projects get-iam-policy $prj --format=json > policy.json
Open this file in your editor, find the entry for roles/editor
, and add a new member for your user 2, by adding the line user:the-email-address
.
Now apply the amended policy:
gcloud projects set-iam-policy $prj policy.json
Done!
And that’s it! Hope you found this walkthrough useful.
Before You Go
- Please share this with anyone that you think will be interested. It might help them, and it really helps me!
- Feel free to leave a comment 💬.
- Follow and subscribe, so you don’t miss my content. Go to my Profile Page, and click on these icons: