Skip to content

Commit

Permalink
Add example of cloudbuild with docker-compose running tcp proxy in th…
Browse files Browse the repository at this point in the history
…e background for all build steps (GoogleCloudPlatform#897)
  • Loading branch information
yyzh1 authored Oct 14, 2022
1 parent e933608 commit 6df9f5c
Show file tree
Hide file tree
Showing 8 changed files with 734 additions and 158 deletions.
608 changes: 450 additions & 158 deletions README.md

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions examples/cloudbuild-with-tcp-proxy/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
PORT=9999
ZONE=us-central1-c
PROXY_SERVER=automation-bastion
PROJECT_ID=<project_id_of_vm>
24 changes: 24 additions & 0 deletions examples/cloudbuild-with-tcp-proxy/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Copyright 2022 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.

FROM gcr.io/cloud-builders/gcloud-slim:latest

RUN apt-get -y update && \
apt-get -y install net-tools coreutils

COPY gssh_proxy.sh /

RUN chmod +x /gssh_proxy.sh

ENTRYPOINT ["/gssh_proxy.sh"]
71 changes: 71 additions & 0 deletions examples/cloudbuild-with-tcp-proxy/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
This is an example of running build steps with cloudbuild, having docker-compose
running HTTPS_PROXY in the background connected to a bastion host via Identity
Aware Proxy using 'gcloud compute ssh'.

This is one of the way to restrict outbound public IP address of the cloudbuild
default pool.

# Prerequisite:

## Setup Bastion Host and install Proxy

e.g. Tiny proxy is pre-installed in the bastion host.

```
sudo apt-get install tinyproxy
sudo vim /etc/tinyproxy/tinyproxy.conf
########################
# Edit tiny proxy config
# - Update Port
# - Update Allow list with: 0.0.0.0/0, localhost
########################
sudo /etc/init.d/tinyproxy restart
```

## Reserve public IP

* [Reserve a public IP](https://cloud.google.com/compute/docs/ip-addresses/reserve-static-external-ip-address)
* [Setup Cloud NAT](https://cloud.google.com/nat/docs/set-up-manage-network-address-translation)
* [Setup Cloud NAT with reserved IP](https://cloud.google.com/nat/docs/set-up-manage-network-address-translation)

## Edit '.env' file with required variables

* PROJECT_ID: The Project ID that the Proxy Server is running in
* ZONE: The Zone that Proxy Server is running in
* PROXY_SERVER: The name of the VM running as Proxy Server
* PORT: The PORT that tinyproxy config points to

# Running the build

## Running docker-compose in local host

To make sure that the config is properly setup, it is easier to test it in local
environment before submitting to Cloud Build.

* Run docker-compose locally to connect to Proxy Server:

```
docker-compose -f docker-compose-local.yaml up --build
```

* To verify that proxy is connected correctly, run below command and make sure
that the egress IP is the same as the public IP reserved for Cloud NAT

```
curl -x localhost:$PORT https://api.ipify.org?format=json
```

* Bring down docker-compose

```
docker-compose -f docker-compose-local.yaml down
```

## Running the test in Cloud Build

* Submit a Cloud Build request and verify that the public IP for NAT is used
by Step 2

```
gcloud builds submit . --substitutions=$(sed -z 's/\n/,_/g;s/,_$/\n/;s/^/_/' .env)
```
46 changes: 46 additions & 0 deletions examples/cloudbuild-with-tcp-proxy/cloudbuild.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Copyright 2022 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:
- id: connect_to_proxy
# cautious with ":latest" tag.
# current latest public version (1.29.2) does not support healthcheck with condition.
name: 'docker/compose:1.28.2'
args: ['-f', 'docker-compose-cloudbuild.yaml', 'up', '-d', '--build']
env:
- 'PROJECT_ID=$_PROJECT_ID'
- 'PORT=$_PORT'
- 'ZONE=$_ZONE'
- 'PROXY_SERVER=$_PROXY_SERVER'

- id: inspect_proxy_healthcheck
name: gcr.io/cloud-builders/docker
args: ['inspect', "--format='{{json .State.Health}}'", "workspace_gcloud_ssh_proxy_1"]
waitFor:
connect_to_proxy

- id: verify_proxy
name: gcr.io/cloud-builders/curl
args:
https://api.ipify.org?format=json
env:
- HTTPS_PROXY=workspace_gcloud_ssh_proxy_1.cloudbuild:$_PORT
waitFor:
connect_to_proxy

- id: disconnect_docker_compose
name: 'docker/compose:1.28.2'
args: ['-f', 'docker-compose-cloudbuild.yaml', 'down']
waitFor:
verify_proxy
49 changes: 49 additions & 0 deletions examples/cloudbuild-with-tcp-proxy/docker-compose-cloudbuild.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Copyright 2022 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.

version: '3'

services:
gcloud_ssh_proxy:
build: .
entrypoint:
'/gssh_proxy.sh'
ports:
- '$PORT:$PORT'
healthcheck:
test: 'netstat -ltn | grep -c $PORT || exit 1'
interval: 5s
timeout: 5s
retries: 10
environment:
- PORT=$PORT
- ZONE=$ZONE
- PROXY_SERVER=$PROXY_SERVER
- PROJECT_ID=$PROJECT_ID

# proxy_waiter runs a dummy container to wait for healtcheck of gcloud ssh proxy
proxy_waiter:
image: gcr.io/cloud-builders/gcloud-slim:latest
depends_on:
gcloud_ssh_proxy:
condition: service_healthy

# docker-compose uses builders_default network by default.
# cloudbuild steps uses docker network cloudbuild by default.
# must specify cloudbuild network explicitly if running in cloudbuild.
networks:
default:
external:
name: cloudbuild

51 changes: 51 additions & 0 deletions examples/cloudbuild-with-tcp-proxy/docker-compose-local.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Copyright 2022 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.

version: '3'

volumes:
root_config_gcloud:
services:
gcloud_ssh_proxy:
build: .
volumes:
- ~/.config/gcloud:/.config/gcloud
- ~/.ssh:/root/.ssh
# use network_mode:host for easy debug in local env.
network_mode: host
entrypoint:
'/gssh_proxy.sh'
healthcheck:
test: 'netstat -ltn | grep -c $PORT || exit 1'
interval: 5s
timeout: 3s
retries: 10
environment:
- CLOUDSDK_CONFIG=/.config/gcloud
- TERM=xterm-256color
- USER
- PORT=$PORT
- ZONE=$ZONE
- PROXY_SERVER=$PROXY_SERVER
- PROJECT_ID=$PROJECT_ID

# proxy_waiter runs a dummy container to wait for healtcheck of gcloud ssh proxy
proxy_waiter:
image: gcr.io/cloud-builders/gcloud-slim:latest
network_mode: host
command: >
version
depends_on:
gcloud_ssh_proxy:
condition: service_healthy
39 changes: 39 additions & 0 deletions examples/cloudbuild-with-tcp-proxy/gssh_proxy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/bin/bash
# Copyright 2022 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.


set -e

echo "START: Connecting to proxy"

# avoid hitting issue with login profile size
# (https://github.com/kyma-project/test-infra/issues/93)
for i in $(gcloud compute os-login ssh-keys list | grep -v FINGERPRINT); do echo "$i"; gcloud compute os-login ssh-keys remove --key "$i"; done

gcloud compute ssh \
--project="$PROJECT_ID" \
--zone="$ZONE" \
--tunnel-through-iap "$PROXY_SERVER" \
-- -L 0.0.0.0:"$PORT":localhost:"$PORT" -Nqf
# tail tinyproxy log only works for local
# --command='sudo tail -f /var/log/tinyproxy/tinyproxy.log' \

echo "SUCCESS: Connected to proxy"

# keep container running in background
while :
do
sleep 5
done

0 comments on commit 6df9f5c

Please sign in to comment.