Quick and Secure Test Environments with GCP and IAP
Have you ever thought “It would be great if I could just launch $container or $app somewhere, just to get through this demo” but scrapped the idea due to security and time constraints or because your local machine already sounds like a 747 taking off during video calls? This article will lay the foundation for rapidly prototyping infrastructure in a GCP environment with nothing more than native
gcloud commands. So get your terminals ready and let’s get building.
To get started, it is assumed that the gcloud CLI tools are installed and configured to point to an active project. The official docs are a great place to start if more detailed explanation of this process is needed. As a quick test
gcloud compute instances list should succeed in listing any instances currently running in the configured environment. Going forward, any command snippets will assume the CLI tools have been configured with a default region/zone to simplify the example inputs.
A simple app deployment can become cumbersome very quickly when remote access and persistence are also required. Luckily GCP’s API driven nature makes it easy to rapidly modify and replace individual components and deploy secure networking and storage configurations. Before deploying any instances, start with creating a firewall for allowing access to the app.
First, create a firewall rule to be used with the application. SSH is the standard for remote access to Linux so the rule will allow inbound connections on port 22 in the desired VPC network and be applied to the instance via networking tagging using the ‘demo-app’ tag.
gcloud compute firewall-rules create demo-app-ssh \ --action allow \ --direction ingress \ --rules tcp:22 \ --target-tags demo-app \ --source-ranges 18.104.22.168/20 \
Finally, specify a source range of
22.214.171.124/20/20 for the rule. For those new to Google’s Identity Aware Proxy (IAP) this may seem oddly specific and even a little suspicious, but fear not, this range is managed by Google. IAP is an awesome tool for managing access to resources but well beyond the scope of this post. For the sake of brevity, leveraging IAP here allows for a finer grain of access control to the instance without having to expose open ports to the wider internet. The utility of this firewall rule will become apparent later in this article.
If Kubernetes is overkill for a single container and Cloud Run is impractical for a particular application, there is a lesser known feature built in to Compute Engine that can be leveraged to quickly deploy a single container on a compute instance with one command. For example, a recent engagement involved prototyping enterprise CI/CD pipelines that used Bitbucket Server for SCM. Since Atlassian provides a prebuilt server image that can be launched with minimal configuration, the following
gcloud command is sufficient:
gcloud compute instances create-with-container bb2 \ --container-image "atlassian/bitbucket-server" \ --tags=demo-app \ --no-address
--tags=demo-app assigns the firewall rule created earlier and
--no-address dissables assignment of a public IP (more on the lack of public IP later). Since this deployment is for demo purposes and will only be used during specific times, it would be nice to persist data between reboots and shutdowns. A quick modification to the command will add a persistent disk and mount it appropriately in the container:
gcloud compute instances create-with-container bb \ --container-image "nginx" \ --tags=demo-app \ --no-address \ --create-disk name=bb-data,mode=rw,size=10GB,auto-delete=no \ --container-mount-disk mode=rw,mount-path="/var/atlassian/application-data/bitbucket",name=bb-data
Remote Access and IAP
With an instance running with the desired container and a disk on which to persist data, the demo infrastructure is almost complete. To access the instance use the built in SSH functionality of
gcloud compute ssh bb --tunnel-through-iap
-tunnel-through-iap flag uses GCP’s IAP infrastructure to tunnel in to the VPC without explicitly exposing an external interface on the instance (hence the 126.96.36.199/20) and authenticates the SSH session transparently using IAM rather than a preconfigured Linux user. Touching the underlying host itself is of limited use for demonstrating what is running in the container, so an additional port forward is needed to route traffic to the container from the local machine over the SSH tunnel:
gcloud compute ssh bb --tunnel-through-iap -- -NL 7990:localhost:7990
Per the Bitbucket container specs, the web interface is exposed via port 7990 on the instance so the Bitbucket interface should be accessible via localhost:7990 in a web browser.
The combination of a simple firewall rule, container instances, and tunneling through IAP makes fast, secure, full featured demos and infrastructure prototyping only a few commands away.
The information presented in this article is accurate as of 11/19/2020. Follow the ScaleSec blog for new articles and updates.
ScaleSec is a service-disabled, veteran-owned small business (SDVOSB) for cloud security and compliance that helps innovators meet the requirements of their most scrutinizing customers. We specialize in cloud security engineering and cloud compliance. Our team of experts guides customers through complex cloud security challenges, from foundations to implementation, audit preparation and beyond.