Skip to content

Commit 1ff0261

Browse files
authored
Migrate cert-renewal process to cloud run job (#79)
Previously, the cert-renewal process was a long standing instance that ran the script once and slept. The problem arises that this sleep eventually breaks and the instance never recovers. This migrates the job to be a cloud run job that runs the script and that is it. The sleep is now handled by a cron schedule. This ensures the instance is always fresh. Fixes #57 Fixes #77
1 parent 26b6a1b commit 1ff0261

File tree

11 files changed

+398
-453
lines changed

11 files changed

+398
-453
lines changed

.github/workflows/lint.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,6 @@ jobs:
2121
- name: Set up Terraform
2222
uses: hashicorp/setup-terraform@v1
2323
with:
24-
terraform_version: '1.2.5'
24+
terraform_version: '1.6.2'
2525
- name: terraform
2626
run: terraform fmt --check

.terraform.lock.hcl

Lines changed: 27 additions & 26 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ Requirements:
139139

140140
- [Python 3](https://python.org)
141141
- [Pipenv](https://pipenv.pypa.io/)
142-
- [Terraform](https://www.terraform.io/) version 1.2.5
142+
- [Terraform](https://www.terraform.io/) version 1.6.2
143143

144144
The following commands will run the lints:
145145

cert-renewer.Dockerfile

Lines changed: 26 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -8,32 +8,26 @@ ENV WPT_HOST=wpt.live \
88
WPT_ALT_HOST=not-wpt.live \
99
WPT_BUCKET=wpt-live
1010

11-
# Pin the versions for repeatable builds
11+
# Pin the versions of python and google cloud cli for repeatable builds
1212
# For ubuntu package versions, go to https://packages.ubuntu.com/
1313
# Search for the package with the "jammy" distribution (aka 22.04) selected.
14-
# For Google Cloud, look under https://packages.cloud.google.com/apt/dists/cloud-sdk/main/binary-amd64/Packages
1514
RUN apt-get -qqy update && \
1615
apt-get -qqy install \
17-
apt-transport-https=2.4.6 \
18-
ca-certificates=20211016 \
19-
curl=7.81.0-1ubuntu1.3 \
20-
gnupg=2.2.27-3ubuntu2.1 \
21-
python3=3.10.4-0ubuntu2 \
22-
python3-dev=3.10.4-0ubuntu2 \
23-
python3-pip=22.0.2+dfsg-1 && \
24-
# https://cloud.google.com/storage/docs/gsutil_install
25-
echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] https://packages.cloud.google.com/apt cloud-sdk main" | \
26-
tee -a /etc/apt/sources.list.d/google-cloud-sdk.list && \
27-
curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | \
28-
tee /usr/share/keyrings/cloud.google.gpg && \
29-
apt-get -qqy update && \
30-
apt-get -qqy install \
31-
google-cloud-cli=396.0.0-0 && \
32-
rm -rf /var/lib/apt/lists/* && apt-get clean
16+
apt-transport-https \
17+
ca-certificates \
18+
curl \
19+
gnupg \
20+
python3=3.10.6-1~22.04 \
21+
python3-dev=3.10.6-1~22.04 \
22+
python3-pip=22.0.2+dfsg-1
23+
# For Google Cloud, look under https://packages.cloud.google.com/apt/dists/cloud-sdk/main/binary-amd64/Packages
24+
# https://cloud.google.com/storage/docs/gsutil_install
25+
# Copy the "Docker Tip" instructions from gsutil_install link and then pin the version
26+
RUN echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] http://packages.cloud.google.com/apt cloud-sdk main" | tee -a /etc/apt/sources.list.d/google-cloud-sdk.list && curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key --keyring /usr/share/keyrings/cloud.google.gpg add - && apt-get update -y && apt-get install google-cloud-cli=451.0.1-0 -y
3327

3428
# Instructions for certbot installation
3529
# https://certbot.eff.org/instructions?ws=other&os=pip
36-
RUN pip install certbot==1.29.0 certbot-dns-google==1.29.0
30+
RUN pip install acme==1.29.0 certbot==1.29.0 certbot-dns-google==1.29.0
3731

3832
COPY src/cert-store.sh /usr/local/bin/
3933

@@ -47,19 +41,16 @@ COPY src/cert-store.sh /usr/local/bin/
4741
# https://eff-certbot.readthedocs.io/en/stable/using.html?highlight=wildcard#dns-plugins
4842

4943
CMD bash -c '\
50-
cert-store.sh fetch ${WPT_BUCKET} ${WPT_HOST}; \
51-
while true; do \
52-
certbot certonly \
53-
-d ${WPT_HOST} \
54-
-d *.${WPT_HOST} \
55-
-d ${WPT_ALT_HOST} \
56-
-d *.${WPT_ALT_HOST} \
57-
--dns-google \
58-
--dns-google-propagation-seconds 120 \
59-
--agree-tos \
60-
--non-interactive \
61-
62-
--server https://acme-v02.api.letsencrypt.org/directory \
63-
--deploy-hook "cert-store.sh save ${WPT_BUCKET} ${WPT_HOST}"; \
64-
sleep $((60 * 60 * 24)); \
65-
done'
44+
cert-store.sh fetch ${WPT_BUCKET} ${WPT_HOST} && \
45+
certbot certonly \
46+
-d ${WPT_HOST} \
47+
-d *.${WPT_HOST} \
48+
-d ${WPT_ALT_HOST} \
49+
-d *.${WPT_ALT_HOST} \
50+
--dns-google \
51+
--dns-google-propagation-seconds 120 \
52+
--agree-tos \
53+
--non-interactive \
54+
55+
--server https://acme-v02.api.letsencrypt.org/directory \
56+
--deploy-hook "cert-store.sh save ${WPT_BUCKET} ${WPT_HOST}"'

infrastructure/docker-image/versions.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11

22
terraform {
3-
required_version = "~> 1.2.5"
3+
required_version = "~> 1.6.2"
44
required_providers {
55
external = {
66
source = "hashicorp/external"

infrastructure/web-platform-tests/compute.tf

Lines changed: 38 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -154,96 +154,54 @@ resource "google_compute_instance_template" "wpt_server" {
154154

155155
########################################
156156
# Cert Renewers
157-
# These configurations come from: github.com/dcaba/terraform-google-managed-instance-group
158-
# More information about how it was used previously: https://github.com/web-platform-tests/wpt.live/blob/67dc5976ccce2e64483f2028a35659d4d6e58891/infrastructure/web-platform-tests/main.tf#L139-L178
159157
########################################
160158

161-
resource "google_compute_instance_template" "cert_renewers" {
162-
name_prefix = "default-"
163-
164-
machine_type = "f1-micro"
165-
166-
region = var.region
167-
168-
tags = ["allow-ssh", "${var.name}-allow"]
169-
170-
labels = {
171-
"${module.cert-renewer-container.vm_container_label_key}" = module.cert-renewer-container.vm_container_label
172-
}
173-
174-
network_interface {
175-
network = var.network_name
176-
subnetwork = var.subnetwork_name
177-
network_ip = ""
178-
access_config {
179-
network_tier = "PREMIUM"
159+
resource "google_cloud_run_v2_job" "cert_renewers" {
160+
name = "${var.name}-cert-renewers"
161+
location = var.region
162+
launch_stage = "BETA"
163+
164+
template {
165+
template {
166+
containers {
167+
image = var.cert_renewer_image
168+
env {
169+
name = "WPT_HOST"
170+
value = var.host_name
171+
}
172+
env {
173+
name = "WPT_ALT_HOST"
174+
value = var.alt_host_name
175+
}
176+
env {
177+
name = "WPT_BUCKET"
178+
value = local.bucket_name
179+
}
180+
}
180181
}
181182
}
182-
183-
can_ip_forward = false
184-
185-
disk {
186-
auto_delete = true
187-
boot = true
188-
source_image = module.cert-renewer-container.source_image
189-
type = "PERSISTENT"
190-
disk_type = "pd-ssd"
191-
mode = "READ_WRITE"
192-
}
193-
194-
service_account {
195-
email = "default"
196-
scopes = ["cloud-platform"]
197-
}
198-
199-
# startup-script and tf_depends_id comes from the module previously used for cert renewer. (see link at top)
200-
# TODO: evaluate if those two should be removed.
201-
metadata = {
202-
"${module.cert-renewer-container.metadata_key}" = module.cert-renewer-container.metadata_value
203-
"startup-script" = ""
204-
"tf_depends_id" = ""
205-
"google-logging-enabled" = "true"
206-
}
207-
208-
scheduling {
209-
preemptible = false
210-
automatic_restart = true
211-
on_host_maintenance = "MIGRATE"
212-
}
213-
214-
lifecycle {
215-
create_before_destroy = true
216-
}
217183
}
218184

219-
resource "google_compute_instance_group_manager" "cert_renewers" {
220-
name = "${var.name}-cert-renewers"
221-
description = "compute VM Instance Group"
222-
wait_for_instances = false
223-
224-
base_instance_name = "${var.name}-cert-renewers"
225-
226-
version {
227-
instance_template = google_compute_instance_template.cert_renewers.self_link
228-
}
185+
data "google_project" "project" {
186+
}
229187

230-
zone = var.zone
188+
resource "google_cloud_scheduler_job" "cert_renewer_schedule" {
189+
provider = google
190+
name = "${var.name}-cert-renewer-schedule"
191+
description = "cert renewal schedule job"
192+
schedule = "0 0 * * *"
193+
attempt_deadline = "320s"
194+
region = "us-central1"
231195

232-
update_policy {
233-
type = local.update_policy.type
234-
minimal_action = local.update_policy.minimal_action
235-
max_unavailable_fixed = local.update_policy.max_unavailable_fixed
196+
retry_config {
197+
retry_count = 3
236198
}
237199

238-
target_pools = []
239-
240-
target_size = 1
241-
242-
dynamic "named_port" {
243-
for_each = var.cert_renewer_ports
244-
content {
245-
name = named_port.value["name"]
246-
port = named_port.value["port"]
200+
http_target {
201+
http_method = "POST"
202+
uri = "https://${google_cloud_run_v2_job.cert_renewers.location}-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/${data.google_project.project.number}/jobs/${google_cloud_run_v2_job.cert_renewers.name}:run"
203+
oauth_token {
204+
service_account_email = var.service_account_email
247205
}
248206
}
249207
}

infrastructure/web-platform-tests/main.tf

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -36,31 +36,6 @@ module "wpt-server-container" {
3636
restart_policy = "Always"
3737
}
3838

39-
module "cert-renewer-container" {
40-
source = "terraform-google-modules/container-vm/google"
41-
version = "3.0.0"
42-
43-
container = {
44-
image = var.cert_renewer_image
45-
env = [
46-
{
47-
name = "WPT_HOST"
48-
value = var.host_name
49-
},
50-
{
51-
name = "WPT_ALT_HOST"
52-
value = var.alt_host_name
53-
},
54-
{
55-
name = "WPT_BUCKET"
56-
value = local.bucket_name
57-
},
58-
]
59-
}
60-
61-
restart_policy = "Always"
62-
}
63-
6439
resource "google_storage_bucket" "certificates" {
6540
name = local.bucket_name
6641
location = "US"

infrastructure/web-platform-tests/variables.tf

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,10 @@ variable "wpt_server_ports" {
8989
]
9090
}
9191

92+
variable "service_account_email" {
93+
type = string
94+
default = "[email protected]"
95+
}
9296

9397
variable "cert_renewer_ports" {
9498
type = list(object({

infrastructure/web-platform-tests/versions.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11

22
terraform {
3-
required_version = "~> 1.2.5"
3+
required_version = "~> 1.6.2"
44
required_providers {
55
google = {
66
source = "hashicorp/google"

0 commit comments

Comments
 (0)