Skip to content

Commit

Permalink
feat: Cloud Deploy CICD (#79)
Browse files Browse the repository at this point in the history
* add cloud deploy resources

* boilerplate for deploy trigger

* add dynamic steps to build trigger

* use inline yaml for build trigger

* use build service account for build trigger

* use build_id for unique releases

* rename trigger name from deploy to release

* use short build ID for cloud deploy release name

* rename new release build

* use built-in subs instead of template vars

* formatting

* use built-in subs for build trigger too

* use tftpl for config files

* remove unused local block

* update new release trigger to use local templates

* chore: tf fmt

* rename tftpl and tf fmt

* update local vars

* update yaml name to tftpl

* update AR repo vars

* require cloud deploy approval

* rearrange resources and add comments

* new lines

* add env vars to app-prod tftpl

* retrieve ip addr and pass var values

* tf fmt

* rm old clouddeploy module

* update name of module in root

* add clouddeploy api and delay

* add additional apis

* tf fmt

* rename env directories

* update README with pipeline instructions

* correct regex

* change src/*

* replace provider

---------

Co-authored-by: Roger Martinez <rogerthatdev@gmail.com>
  • Loading branch information
rogerthatdev and Roger Martinez authored Apr 22, 2023
1 parent 914e324 commit d734481
Show file tree
Hide file tree
Showing 16 changed files with 323 additions and 335 deletions.
63 changes: 63 additions & 0 deletions infra/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,69 @@ gcloud run services update-traffic $CLOUD_RUN_SERVICE_NAME \
--project ${project}
```

# Example CICD pipeline

This repository includes an example CI/CD pipeline that uses Cloud Build and Cloud Deploy to continuously intergrate
changes to the application code into new builds of your application and automatically deploy those builds to to Cloud
Run. The following steps are required to set this pipeline up:

1. Deploy application infrastructure to a Google Cloud project
2. Fork this repository
3. Connect the fork to your Google Cloud project
4. Run the Terraform code in `infra/environments/main`


## 1. Deploy the application infrastructure

Using a Google Cloud Project with billing enabled, deploy the application infrastructure via the Terraform made
available in the
[terraform-dynamic-javascript-webapp repo](https://github.com/GoogleCloudPlatform/terraform-dynamic-javascript-webapp/tree/main/infra)


## 2. Fork this repository

In order to demonstrate the CI/CD pipeline, you'll need to create a fork of this repository so that you can make
changes to the main branch and initiate the pipeline. Instructions for forking a repository can be found in GitHub's
[documentation](https://docs.github.com/en/get-started/quickstart/fork-a-repo)

## 3. Connect your fork to your Google Cloud Project

Cloud Build triggers can be created to respond to GitHub repository actions, such as pull requests, and merges to the
main branch. To be able to create such triggers, the Google Cloud project must have the repository added to it in the
region of the trigger.

Connect your GitHub repo to your Google Cloud project via the
[Cloud Build triggers page](https://console.cloud.google.com/cloud-build/triggers/connect), making sure to specify the
'global' region.


## 4. Run the Terraform code

The `infra/environments/main` directory is a root Terraform module that creates the CICD pipeline resources in the
specified project. To apply the Terraform to your project, do the following from the `main` directory:

1. Supply the values for the variables

Rename `terraform.tfvars.example` to terraform.tfvars. This file is where you can provide values for the required
variables.

2. Run `terraform init`

To initiate the root module, run [`terraform init`](https://developer.hashicorp.com/terraform/cli/commands/init).
This initializes the working directory containing Terraform configuration files.

3. Run `terraform plan`

Running [`terraform plan`](https://developer.hashicorp.com/terraform/cli/commands/plan) will output an execution
plan that will servce as a preview of any changes that will be made to your Google Cloud project.

4. Run `terraform apply`

To apply the changes to your Google Cloud project, run
[`terraform apply`](https://developer.hashicorp.com/terraform/cli/commands/apply). The output will include the plan
and a prompt requesting that you approve the plan. Enter `yes` to deploy the Google Cloud resources to your
project.

<!-- doc links -->
[Artifact Registry]:
https://cloud.google.com/artifact-registry
Expand Down
62 changes: 0 additions & 62 deletions infra/environments/dev/README.md

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@
# See the License for the specific language governing permissions and
# limitations under the License.

module "cloud_build_cicd" {
source = "../../modules/cicd"
project_id = var.project_id
run_service_name = var.run_service_name
github_repository_url = var.github_repository_url
}
terraform {
# Uncomment to use a remote GCS backend. Bucket must already exist.
# backend "gcs" {
# bucket = "bucket-name"
# prefix = "build-cicd-state"
# }
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.

module "cloud_build_cicd" {
module "cicd_pipeline" {
source = "../../modules/cicd"
project_id = var.project_id
run_service_name = var.run_service_name
Expand Down
File renamed without changes.
29 changes: 0 additions & 29 deletions infra/environments/prod/variables.tf

This file was deleted.

5 changes: 3 additions & 2 deletions infra/modules/cicd/apis.tf
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,16 @@ module "project_services" {
enable_apis = var.enable_apis

activate_apis = [

"artifactregistry.googleapis.com",
"cloudbuild.googleapis.com",
"clouddeploy.googleapis.com",
]
}

resource "time_sleep" "project_services" {
depends_on = [
module.project_services
]

create_duration = "45s"
}

Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,13 @@
# See the License for the specific language governing permissions and
# limitations under the License.

terraform {
backend "gcs" {
bucket = "birds-of-paradise-tf-state"
prefix = "build-cicd-state"
impersonate_service_account = "terraformer@birds-of-paradise.iam.gserviceaccount.com"
}
}

steps:
- name: gcr.io/cloud-builders/docker
id: Docker Build
entrypoint: docker
args:
- 'build'
- '-t'
- '$${_IMAGE}:$${SHORT_SHA}'
- '.'
20 changes: 20 additions & 0 deletions infra/modules/cicd/cloudbuild/app-prod.yaml.tftpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: ${deployment_name}
spec:
template:
spec:
containers:
- image: app-image
env:
- name: NEXTAUTH_URL
value: http://${lb_ip_address}
- name: PROJECT_ID
value: ${project_id}
- name: NEXTAUTH_SECRET
valueFrom:
secretKeyRef:
key: latest
name: ${deployment_name}-nextauth-secret
serviceAccountName: ${run_service_account}
42 changes: 42 additions & 0 deletions infra/modules/cicd/cloudbuild/new-release.cloudbuild.yaml.tftpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# 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.

steps:
# Skaffold yaml
- name: 'ubuntu'
id: 'Skaffold yaml config'
entrypoint: 'bash'
args:
- '-c'
- |
echo "$${_SKAFFOLD_CONFIG}" > /workspace/skaffold.yaml
- name: 'ubuntu'
id: 'Run yaml config'
entrypoint: 'bash'
args:
- '-c'
- |
echo "$${_RUN_CONFIG}" > /workspace/app-prod.yaml
- name: gcr.io/cloud-builders/gcloud
id: 'Create new release on Cloud Deploy'
entrypoint: 'bash'
args:
- '-c'
- |
gcloud deploy releases create app-release-$(echo $${BUILD_ID} | cut -f1 -d'-') \
--project=$${PROJECT_ID} \
--region=$${_REGION} \
--delivery-pipeline=$${_PIPELINE_NAME} \
--images=app-image=$${_IMAGE}:$${SHORT_SHA}

11 changes: 11 additions & 0 deletions infra/modules/cicd/cloudbuild/skaffold.yaml.tftpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
apiVersion: skaffold/v3alpha1
kind: Config
metadata:
name: ${name}
profiles:
- name: prod
manifests:
rawYaml:
- app-prod.yaml
deploy:
cloudrun: {}
Loading

0 comments on commit d734481

Please sign in to comment.