This section will detail the creation and configuration of a new GCP project to houes all of the Terraform-managed resources for the storefront.
- Create the project
- Assign a billing account
- Create a storage bucket for Terraform
- Create an Artifact Registry docker repository
- Create a service account for Terraform
Create a new GCP project by following the official instructions.
Upon creation, make a note of the project id (not the project number). We will need this later when configuring Github Secrets.
If there is not already a billing acount set up for your organization, create one now.
Once a billing account is available, select "Billing" in the sidebar menu.
Then select "Link a billing account".
Select your billing account in the dropdown menu and then click "Set account".
Now that we have a billing account assigned to the project, we can create additional resources, including a new Cloud Storage bucket in which Terraform can store its state file.
In the sidebar menu, select "Cloud Storage".
Select "Create bucket".
Give the bucket a unique name and then click "Continue" (not "Create").
After choosing a region and the "Standard" storage class, selecting "Continue" on each screen, we now want to make sure to select "Enforce public access prevention on this bucket".
Terraform's state file is not encrypted, and it will contain any secret variable we supply it. Therefore, we need to be doubly certain that the state file can only be accessed by those who have permission via IAM, etc.
You can configure the "Access control" or "Choose how to protect object data" however you'd like, and once done select "Create".
In your GCP project, open the services menu.
Scroll down to the "CI/CD" section and click "Artifact Registry".
Being a new GCP project, you will need to click "Enable".
Now click "Create repository".
Here, assign the repository a name, make sure "Docker" is selected, and assign a region. (Most likely same as project region.). Then click "Create".
Once created, click the repository name in the table to go to the repository details.
Find the registry name - it will look something like <region>-docker.pkg.dev
.
The service account is an identity that Terraform can use to perform GCP API operations. In this step, we'll create a new account with the required roles and download a JSON file with the private key.
Disclaimer: Service account roles should only give terraform the absolute minimum power necessary to perform all functions. The roles outlined farther below are believed to be the minimum set, but there is a chance that they might be more elevated than they need to be.
Feel free to try restricting them further - if there is a less-priviledged set of roles that still allow full resource management, please let us know so that we can update the instructions accordingly.
In your GCP project, open the services menu.
Then, scroll down to IAM and select "Service Accounts".
From here, click "Create Service Account".
Give the account a recognizable name and, if desired, a description. When done, click "Create and Continue".
Now "Add Another Role" until the following four are assigned, and then click "Continue".
You can choose to assign users or groups to this account so they can perform actions with it if you'd like. If not, or once done, click "Done".
Now find the service account in the list and click the email to go to the account details screen.
Once there, click on "Keys".
Select "Add Key" and click "Create new key".
Make sure that JSON is selected and then click "Create". You will be prompted to open or download the resulting key - make sure to save it because you cannot recover it later.
You should have a JSON file that looks approximately like this:
{
"type": "service_account",
"project_id": "<project-id>",
"private_key_id": "abc..snip...xyz",
"private_key": "-----BEGIN PRIVATE KEY-----\nABC... snip ...XYZ\n-----END PRIVATE KEY-----\n",
"client_email": "<user>@<project-id>.iam.gserviceaccount.com",
"client_id": "123... snip ...789",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/<user>%40<project-id>.iam.gserviceaccount.com"
}
Notice that this file contains new-lines. It is vitally important to retain newlines in the JSON key wherever we use it - even in an environment variable, even if we base-64 encode it.
Without newlines, terraform cannot authenticate. For whatever reason, Google tools require them.