Skip to content

Commit adc8781

Browse files
authored
Add Cloud Deploy example (#8)
This PR adds an example workflow for the [`create-cloud-deploy-release`](https://github.com/marketplace/actions/create-cloud-deploy-release) GitHub action. The example workflow: 1. Builds an example (included) demo application as a container image 1. Pushes the container image to [Google Artifact Registry](https://cloud.google.com/artifact-registry) 1. Creates a [Google Cloud Deploy](https://cloud.google.com/deploy) delivery pipeline 1. Uses the [`create-cloud-deploy-release`](https://github.com/marketplace/actions/create-cloud-deploy-release) action to create a release and deploy the example application to [Google Cloud Run](https://cloud.google.com/run).
1 parent 0f3524a commit adc8781

12 files changed

+377
-1
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@ This repository holds several references to example workflows and demonstrates h
66

77
## Available Examples
88

9+
### [create-cloud-deploy-release](workflows/create-cloud-deploy-release/README.md)
10+
11+
| Name | Starter | Description |
12+
| ------------------------------------------------------------ | ------------------------- | ---------------- |
13+
|[cloud-deploy-to-cloud-run](workflows/create-cloud-deploy-release/cloud-deploy-to-cloud-run.yml) | | Build a Docker container, publish it to Google Artifact Registry, and use Cloud Deploy to deploy to Google Cloud Run. |
14+
915
### [deploy-cloudrun](workflows/deploy-cloudrun/README.md)
1016

1117
| Name | Starter | Description |
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"name": "Create a Cloud Deploy release and deploy to Cloud Run",
3+
"description": "Build a Docker container, publish it to Google Artifact Registry, and use Cloud Deploy to deploy to Google Cloud Run.",
4+
"creator": "Google Cloud",
5+
"iconName": "google-cloud",
6+
"categories": ["Cloud Deploy", "Deployment", "Containers", "Cloud Run", "Serverless"]
7+
}

workflow.config.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
11
{
2+
"cloud-deploy-to-cloud-run": {
3+
"starter": false,
4+
"type": "deployments",
5+
"workflowPath": "workflows/create-cloud-deploy-release/cloud-deploy-to-cloud-run.yml",
6+
"propertiesPath": "properties/cloud-deploy-to-cloud-run.properties.json"
7+
},
28
"cloudrun-declarative": {
39
"starter": false,
410
"type": "deployments",
@@ -23,4 +29,4 @@
2329
"workflowPath": "workflows/get-gke-credentials/gke-build-deploy.yml",
2430
"propertiesPath": "properties/gke-build-deploy.properties.json"
2531
}
26-
}
32+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# create-cloud-deploy-release examples
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Copyright 2023 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
FROM golang:1.19 AS builder
16+
WORKDIR /go/src/hello
17+
COPY . .
18+
RUN CGO_ENABLED=0 go build -o /go/bin/hello
19+
20+
FROM gcr.io/distroless/static-debian11
21+
COPY --from=builder /go/bin/hello /
22+
CMD ["/hello"]
23+
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module app
2+
3+
go 1.19
4+
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Copyright 2023 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package main
16+
17+
import (
18+
"fmt"
19+
"log"
20+
"net/http"
21+
"os"
22+
)
23+
24+
func main() {
25+
log.Print("starting server...")
26+
http.HandleFunc("/", handler)
27+
28+
// Determine port for HTTP service.
29+
port := os.Getenv("PORT")
30+
if port == "" {
31+
port = "8080"
32+
log.Printf("defaulting to port %s", port)
33+
}
34+
35+
// Start HTTP server.
36+
log.Printf("listening on port %s", port)
37+
if err := http.ListenAndServe(":"+port, nil); err != nil {
38+
log.Fatal(err)
39+
}
40+
}
41+
42+
func handler(w http.ResponseWriter, r *http.Request) {
43+
name := os.Getenv("TARGET")
44+
if name == "" {
45+
name = "World"
46+
}
47+
fmt.Fprintf(w, "\nHello %s! 🎉\n\n", name)
48+
log.Printf("Sent response, target customization was '%s'", name)
49+
}
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
# This workflow builds and pushes a Docker container to Google Artifact Registry
2+
# and creates a release in Cloud Deploy using a declarative YAML Service
3+
# specification (service-*.yaml) when a commit is pushed to the $default-branch branch.
4+
#
5+
# Overview:
6+
#
7+
# 1. Authenticate to Google Cloud
8+
# 2. Configure Docker for Artifact Registry
9+
# 3. Build a container image
10+
# 4. Publish it to Google Artifact Registry
11+
# 5. Create YAML manifests from templates
12+
# 6. Create a Cloud Deploy delivery pipeline and targets (staging and production)
13+
# 7. Create a Cloud Deploy release to deploy the container image to Cloud Run
14+
#
15+
# To configure this workflow:
16+
#
17+
# 1. Ensure the required Google Cloud APIs are enabled:
18+
#
19+
# Cloud Build cloudbuild.googleapis.com
20+
# Cloud Deploy clouddeploy.googleapis.com
21+
# Cloud Run run.googleapis.com
22+
# Artifact Registry artifactregistry.googleapis.com
23+
#
24+
# 2. Create and configure Workload Identity Federation for GitHub (https://github.com/google-github-actions/auth#setting-up-workload-identity-federation)
25+
#
26+
# 3. Ensure the required IAM permissions are granted to the service account configured in
27+
# Workload Identity Federation:
28+
#
29+
# Artifact Registry
30+
# roles/artifactregistry.writer (Project or repository level)
31+
#
32+
# Cloud Deploy
33+
# roles/clouddeploy.operator (To configure Cloud Deploy)
34+
#
35+
# Cloud Storage
36+
# roles/storage.admin (To write release packages)
37+
#
38+
# 4. Ensure the required IAM permissions are granted to the default compute
39+
# service account:
40+
#
41+
# Cloud Logging
42+
# roles/logging.logWriter (To write logs)
43+
#
44+
# Cloud Run
45+
# roles/run.developer (To create Cloud Run services)
46+
#
47+
# Cloud Storage
48+
# storage/object.viewer (To read Cloud Deploy artifacts)
49+
# storage/object.creator (To write Cloud Deploy artifacts)
50+
#
51+
# Additionally, the default compute service account requires permissions to "ActAs" itself
52+
# to be able to deploy to Cloud Run. You can add this permission with the following command:
53+
#
54+
# gcloud iam service-accounts add-iam-policy-binding $(gcloud projects describe ${PROJECT_ID} \
55+
# --format="value(projectNumber)")[email protected] \
56+
# --member="serviceAccount:$(gcloud projects describe ${PROJECT_ID}\
57+
# --format="value(projectNumber)")[email protected]" \
58+
# --role="roles/iam.serviceAccountUser"
59+
#
60+
# NOTE: You should always follow the principle of least privilege when assigning IAM roles
61+
#
62+
# 5. Create GitHub secrets for WIF_PROVIDER and WIF_SERVICE_ACCOUNT
63+
#
64+
# 6. Change the values for the PROJECT_ID, GAR_LOCATION, and REGION environment variables (below).
65+
#
66+
# NOTE: To use Google Container Registry instead, replace ${{ env.GAR_LOCATION }}-docker.pkg.dev with gcr.io
67+
#
68+
# For more support on how to run this workflow, please visit https://github.com/marketplace/actions/create-cloud-deploy-release
69+
#
70+
# Further reading:
71+
# Cloud Deploy IAM permissions - https://cloud.google.com/deploy/docs/iam-roles-permissions
72+
# Cloud Run IAM permissions - https://cloud.google.com/run/docs/deploying
73+
# Cloud Run IAM roles - https://cloud.google.com/run/docs/reference/iam/roles
74+
# Cloud Run targets in Cloud Deploy - https://cloud.google.com/deploy/docs/run-targets
75+
76+
name: Build app and create a release in Cloud Deploy
77+
78+
on:
79+
push:
80+
branches:
81+
- $default_branch
82+
83+
env:
84+
PROJECT_ID: YOUR_PROJECT_ID # TODO: update Google Cloud project id
85+
GAR_LOCATION: YOUR_GAR_LOCATION # TODO: update Artifact Registry location
86+
REGION: YOUR_APP_REGION # TODO: update Cloud Run service region
87+
APP: app
88+
89+
jobs:
90+
deploy:
91+
# Add 'id-token' with the intended permissions for workload identity federation
92+
permissions:
93+
contents: 'read'
94+
id-token: 'write'
95+
96+
runs-on: ubuntu-latest
97+
steps:
98+
- name: 'Checkout'
99+
uses: 'actions/checkout@v3'
100+
101+
- name: 'Google auth'
102+
id: 'auth'
103+
uses: 'google-github-actions/auth@v1'
104+
with:
105+
workload_identity_provider: '${{ secrets.WIF_PROVIDER }}' # e.g. - projects/123456789/locations/global/workloadIdentityPools/my-pool/providers/my-provider
106+
service_account: '${{ secrets.WIF_SERVICE_ACCOUNT }}' # e.g. - [email protected]
107+
108+
- name: 'Set up Cloud SDK'
109+
uses: 'google-github-actions/setup-gcloud@v1'
110+
with:
111+
project_id: '${{ secrets.PROJECT_ID }}'
112+
113+
- name: 'Docker auth'
114+
run: |-
115+
gcloud auth configure-docker ${{ env.GAR_LOCATION }}-docker.pkg.dev
116+
117+
- name: 'Build and push container'
118+
run: |-
119+
docker build -t "${{ env.GAR_LOCATION }}-docker.pkg.dev/${{ env.PROJECT_ID }}/${{ env.APP }}/${{ env.APP }}:${{ github.sha }}" ./app
120+
docker push "${{ env.GAR_LOCATION }}-docker.pkg.dev/${{ env.PROJECT_ID }}/${{ env.APP }}/${{ env.APP }}:${{ github.sha }}"
121+
122+
- name: 'Render templatised config manifests'
123+
run: |-
124+
export PROJECT_ID="${{ env.PROJECT_ID }}"
125+
export REGION="${{ env.REGION }}"
126+
for template in $(ls config/*.template.yaml); do envsubst < ${template} > ${template%%.*}.yaml ; done
127+
128+
- name: 'Create Cloud Deploy delivery pipeline'
129+
run: |-
130+
gcloud deploy apply --file config/clouddeploy.yaml --region ${{ env.GAR_LOCATION }}
131+
132+
- name: 'Create release name'
133+
run: |-
134+
echo "RELEASE_NAME=${{ env.APP }}-${GITHUB_SHA::7}-${GITHUB_RUN_NUMBER}" >> ${GITHUB_ENV}
135+
136+
- name: 'Create Cloud Deploy release'
137+
id: 'release'
138+
uses: 'google-github-actions/create-cloud-deploy-release@v0'
139+
with:
140+
delivery_pipeline: '${{ env.APP }}'
141+
name: '${{ env.RELEASE_NAME }}'
142+
region: '${{ env.REGION }}'
143+
description: '${{ env.GITHUB_COMMIT_MSG }}'
144+
skaffold_file: 'config/skaffold.yaml'
145+
images: 'app=${{ env.GAR_LOCATION }}-docker.pkg.dev/${{ env.PROJECT_ID }}/${{ env.APP }}/${{ env.APP }}:${{ github.sha }}'
146+
147+
- name: 'Report Cloud Deploy release'
148+
run: |-
149+
echo "Created release ${{ steps.release.outputs.name }} "
150+
echo "Release link ${{ steps.release.outputs.link }} "
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Copyright 2023 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
apiVersion: serving.knative.dev/v1
16+
kind: Service
17+
metadata:
18+
name: 'app-prod'
19+
spec:
20+
template:
21+
metadata:
22+
annotations:
23+
autoscaling.knative.dev/maxScale: '1'
24+
spec:
25+
containers:
26+
- name: 'app'
27+
image: 'app'
28+
env:
29+
- name: 'TARGET'
30+
value: 'Prod'
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Copyright 2023 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
apiVersion: serving.knative.dev/v1
16+
kind: Service
17+
metadata:
18+
name: 'app-staging'
19+
spec:
20+
template:
21+
metadata:
22+
annotations:
23+
autoscaling.knative.dev/maxScale: '1'
24+
spec:
25+
containers:
26+
- name: 'app'
27+
image: 'app'
28+
env:
29+
- name: 'TARGET'
30+
value: 'Staging'

0 commit comments

Comments
 (0)