* [have fun with them](https://cloudplatform.googleblog.com/2016/06/filtering-and-formatting-fun-with.html) * [projections](https://cloud.google.com/sdk/gcloud/reference/topic/projections) * [filters](https://cloud.google.com/sdk/gcloud/reference/topic/filters) * [resource-keys](https://cloud.google.com/sdk/gcloud/reference/topic/resource-keys) * [scripting-gcloud](https://cloud.google.com/sdk/docs/scripting-gcloud) * http://cloudplatform.googleblog.com/2018/03/introducing-GCPs-new-interactive-CLI.html * https://medium.com/@Joachim8675309/getting-started-with-gcloud-sdk-part-1-114924737 * https://medium.com/@Joachim8675309/getting-started-with-gcloud-sdk-part-2-4d049a656f1a ## auth ``` gcloud auth list gcloud auth login gcloud auth activate-service-account --key-file=sa_key.json ``` kubectl uses OAuth token generated by * `gcloud config config-helper --format json` * `gcloud config config-helper --format='value(credential.access_token)'` * `gcloud auth print-access-token` generates new token ## info ``` gcloud info --format flattened export PROJECT=$(gcloud info --format='value(config.project)') ``` ## zones To return a list of zones given a region ``` gcloud compute zones list --filter=region:us-central1 ``` ## projects ``` # various way to get project_id PROJECT_ID=$(gcloud config get-value core/project) PROJECT_ID=$(gcloud config list project --format='value(core.project)') PROJECT_ID=$(gcloud info --format='value(config.project)') # get project_number gcloud projects list --filter="name:${project_id}" --format='value(project_number)' ``` ## billing ``` gcloud beta billing accounts list gcloud organizations list ``` ## switch gcloud context with gcloud config ``` gcloud config list gcloud config configurations list gcloud config set account pythonrocksk8s201702@gmail.com gcloud config set project salt-163215 gcloud config set compute/region us-west1 gcloud config set compute/zone us-west1-a alias demo='gcloud config set account pythonrocksk8s201702@gmail.com && gcloud config set project salt-163215 && gcloud config set compute/region us-west1 && gcloud config set compute/zone us-west1-a' cluster=$(gcloud config get-value container/cluster 2> /dev/null) zone=$(gcloud config get-value compute/zone 2> /dev/null) project=$(gcloud config get-value core/project 2> /dev/null) # switch project based on the name gcloud config set project $(gcloud projects list --filter='name:wordpress-dev' --format='value(project_id)') # get the GKE cluster endpoint gcloud container clusters describe mycluster --zone $(gcloud config get-value compute/zone) --format='get(endpoint)' ``` ``` command -v gcloud >/dev/null 2>&1 || { \ echo >&2 "I require gcloud but it's not installed. Aborting."; exit 1; } REGION=$(gcloud config get-value compute/region) if [[ -z "${REGION}" ]]; then echo "https://cloud.google.com/compute/docs/regions-zones/changing-default-zone-region" 1>&2 echo "gcloud cli must be configured with a default region." 1>&2 echo "run 'gcloud config set compute/region REGION'." 1>&2 echo "replace 'REGION' with the region name like us-west1." 1>&2 exit 1; fi ``` ## service account and IAM * [When granting IAM roles, you can treat a service account either as a resource or as an identity](https://cloud.google.com/iam/docs/granting-roles-to-service-accounts) ``` # creaate jenkins sa gcloud iam service-accounts create jenkins --display-name jenkins export SA_EMAIL=$(gcloud iam service-accounts list \ --filter="displayName:jenkins" --format='value(email)') export PROJECT=$(gcloud info --format='value(config.project)') gcloud projects add-iam-policy-binding $PROJECT \ --role roles/storage.admin --member serviceAccount:$SA_EMAIL gcloud projects add-iam-policy-binding $PROJECT --role roles/compute.instanceAdmin.v1 \ --member serviceAccount:$SA_EMAIL gcloud projects add-iam-policy-binding $PROJECT --role roles/compute.networkAdmin \ --member serviceAccount:$SA_EMAIL gcloud projects add-iam-policy-binding $PROJECT --role roles/compute.securityAdmin \ --member serviceAccount:$SA_EMAIL gcloud projects add-iam-policy-binding $PROJECT --role roles/iam.serviceAccountActor \ --member serviceAccount:$SA_EMAIL # create service account key gcloud iam service-accounts keys create jenkins-sa.json --iam-account $SA_EMAIL ``` ``` gcloud iam service-accounts keys list --iam-account=vault-admin@.iam.gserviceaccount.com gcloud projects get-iam-policy gcloud iam service-accounts list gcloud iam service-accounts get-iam-policy # get the compute engine account gcloud iam service-accounts list --filter='email ~ [0-9]*-compute@.*' --format='table(email)' # add role to service account gcloud iam service-accounts add-iam-policy-binding infrastructure@retviews-154908.iam.gserviceaccount.com --member='serviceAccount:infrastructure@retviews-154908.iam.gserviceaccount.com' --role='roles/iam.serviceAccountActor' ``` ``` COMPUTE_ENGINE_SA_EMAIL=$(gcloud iam service-accounts list --filter="name:Compute Engine default service account" --format "value(email)") gsutil iam ch serviceAccount:${COMPUTE_ENGINE_SA_EMAIL}:objectViewer gs://bucket-name ``` ## app engine * https://medium.com/google-cloud/app-engine-project-cleanup-9647296e796a ## cloud build ``` # user defined gcloud builds submit --config=cloudbuild.yaml --substitutions=_BRANCH_NAME=foo,_BUILD_NUMBER=1 . # override built in TAG_NAME gcloud builds submit --config=cloudbuild.yaml --substitutions=TAG_NAME=v1.0.1 ``` ## kms * [cloud-encrypt-with-kms](https://codelabs.developers.google.com/codelabs/cloud-encrypt-with-kms/#0) * [Integrated with cloud build](https://cloud.google.com/cloud-build/docs/securing-builds/use-encrypted-secrets-credentials) ``` # list all keyrings gcloud kms keyrings list --location global # list all keys in my_key_ring gcloud kms keys list --keyring my_key_ring --location global # grant KMS IAM permission to a sv account $USER_EMAIL gcloud kms keyrings add-iam-policy-binding $KEYRING_NAME \ --location global \ --member user:$USER_EMAIL \ --role roles/cloudkms.admin gcloud kms keyrings add-iam-policy-binding $KEYRING_NAME \ --location global \ --member user:$USER_EMAIL \ --role roles/cloudkms.admin # Encrypt and Decrypt in REST API curl -v "https://cloudkms.googleapis.com/v1/projects/$DEVSHELL_PROJECT_ID/locations/global/keyRings/$KEYRING_NAME/cryptoKeys/$CRYPTOKEY_NAME:encrypt" \ -d "{\"plaintext\":\"$PLAINTEXT\"}" \ -H "Authorization:Bearer $(gcloud auth application-default print-access-token)"\ -H "Content-Type:application/json" \ | jq .ciphertext -r > 1.encrypted curl -v "https://cloudkms.googleapis.com/v1/projects/$DEVSHELL_PROJECT_ID/locations/global/keyRings/$KEYRING_NAME/cryptoKeys/$CRYPTOKEY_NAME:decrypt" \ -d "{\"ciphertext\":\"$(cat 1.encrypted)\"}" \ -H "Authorization:Bearer $(gcloud auth application-default print-access-token)"\ -H "Content-Type:application/json" \ | jq .plaintext -r | base64 -d ``` ## gcloud command for creating an instance? from web console ``` gcloud beta compute --project=victory-demo-dev instances create micro1 --zone=us-west1-a --machine-type=f1-micro --subnet=default --network-tier=PREMIUM --maintenance-policy=MIGRATE --service-account=398028291895-compute@developer.gserviceaccount.com --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 --min-cpu-platform=Automatic --image=debian-9-stretch-v20180510 --image-project=debian-cloud --boot-disk-size=10GB --boot-disk-type=pd-standard --boot-disk-device-name=micro1 ``` ## instances, template, target-pool and instance group ``` cat << EOF > startup.sh #! /bin/bash apt-get update apt-get install -y nginx service nginx start sed -i -- 's/nginx/Google Cloud Platform - '"\$HOSTNAME"'/' /var/www/html/index.nginx-debian.html EOF gcloud compute instance-templates create nginx-template --metadata-from-file startup-script=startup.sh gcloud compute target-pools create nginx-pool gcloud compute instance-groups managed create nginx-group \ --base-instance-name nginx \ --size 2 \ --template nginx-template \ --target-pool nginx-pool ``` ### MIG with startup and shutdown scripts https://cloud.google.com/vpc/docs/special-configurations#multiple-natgateways ``` gsutil cp gs://nat-gw-template/startup.sh . gcloud compute instance-templates create nat-1 \ --machine-type n1-standard-2 --can-ip-forward --tags natgw \ --metadata-from-file=startup-script=startup.sh --address $nat_1_ip gcloud compute instance-templates create nat-2 \ --machine-type n1-standard-2 --can-ip-forward --tags natgw \ --metadata-from-file=startup-script=startup.sh --address $nat_2_ip ``` ### route tag the instances with `no-ips` ``` gcloud compute instances add-tags existing-instance --tags no-ip gcloud compute routes create no-ip-internet-route \ --network custom-network1 \ --destination-range 0.0.0.0/0 \ --next-hop-instance nat-gateway \ --next-hop-instance-zone us-central1-a \ --tags no-ip --priority 800 ``` ## layer 3 network lb ``` gcloud compute firewall-rules create www-firewall --allow tcp:80 gcloud compute forwarding-rules create nginx-lb \ --region us-central1 \ --ports=80 \ --target-pool nginx-pool gcloud compute forwarding-rules list ``` ## layer 7 http lb * https://cloud.google.com/solutions/scalable-and-resilient-apps ``` gcloud compute http-health-checks create http-basic-check gcloud compute instance-groups managed \ set-named-ports nginx-group \ --named-ports http:80 gcloud compute backend-services create nginx-backend \ --protocol HTTP --http-health-checks http-basic-check --global gcloud compute backend-services add-backend nginx-backend \ --instance-group nginx-group \ --instance-group-zone us-central1-a \ --global gcloud compute url-maps create web-map \ --default-service nginx-backend gcloud compute target-http-proxies create http-lb-proxy \ --url-map web-map gcloud compute forwarding-rules create http-content-rule \ --global \ --target-http-proxy http-lb-proxy \ --ports 80 gcloud compute forwarding-rules list ``` ## forwarding-rules ``` gcloud compute forwarding-rules list --filter=$(dig +short ) gcloud compute forwarding-rules describe my-forwardingrule --region us-central1 gcloud compute forwarding-rules describe my-http-forwardingrule --global ``` ## address ``` gcloud compute addresses describe https-lb --global --format json # list all IP addresses gcloud projects list --format='value(project_id)' | xargs -I {} gcloud compute addresses list --format='value(address)' --project {} 2>/dev/null | sort | uniq -c ``` ## compute engine image ``` gcloud compute images list --filter=name:debian --uri https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/debian-8-jessie-v20180109 https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/debian-9-stretch-v20180105 ``` ## list an instance * [filters](https://cloud.google.com/sdk/gcloud/reference/topic/filters) * [resource-keys](https://cloud.google.com/sdk/gcloud/reference/topic/resource-keys) ``` gcloud compute instances list --filter="zone:us-central1-a" gcloud compute instances list --project=dev --filter="name~^es" gcloud compute instances list --project=dev --filter=name:kafka --format="value(name,INTERNAL_IP)" gcloud compute instances list --filter=tags:kafka-node gcloud compute instances list --filter='machineType:g1-small' ``` ## move instance `gcloud compute instances move --destination-zone=us-central1-a --zone=us-central1-c` ## ssh & scp ``` #--verbosity=debug is great for debugging, showing the SSH command # the following is a real word example for running a bastion server that talks to a GKE cluster (master authorized network) gcloud compute ssh --verbosity=debug --command "kubectl get nodes" gcloud compute scp --recurse ../manifest : ``` ### ssh port forwarding for elasticsearch ``` gcloud compute --project "foo" ssh --zone "us-central1-c" "elasticsearch-1" --ssh-flag="-L localhost:9200:localhost:9200" ``` The 2nd `localhost` is relative to elasticsearch-1` ### generate ssh config ``` gcloud compute config-ssh ``` ## serial port debug * https://cloud.google.com/compute/docs/instances/interacting-with-serial-console ## disk snapshot ``` gcloud compute disks snapshot kafka-data1-1 --async --snapshot-names=kafka-data-1 --project project_a --zone us-west1-a Use [gcloud compute operations describe URI] command to check the status of the operation(s). ``` ## regional disk ``` gcloud beta compute instance attach-disk micro1 --disk pd-west1 --disk-scope regional ``` ## debugging ``` gcloud compute instances list --log-http ``` ## instance level metadata ``` curl -s "http://metadata.google.internal/computeMetadata/v1/instance/?recursive=true&alt=text" -H "Metadata-Flavor: Google" leader=$(curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/leader" -H "Metadata-Flavor: Google") ``` ## project level metadata ``` gcloud compute project-info describe ``` ## GCP managed ssl certificate ``` gcloud beta compute ssl-certificates create example-mydomain --domains example.mydomain.com gcloud beta compute ssl-certificates list gcloud beta compute ssl-certificates describe example-mydomain # It takes 30mins+ to provision the TLS, one of conditions is the target-https-proxies needs to be associated with the cert. gcloud beta compute target-https-proxies list ``` ## StackDriver logging ``` gcloud logging read "timestamp >= \"2018-04-19T00:30:00Z\" and logName=projects/${project_id}/logs/requests and resource.type=http_load_balancer" --format="csv(httpRequest.remoteIp,httpRequest.requestUrl,timestamp)" --project=${project_id} ``` ## Enable Service ``` # chain gcloud services enable cloudapis.googleapis.com && \ cloudresourcemanager.googleapis.com && \ compute.googleapis.com # or not chain gcloud services enable container.googleapis.com gcloud services enable containerregistry.googleapis.com gcloud services enable cloudbuild.googleapis.com gcloud services enable iam.googleapis.com gcloud services enable logging.googleapis.com gcloud services enable monitoring.googleapis.com gcloud services enable storage-api.googleapis.com gcloud services enable storage-component.googleapis.com gcloud services enable sourcerepo.googleapis.com ``` ``` function enable-service() { SERVICE=$1 if [[ $(gcloud services list --format="value(serviceConfig.name)" \ --filter="serviceConfig.name:$SERVICE" 2>&1) != \ "$SERVICE" ]]; then echo "Enabling $SERVICE" gcloud services enable $SERVICE else echo "$SERVICE is already enabled" fi } enable-service container.googleapis.com ``` ## Client libraries you can use to connect to Google APIs * https://medium.com/google-cloud/simple-google-api-auth-samples-for-service-accounts-installed-application-and-appengine-da30ee4648 ## chaining gcloud commands ``` gcloud compute forwarding-rules list --format 'value(NAME)' \ | xargs -I {} gcloud compute forwarding-rules delete {} --region us-west1 -q gcloud projects list --format='value(project_id)' \ | xargs -I {} gcloud compute addresses list --format='value(address)' --project {} 2>/dev/null | sort | uniq -c gcloud compute instances list --filter=elasticsearch --format='value(NAME)' \ | xargs -I {} -p gcloud compute instances stop {} gcloud compute instances list --filter=elasticsearch --format='value(INTERNAL_IP)' \ | xargs -I {} ssh {} "sudo chef-client" # delete non default routes gcloud compute routes list --filter="NOT network=default" --format='value(NAME)' \ | xargs -I {} gcloud compute routes delete -q {} ``` ## one liner to purge GCR images given a date ``` DATE=2018-10-01 IMAGE=/ gcloud container images list-tags gcr.io/$IMAGE --limit=unlimited --sort-by=TIMESTAMP \ --filter="NOT tags:* AND timestamp.datetime < '${DATE}'" --format='get(digest)' | \ while read digest;do gcloud container images delete -q --force-delete-tags gcr.io/$IMAGE@$digest ;done ```