From 850296ac39e9bd021752f9d122dbdff992bf5e3a Mon Sep 17 00:00:00 2001 From: Bhaskar Singhal Date: Fri, 15 Mar 2024 07:36:21 +0000 Subject: [PATCH 1/2] feat: add support for make it mine and deploy via cloudbuild trigger --- cloudbuild.yaml | 20 ++++++++ deploy_solution.sh | 96 ++++++++++++++++++++++++++++++++++++++ deploy_via_trigger.sh | 105 ++++++++++++++++++++++++++++++++++++++++++ roles.txt | 16 +++++++ tutorial.md | 85 ++++++++++++++++++++++++++++++++++ 5 files changed, 322 insertions(+) create mode 100644 cloudbuild.yaml create mode 100755 deploy_solution.sh create mode 100755 deploy_via_trigger.sh create mode 100644 roles.txt create mode 100644 tutorial.md diff --git a/cloudbuild.yaml b/cloudbuild.yaml new file mode 100644 index 00000000..a69cda17 --- /dev/null +++ b/cloudbuild.yaml @@ -0,0 +1,20 @@ +# Copyright 2024 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. +steps: +- name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' + entrypoint: 'bash' + args: ['./deploy_via_trigger.sh', '-p$PROJECT_ID'] +serviceAccount: 'projects/$PROJECT_ID/serviceAccounts/cloudbuild-trigger-default@$PROJECT_ID.iam.gserviceaccount.com' +options: + logging: CLOUD_LOGGING_ONLY diff --git a/deploy_solution.sh b/deploy_solution.sh new file mode 100755 index 00000000..3db3b951 --- /dev/null +++ b/deploy_solution.sh @@ -0,0 +1,96 @@ +#!/bin/bash +# Copyright 2023 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. +set -o pipefail + +handle_error() { + local exit_code=$? + exit $exit_code +} +trap 'handle_error' ERR + +SOLUTION_ID="ecommerce-platform-serverless" + +echo "Fetching Project ID" +PROJECT_ID=$(gcloud config get project) +echo "Project ID is ${PROJECT_ID}" + +# Iterate over the infra manager location to identify the deployment +# currently one deployment per project is only supported +# in future if multiple deployments are supported per project this will need to change +IM_SUPPORTED_REGIONS=("us-central1" "europe-west1" "asia-east1") + +for REGION in "${IM_SUPPORTED_REGIONS[@]}"; do + DEPLOYMENT_NAME=$(gcloud infra-manager deployments list --location "${REGION}" \ + --filter="labels.goog-solutions-console-deployment-name:* AND \ + labels.goog-solutions-console-solution-id:${SOLUTION_ID}" \ + --format='value(name)') + if [ -n "$DEPLOYMENT_NAME" ]; then + break + fi +done +if [ -z "$DEPLOYMENT_NAME" ]; then + echo "Failed to find the existing deployment, exiting now!" + exit 1 +fi +echo "Region is ${REGION}" +echo "Deployment name is ${DEPLOYMENT_NAME}" + +SERVICE_ACCOUNT=$(gcloud infra-manager deployments describe "${DEPLOYMENT_NAME}" --location "${REGION}" --format='value(serviceAccount)') + +echo "Assigning required roles to the service account ${SERVICE_ACCOUNT}" +# Iterate over the roles and check if the service account already has that role +# assigned. If it has then skip adding that policy binding as using +# --condition=None can overwrite any existing conditions in the binding. +CURRENT_POLICY=$(gcloud projects get-iam-policy "${PROJECT_ID}" --format=json) +MEMBER_EMAIL=$(echo "${SERVICE_ACCOUNT}" | awk -F '/' '{print $NF}') +MEMBER="serviceAccount:${MEMBER_EMAIL}" + +while IFS= read -r role || [[ -n "$role" ]] +do \ +if echo "$CURRENT_POLICY" | jq -e --arg role "$role" --arg member "$MEMBER" '.bindings[] | select(.role == $role) | .members[] | select(. == $member)' > /dev/null; then \ + echo "IAM policy binding already exists for member ${MEMBER} and role ${role}" +else \ + gcloud projects add-iam-policy-binding "${PROJECT_ID}" \ + --member="$MEMBER" \ + --role="$role" \ + --condition=None +fi +done < "roles.txt" + +DEPLOYMENT_DESCRIPTION=$(gcloud infra-manager deployments describe "${DEPLOYMENT_NAME}" --location "${REGION}" --format json) +cat < input.tfvars +# Do not edit the region as changing the region can lead to failed deployment. +region="$(echo "$DEPLOYMENT_DESCRIPTION" | jq -r '.terraformBlueprint.inputValues.region.inputValue')" +project_id = "${PROJECT_ID}" +labels = { + "goog-solutions-console-deployment-name" = "${DEPLOYMENT_NAME}", + "goog-solutions-console-solution-id" = "${SOLUTION_ID}" +} +EOF + +echo "An input.tfvars has been created in the current directory with a set of default input terraform variables for the solution. You can modify their values or go ahead with the defaults." +read -r -p "Once done, press Enter to continue: " + +echo "Creating the cloud storage bucket if it does not exist already" +BUCKET_NAME="${PROJECT_ID}_infra_manager_staging" +if ! gsutil ls "gs://$BUCKET_NAME" &> /dev/null; then + gsutil mb "gs://$BUCKET_NAME/" + echo "Bucket $BUCKET_NAME created successfully." +else + echo "Bucket $BUCKET_NAME already exists. Moving on to the next step." +fi + +echo "Deploying the solution" +gcloud infra-manager deployments apply projects/"${PROJECT_ID}"/locations/"${REGION}"/deployments/"${DEPLOYMENT_NAME}" --service-account "${SERVICE_ACCOUNT}" --local-source="infra" --inputs-file="input.tfvars" --labels="modification-reason=make-it-mine,goog-solutions-console-deployment-name=${DEPLOYMENT_NAME},goog-solutions-console-solution-id=${SOLUTION_ID},goog-config-partner=sc" diff --git a/deploy_via_trigger.sh b/deploy_via_trigger.sh new file mode 100755 index 00000000..4d7ed12c --- /dev/null +++ b/deploy_via_trigger.sh @@ -0,0 +1,105 @@ +#!/bin/bash +# Copyright 2024 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. + +set -o pipefail + +handle_error() { + local exit_code=$? + exit $exit_code +} +trap 'handle_error' ERR + +while getopts p: flag +do + case "${flag}" in + p) PROJECT_ID=${OPTARG};; + *) echo "usage: $0 [-p PROJECT_ID]" >&2 + exit 1 ;; + esac +done + +if [ -z "$PROJECT_ID" ]; then + echo "Failed to read the project id, exiting now!" + exit 1 +fi + +SOLUTION_ID="ecommerce-platform-serverless" + +# Iterate over the infra manager location to identify the deployment +# currently one deployment per project is only supported +# in future if multiple deployments are supported per project this will need to change +IM_SUPPORTED_REGIONS=("us-central1" "europe-west1" "asia-east1") + +for REGION in "${IM_SUPPORTED_REGIONS[@]}"; do + DEPLOYMENT_NAME=$(gcloud infra-manager deployments list --location "${REGION}" \ + --filter="labels.goog-solutions-console-deployment-name:* AND \ + labels.goog-solutions-console-solution-id:${SOLUTION_ID}" \ + --format='value(name)') + if [ -n "$DEPLOYMENT_NAME" ]; then + break + fi +done +if [ -z "$DEPLOYMENT_NAME" ]; then + echo "Failed to find the existing deployment, exiting now!" + exit 1 +fi +echo "Project ID is ${PROJECT_ID}" +echo "Region is ${REGION}" +echo "Deployment name is ${DEPLOYMENT_NAME}" + +SERVICE_ACCOUNT=$(gcloud infra-manager deployments describe "${DEPLOYMENT_NAME}" --location "${REGION}" --format='value(serviceAccount)') + +echo "Assigning required roles to the service account ${SERVICE_ACCOUNT}" +# Iterate over the roles and check if the service account already has that role +# assigned. If it has then skip adding that policy binding as using +# --condition=None can overwrite any existing conditions in the binding. +CURRENT_POLICY=$(gcloud projects get-iam-policy "${PROJECT_ID}" --format=json) +MEMBER_EMAIL=$(echo "${SERVICE_ACCOUNT}" | awk -F '/' '{print $NF}') +MEMBER="serviceAccount:${MEMBER_EMAIL}" +apt-get install jq -y +while IFS= read -r role || [[ -n "$role" ]] +do \ +if echo "$CURRENT_POLICY" | jq -e --arg role "$role" --arg member "$MEMBER" '.bindings[] | select(.role == $role) | .members[] | select(. == $member)' > /dev/null; then \ + echo "IAM policy binding already exists for member ${MEMBER} and role ${role}" +else \ + gcloud projects add-iam-policy-binding "${PROJECT_ID}" \ + --member="$MEMBER" \ + --role="$role" \ + --condition=None +fi +done < "roles.txt" + +DEPLOYMENT_DESCRIPTION=$(gcloud infra-manager deployments describe "${DEPLOYMENT_NAME}" --location "${REGION}" --format json) +cat < input.tfvars +# Do not edit the region as changing the region can lead to failed deployment. +region="$(echo "$DEPLOYMENT_DESCRIPTION" | jq -r '.terraformBlueprint.inputValues.region.inputValue')" +project_id = "${PROJECT_ID}" +labels = { + "goog-solutions-console-deployment-name" = "${DEPLOYMENT_NAME}", + "goog-solutions-console-solution-id" = "${SOLUTION_ID}" +} +EOF + +echo "Creating the cloud storage bucket if it does not exist already" +BUCKET_NAME="${PROJECT_ID}_infra_manager_staging" +if ! gsutil ls "gs://$BUCKET_NAME" &> /dev/null; then + gsutil mb "gs://$BUCKET_NAME/" + echo "Bucket $BUCKET_NAME created successfully." +else + echo "Bucket $BUCKET_NAME already exists. Moving on to the next step." +fi + +echo "Deploying the solution" +gcloud infra-manager deployments apply projects/"${PROJECT_ID}"/locations/"${REGION}"/deployments/"${DEPLOYMENT_NAME}" --service-account "${SERVICE_ACCOUNT}" --local-source="infra" --inputs-file="input.tfvars" --labels="modification-reason=make-it-mine,goog-solutions-console-deployment-name=${DEPLOYMENT_NAME},goog-solutions-console-solution-id=${SOLUTION_ID},goog-config-partner=sc" diff --git a/roles.txt b/roles.txt new file mode 100644 index 00000000..f78894e3 --- /dev/null +++ b/roles.txt @@ -0,0 +1,16 @@ +roles/cloudbuild.builds.editor +roles/cloudsql.admin +roles/compute.admin +roles/compute.networkAdmin +roles/config.agent +roles/firebase.admin +roles/firebase.managementServiceAgent +roles/firebasehosting.admin +roles/iam.serviceAccountAdmin +roles/iam.serviceAccountUser +roles/pubsub.editor +roles/resourcemanager.projectIamAdmin +roles/run.admin +roles/secretmanager.admin +roles/serviceusage.serviceUsageAdmin +roles/storage.admin diff --git a/tutorial.md b/tutorial.md new file mode 100644 index 00000000..d50615ab --- /dev/null +++ b/tutorial.md @@ -0,0 +1,85 @@ + + + + + + + +# Customize an Ecommerce platform with serverless computing Solution + +Learn how to build and deploy your own proof of concept based on the deployed [Ecommerce platform with serverless computing](https://console.cloud.google.com/products/solutions/details/ecommerce-platform-serverless) Jump Start Solution. You can customize the Jump Start Solution deployment by creating a copy of the source code. You can modify the infrastructure and application code as needed and redeploy the solution with the changes. + +To avoid conflicts, only one user should modify and deploy a solution in a single Google Cloud project. + +## Open cloned repository as workspace + +Open the directory where the repository is cloned as a workspace in the editor, follow the steps based on whether you are using the Cloud Shell Editor in Preview Mode or Legacy Mode. + +--- +**Legacy Cloud Shell Editor** + +1. Go to the `File` menu. +2. Select `Open Workspace`. +3. Choose the directory where the repository has been cloned. This directory is the current directory in the cloud shell terminal. + +**New Cloud Shell Editor** + +1. Go the hamburger icon located in the top left corner of the editor. +2. Go to the `File` Menu. +3. Select `Open Folder`. +4. Choose the directory where the repository has been cloned. This directory is the current directory in the cloud shell terminal. + +## Before you begin + +We also strongly recommend that you familiarize yourself with the Ecommerce platform with serverless computing solution. + +NOTE: A change in the infrastructure code might cause a change in the incurred cost. + +--- +**Create an automated deployment** + +Run the deploy_solution.sh script. + +```bash +./deploy_solution.sh +``` + +--- +**Monitor the deployment** + +Get the deployment details. + +```bash +gcloud infra-manager deployments describe DEPLOYMENT_NAME --location REGION +``` + +Monitor your deployment at [Solution deployments page](https://console.cloud.google.com/products/solutions/deployments?pageState=(%22deployments%22:(%22f%22:%22%255B%257B_22k_22_3A_22Labels_22_2C_22t_22_3A13_2C_22v_22_3A_22_5C_22modification-reason%2520_3A%2520make-it-mine_5C_22_22_2C_22s_22_3Atrue_2C_22i_22_3A_22deployment.labels_22%257D%255D%22))). + +## Save your edits to the solution + +Use any of the following methods to save your edits to the solution + +--- +**Download the solution** + +To download your solution, in the `File` menu, select `Download Workspace`. The solution is downloaded in a compressed format. + + +--- +**Save the solution to your Git repository** + +Set the remote URL to your Git repository +```bash +git remote set-url origin [git-repo-url] +``` + +Review the modified files, commit and push to your remote repository branch. + +## Delete the deployed solution + +Optional: Use one of the below options in case you want to delete the deployed solution + +* Go to [Solution deployments page](https://console.cloud.google.com/products/solutions/deployments?pageState=(%22deployments%22:(%22f%22:%22%255B%257B_22k_22_3A_22Labels_22_2C_22t_22_3A13_2C_22v_22_3A_22_5C_22modification-reason%2520_3A%2520make-it-mine_5C_22_22_2C_22s_22_3Atrue_2C_22i_22_3A_22deployment.labels_22%257D%255D%22))). +* Click on the link under "Deployment name". It will take you to the deployment details page for the solution. +* Click on the "DELETE" button located at the top right corner of the page. + From 4498597c7f0b60455a0ac57d2dc57f4536a4a2ea Mon Sep 17 00:00:00 2001 From: Bhaskar Singhal Date: Mon, 18 Mar 2024 10:23:55 +0000 Subject: [PATCH 2/2] feat: add support for make it mine and deploy via cloudbuild trigger --- cloudbuild.yaml => cloudbuild_mim.yaml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename cloudbuild.yaml => cloudbuild_mim.yaml (100%) diff --git a/cloudbuild.yaml b/cloudbuild_mim.yaml similarity index 100% rename from cloudbuild.yaml rename to cloudbuild_mim.yaml