Imagine that you are preparing your personal Google Cloud Platform project and have selected numerous PaaS APIs for your solution.
- How can your teammates match their personal GCP project so they can troubleshoot and contribute to the codebase?
- How does your DevOps engineers deploy to Development, Staging and Production without knowing the exact settings of your project?
This solution will provide a safe and repeatable process in which any GCP project's infrastructure will be configured the same way every single time.
Theres solutions out there that will prepare containers, clusters, kubes and more, but there isnt much in terms of preparing projects that focus on PaaS-only solutions.
For example, I would like to use AppEngine, PubSub, Cloud Scheduler and prepare some Cloud Tasks and Buckets. Not all solutions can manage this.
Safe - All methods are idempotent. Meaning, if something exists or is already enabled, the script will skip that step and move on. This allows you to incrementally update your project as you find the need for more services. For example, your solution is already deployed to the wild. My next feature is to add 2 new Cloud Tasks. You can safely re-run the script with your changes and only those new Cloud Tasks methods will run.
Repeatable - Run it again, and again, and again. Same result! Run it on a different project. Same result!
- Copy the
__gcloud_infrastructure_helpers.sh
to your solution. - A driver file, such as the
sample-script.sh
should be created. (Use the sample-script to assist you.) - Run the script by providing a project flag.
bash sample-script.sh --project my-project
You can provide flags to reuse your script with different projects.
- --project - the GCP project you are targeting (mandatory)
- --quiet - will not prompt you for user input (optional)
Enable individual services by using the commands below.
# AppEngine (appengine.googleapis.com)
enable_appengine
# Datastore (datastore.googleapis.com)
enable_datastore
# Cloud Functions API (cloudfunctions.googleapis.com)
enable_cloud_functions
# Cloud Tasks (cloudtasks.googleapis.com)
enable_cloud_tasks
# Cloud Secret Manager (secretmanager.googleapis.com)
enable_secret_manager
# Cloud Resource Manager (cloudresourcemanager.googleapis.com)
enable_cloud_resource_manager
# Identity and Access Management (IAM) API (iam.googleapis.com)
enable_IAM
You can enable all other services not developed above with by specifying the api as follows:
enable_gcp_service "myService.googleapis.com"
Developer Notes: If there are services that seem to come up often, feel free to update the utils file and this document.
With Secrets Manager, you can create a Secret Placeholder that you or your DevOps team may update at a later date. Once created, there will be no version or value added to it so be sure to warn the user or update a wiki entry to fill in the value.
create_secret_placeholder "this-is-my-secret-name"
You can create a Task Queue in App Engine. (Logging will automatically be enabled.) If the task is already created, this step will be skipped.
create_cloud_task "my-task-queue-name"
Create a GCP Bucket by supplying the name with the function. If a bucket with that name already exists, this step will automatically be skipped.
configure_bucket "my-bucket-name"
In the event you need to configure the lifecycle of the objects in a bucket, you can do so by providing a configuration json file. See https://cloud.google.com/storage/docs/managing-lifecycles#configexamples.
configure_bucket_lifecycle "my-bucket-name" "./my-bucket-name-lifecycle.config.json"
There will be times where you may need to add permissions to a service account so that it can either read or write to a bucket.
ELEVATED PERMISSIONS MAY BE NEEDED
NOT 100% IDEMPOTENT
add_role_to_account_and_bucket my-project "some-account@my-project.gserviceaccount.com" "roles/storage.objectCreator"
*
we are marking this as not 100% idempotent because we do not look to see if the role exists. Google does, in fact, safely error out if the permission exists. So you are still safe to rerun this multiple times.
The service account will sometimes need additional roles. Verify the role exists. The script will automatically fail and warn the user that the role is needed on the account to continue.
verify_role_to_serviceAccount my-project "some-account@my-project.gserviceaccount.com" "roles/iam.serviceAccountTokenCreator"
Typically you will want to check that a role exists on the default service account. Be default, you will have the variable $DEFAULT_SERVICE_ACCOUNT available for you to use. The above script will now translate to
verify_role_to_serviceAccount my-project "$DEFAULT_SERVICE_ACCOUNT" "roles/iam.serviceAccountTokenCreator"
During your session, you may want to fail the entire script. You can also provide a warning message if needed.
# Error the script with no message
error_exit
# Error the script with a message
error_exit "you have done something bad"
These variables are automatically set on startup and available for you to use in your script.
$DEFAULT_SERVICE_ACCOUNT
- the app engine default service account for the project. Use this for validating roles or adding/changing permissions.$DEFAULT_SERVICE_ACCOUNT_EXISTS
- whether or not the default service account is available for use. You will receive a warning if one does not exist (although this is unlikely)$quiet
- if the user has requested to run quietly, provide functionality to use a default value or functionality.$project
- The project the script is currently running under.