main.tf
:
provider "google" {
project = "PROJECT_ID"
}
resource "google_compute_instance" "test-redis" {
name = "test-redis"
machine_type = "e2-micro"
zone = "europe-central2-a"
boot_disk {
initialize_params {
image = "debian-12"
}
}
network_interface {
subnetwork = google_compute_subnetwork.test-redis.self_link
access_config {}
}
metadata = {
enable-oslogin = true
startup-script = file("startup.sh")
}
}
resource "google_compute_network" "test-redis" {
name = "test-redis"
auto_create_subnetworks = false
}
resource "google_compute_subnetwork" "test-redis" {
name = "test-redis"
ip_cidr_range = "10.0.0.0/20"
region = "europe-central2"
network = google_compute_network.test-redis.self_link
}
resource "google_compute_firewall" "test-redis-ssh" {
name = "test-redis-ssh"
network = google_compute_network.test-redis.name
source_ranges = ["35.235.240.0/20"]
allow {
protocol = "tcp"
ports = [22]
}
}
resource "google_compute_firewall" "test-redis-redis" {
name = "test-redis-redis"
network = google_compute_network.test-redis.name
source_ranges = ["SOURCE_IP"]
allow {
protocol = "tcp"
ports = [6379]
}
}
startup.sh
:
set -x
curl -fsSL https://download.docker.com/linux/debian/gpg \
-o /etc/apt/keyrings/docker.asc
echo "deb [signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian $(. /etc/os-release && echo "$VERSION_CODENAME") stable" \
> /etc/apt/sources.list.d/docker.list
apt-get update
apt-get install -y docker-ce
mkdir -p root/redis/certs
cd root/redis/certs
openssl req -x509 -subj /CN=root.yourdomain.com -days 3650 -noenc \
-out root.crt -keyout root.key
openssl req -x509 -subj /CN=server.yourdomain.com -days 365 -noenc \
-CA root.crt -CAkey root.key -extensions usr_cert \
-out server.crt -keyout server.key
openssl req -x509 -subj /CN=client.yourdomain.com -days 365 -noenc \
-CA root.crt -CAkey root.key -extensions usr_cert \
-out client.crt -keyout client.key
cd ..
cat <<\END > docker-compose.yml
services:
redis:
image: redis:5.0.14-alpine3.16
command: redis-server /etc/redis.conf
volumes:
- ./redis.conf:/etc/redis.conf
stunnel:
image: dweomer/stunnel
environment:
STUNNEL_SERVICE: redis
STUNNEL_ACCEPT: 6379
STUNNEL_CONNECT: redis:6379
STUNNEL_VERIFY_CHAIN: yes
STUNNEL_VERIFY: 2
STUNNEL_CAFILE: /certs/root.crt
STUNNEL_CRT: /certs/server.crt
STUNNEL_KEY: /certs/server.key
ports:
- 6379:6379
volumes:
- ./certs:/certs
END
docker compose up -d
docker-compose.yml
:
services:
redis:
image: redis:5.0.14-alpine3.16
command: sleep infinity
init: true
stunnel:
image: dweomer/stunnel
environment:
STUNNEL_SERVICE: redis
STUNNEL_ACCEPT: 6379
STUNNEL_CONNECT: xx.xxx.xx.xxx:6379
STUNNEL_CLIENT: yes
STUNNEL_VERIFY_CHAIN: yes
STUNNEL_VERIFY: 2
STUNNEL_CAFILE: /certs/root.crt
STUNNEL_CRT: /certs/client.crt
STUNNEL_KEY: /certs/client.key
volumes:
- ./certs:/certs
// replace PROJECT_ID, SOURCE_IP
$ docker run --rm -itv "$PWD:/app" -w /app google/cloud-sdk:457.0.0-alpine
/app # gcloud auth login --update-adc
/app # apk add terraform
/app # terraform init
/app # terraform apply; echo -e '\a'
/app # gcloud compute ssh test-redis \
--command 'sudo -i tar czf /tmp/certs.tar.gz -C redis certs' \
--tunnel-through-iap --zone europe-central2-a --project PROJECT_ID
/app # gcloud compute scp test-redis:/tmp/certs.tar.gz /tmp/certs.tar.gz \
--tunnel-through-iap --zone europe-central2-a --project PROJECT_ID
$ docker cp ...:/tmp/certs.tar.gz certs.tar.gz
$ tar xf certs.tar.gz
/app # gcloud compute instances list --project PROJECT_ID --filter name:redis
NAME ZONE MACHINE_TYPE PREEMPTIBLE INTERNAL_IP EXTERNAL_IP STATUS
test-redis europe-central2-a e2-micro 10.0.0.5 xx.xxx.xx.xxx RUNNING
// replace the ip in docker-compose.yml
$ docker compose up
$ docker compose exec redis redis-cli -h stunnel -p 6379 keys \*
(empty list or set)