Code Monkey home page Code Monkey logo

cloud-run-static-outbound-ip's Introduction

⚠️ ⚠️ WARNING ⚠️ ⚠️

As of October 2020, this workaround is now deprecated and obsolete. Cloud Run has an official feature (VPC egress) that allows you to configure a static IP through Cloud NAT. Follow the step-by-step guide I developed to use this feature.

⚠️ ⚠️ WARNING ⚠️ ⚠️


Static Outbound IP example for Cloud Run applications

This repository contains an example of a Google Cloud Run application that runs an SSH tunnel through a GCE instance within the container to route outbound requests of the Cloud Run application through the static IP of the GCE instance.

Read the accompanying blog post as well: https://ahmet.im/blog/cloud-run-static-ip/

Before you begin

  1. Launch Google Cloud Shell (recommended, as it has al the tools required pre-installed).

  2. Clone this repository and cd into it.

Create a tunnel instance on GCE

  1. Create a set of ssh key pairs so that your container can SSH into the VM.

    ssh-keygen -q -f ssh_key

    Note that the private SSH key, which is a secret, will be bundled into the container image, which can be compromised if anyone gets access to your source code/build system. You can also use other means of delivering this key to the container in the runtime (e.g. by downloading from a GCS bucket, or using a secrets manager).

  2. Create a Google Compute Engine instance (f1-micro in us-central1 with name "tunnel"):

    gcloud compute instances create "tunnel" \
        --zone=us-central1-b \
        --machine-type=f1-micro
  3. (Optional) You can go to the Cloud Console and promote this VM’s ephemeral IP address to be a "static IP address". But, long as you don't delete this VM, its IP address will not change.

  4. Upload the SSH public key (not a secret) to the VM to authenticate as user "tunnel":

    gcloud compute instances add-metadata "tunnel" \
        --zone=us-central1-b
        --metadata-from-file ssh-keys=<(echo "tunnel:$(cat ssh_key.pub)")

(Optional) Inspect the application source code

Take time to understand:

  • entrypoint.sh: runs a SSH client (as SOCKS5 TCP proxy server via GCE VM) and the flask Python application server.

    This script sets HTTPS_PROXY=socks5://localhost:5000 environment variable to the Python app to use the proxy. However, this HTTPS_PROXY environment variable works the same way on many other languages, including Go as well.

    By setting HTTPS_PROXY environment variable you don't need to update your code to use the SOCKS5 proxy.

  • __init__.py waits for the SSH port-forwarding server configured via HTTPS_PROXY to be accessible.

  • app.py: starts a flask app querying https://ifconfig.me/ip and sends its result back.

  • Dockerfile invokes entrypoint.sh via tini init system.

Deploy Cloud Run application

  1. Set up $PROJECT variable in your shell to your current project.

    PROJECT="$(gcloud config get-value core/project -q)"
  2. Build and push the container image to Google Conatiner Registry.

    gcloud builds submit --tag gcr.io/$PROJECT/sample-tunnel
  3. Find the EXTERNAL_IP address of the Compute Engine VM named "tunnel" you created earlier:

    gcloud compute instances list --filter=name=tunnel
  4. Deploy to Cloud Run, by setting GCE_IP environment variable to the IP of the VM:

    gcloud beta run deploy sample-tunnel \
        --set-env-vars="GCE_IP=x.y.z.t" \
        --platform=managed \
        --region us-central1 \
        --allow-unauthenticated \
        --image=gcr.io/$PROJECT/sample-tunnel

Query the application

When you visit the application’s public URL, you will see that the IP address that it used to query https://ifconfig.me/ip is the IP address of the GCE instance.

You can visit the application’s /exit endpoint to crash the Cloud Run container instance, which would normally have a new dynamic IP assigned to the instance, but in this case it remains the same as Cloud Run holds onto the request.


Don't forget to check out the accompanying blog post: https://ahmet.im/blog/cloud-run-static-ip/

cloud-run-static-outbound-ip's People

Contributors

ahmetb avatar

Stargazers

Sergey Antoninko avatar Christopher Lafay avatar Pakinwet Saksamerprom avatar itinao avatar Carthic Subramanian avatar Michael Corrado avatar Keyo avatar Alexei Ledenev avatar Santi Agüero avatar Tyler Reece avatar  avatar JINNOUCHI Yasushi avatar Rigo B Castro avatar nakatanakatana avatar Aecio avatar  avatar Tetsu avatar  avatar  avatar Christopher Powroznik avatar Junsuk Park avatar Ricardo Amaro avatar Adrian Chifor avatar Barry Qin avatar Hugo Barrigas avatar Khash  avatar Marco Cestari avatar tzvsi avatar Matt Morgis avatar

Watchers

James Cloos avatar  avatar

cloud-run-static-outbound-ip's Issues

Permission denied error

When follow the steps, the service complains for some error as:
[FATAL tini (2)] exec ./entrypoint.sh failed: Permission denied

How could that be fixed?
Tried to add line to change the execution permission but it doesn't work.
RUN chmod +x /app

Failed to start and then listen on the port defined by the PORT environment variable

gcloud run deploy sample-tunnel --set-env-vars "GCE_IP=35.225.211.112" --platform managed --region us-central1 --allow-unauthenticated --image=gcr.io/myproject/sample-tunnel

result:

Deploying container to Cloud Run service [sample-tunnel] in project [myproject] region [us-central1]
X Deploying... Cloud Run error: Container failed to start. Failed to start and then listen on the port defined by the PORT environment variable. Logs for this revision might contain more information.    
  X Creating Revision... Cloud Run error: Container failed to start. Failed to start and then listen on the port defined by the PORT environment variable. Logs for this revision might contain more inform
  ation.                                                                                                                                                                                                   
  . Routing traffic...                                                                                                                                                                                     
  ✓ Setting IAM Policy...                                                                                                                                                                                  
Deployment failed                                                                                                                                                                                          
ERROR: (gcloud.run.deploy) Cloud Run error: Container failed to start. Failed to start and then listen on the port defined by the PORT environment variable. Logs for this revision might contain more information.

Illegal option

I am not able to deploy since the container cannot be started because of this,

./entrypoint.sh: 15: wait: Illegal option -n

This is my code
#!/usr/bin/env bash
set -ex
ssh -i ./ssh_key "cloud-proxy@${HTTP_PROXY}" \
-N -D ${HTTP_TUNNEL} \
-o StrictHostKeyChecking=no &
env HTTPS_PROXY="socks5://${HTTP_TUNNEL}" \
node index.js &
wait -n

What could be the problem? Thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.