Skip to content

Instantly share code, notes, and snippets.

@mikesparr
Created May 12, 2021 19:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save mikesparr/57b604f3f918b299df82af50ae0824d9 to your computer and use it in GitHub Desktop.
Save mikesparr/57b604f3f918b299df82af50ae0824d9 to your computer and use it in GitHub Desktop.
Google Cloud demo invoking a Cloud Run app in Ruby using Cloud Scheduler with OIDC
#!/usr/bin/env bash
export PROJECT_ID=$(gcloud config get-value project)
export PROJECT_USER=$(gcloud config get-value core/account) # set current user
export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")
export IDNS=${PROJECT_ID}.svc.id.goog # workflow identity domain
export GCP_REGION="us-central1" # CHANGEME (OPT)
export GCP_ZONE="us-central1-a" # CHANGEME (OPT)
export NETWORK_NAME="default"
# enable apis
gcloud services enable compute.googleapis.com \
cloudbuild.googleapis.com \
run.googleapis.com \
cloudscheduler.googleapis.com
# set defaults
gcloud config set compute/region $GCP_REGION
gcloud config set compute/zone $GCP_ZONE
#########################################################
# create sample ruby app
#########################################################
export APP_DIR="helloworld"
export APP_FILE="app.rb"
mkdir $APP_DIR
cd $APP_DIR
cat > $APP_FILE << EOF
require "sinatra"
set :bind, "0.0.0.0"
port = ENV["PORT"] || "8080"
set :port, port
get "/" do
name = ENV["NAME"] || "World"
"Hello #{name}!"
end
EOF
cat > Gemfile << EOF
source "https://rubygems.org"
gem "sinatra", "~>2.0"
group :test do
gem "rack-test"
gem "rest-client"
gem "rspec"
gem "rspec_junit_formatter"
gem "rubysl-securerandom"
end
EOF
# install bundler
gem install bundler
# generate Gemfile.lock
bundle install
# dockerize Ruby app
cat > Dockerfile << EOF
FROM ruby:2.5-slim
# Install production dependencies.
WORKDIR /usr/src/app
COPY Gemfile Gemfile.lock ./
ENV BUNDLE_FROZEN=true
RUN gem install bundler && bundle install --without test
# Copy local code to the container image.
COPY . ./
# Run the web service on container startup.
CMD ["ruby", "./app.rb"]
EOF
# create dockerignore
cat > .dockerignore << EOF
Dockerfile
README.md
.ruby-version
.bundle/
vendor/
EOF
# build and push image to container registry
gcloud builds submit --tag gcr.io/${PROJECT_ID}/${APP_DIR}
# deploy app to Cloud Run (requires auth)
gcloud run deploy $APP_DIR \
--image gcr.io/${PROJECT_ID}/${APP_DIR} \
--platform managed \
--region $GCP_REGION \
--no-allow-unauthenticated
# fetch the service URL
export SVC_URL=$(gcloud run services describe $APP_DIR --platform managed --region $GCP_REGION --format="value(status.url)")
#########################################################
# create cloud scheduler job
#########################################################
export SA_NAME="cloud-scheduler-runner"
export SA_EMAIL="${SA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com"
# create service account
gcloud iam service-accounts create $SA_NAME \
--display-name "${SA_NAME}"
# add sa binding to cloud run app
gcloud run services add-iam-policy-binding $APP_DIR \
--platform managed \
--region $GCP_REGION \
--member=serviceAccount:$SA_EMAIL \
--role=roles/run.invoker
# create the job to hit URL every 1 minute
gcloud scheduler jobs create http test-job --schedule "*/1 * * * *" \
--http-method=GET \
--uri=$SVC_URL \
--oidc-service-account-email=$SA_EMAIL \
--oidc-token-audience=$SVC_URL
@mikesparr
Copy link
Author

Cloud Scheduler job authenticates with linked service account.

Screen Shot 2021-05-12 at 1 56 37 PM

Authenticates and successfully invokes Cloud Run service

Screen Shot 2021-05-12 at 1 53 37 PM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment