Skip to content

Commit 66dd7c1

Browse files
authored
Merge pull request #441 from rust-lang/pa-start-release
Create the `start-release` lambda
2 parents 83c646b + 6d7a480 commit 66dd7c1

File tree

7 files changed

+172
-34
lines changed

7 files changed

+172
-34
lines changed

terraform/releases/.terraform.lock.hcl

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

terraform/releases/_terraform.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ terraform {
66
required_providers {
77
aws = {
88
source = "hashicorp/aws"
9-
version = "~> 4.20"
9+
version = "~> 5.58"
1010
}
1111
external = {
1212
source = "hashicorp/external"

terraform/releases/impl/main.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ terraform {
22
required_providers {
33
aws = {
44
source = "hashicorp/aws"
5-
version = "~> 4.20"
5+
version = "~> 5.58"
66
configuration_aliases = [aws.east1]
77
}
88
}

terraform/releases/impl/outputs.tf

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
11
output "promote_release_role_id" {
22
value = aws_iam_role.promote_release.unique_id
33
}
4+
5+
output "codebuild_project_arn" {
6+
value = aws_codebuild_project.promote_release.arn
7+
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
#!/usr/bin/env python3
2+
3+
# We want to grant folks on the release team the ability to start publishing
4+
# releases, but simply granting them permission to start the CodeBuild job
5+
# grants way too many privileges. For example, it would allow them to bypass
6+
# startup checks, override the commit being released, or worse override the
7+
# command being executed by CodeBuild to exfiltrate secrets.
8+
#
9+
# To solve the problem, this script accepts a limited set of actions allowed to
10+
# be executed, and invokes CodeBuild with the right environment variables. This
11+
# means we can safely grant the release team access to this function.
12+
13+
import boto3
14+
import time
15+
16+
17+
codebuild = boto3.client("codebuild")
18+
19+
20+
def handler(event, context):
21+
match event["action"]:
22+
case "update-rust-branches":
23+
# The channel for updating branches is not actually used by
24+
# promote-release, but we have to pass it anyway.
25+
return run_build("promote-branches", "prod", "nightly")
26+
27+
case "publish-rust-dev-nightly":
28+
return run_build("promote-release", "dev", "nightly")
29+
30+
case "publish-rust-dev-beta":
31+
return run_build("promote-release", "dev", "beta")
32+
33+
case "publish-rust-dev-stable":
34+
return run_build(
35+
"promote-release",
36+
"dev",
37+
"stable",
38+
{
39+
"PROMOTE_RELEASE_BLOG_REPOSITORY": "rust-lang/blog.rust-lang.org",
40+
"PROMOTE_RELEASE_BLOG_SCHEDULED_RELEASE_DATE": event["date"],
41+
},
42+
)
43+
44+
case "publish-rust-dev-stable-rebuild":
45+
return run_build(
46+
"promote-release",
47+
"dev",
48+
"stable",
49+
{
50+
"PROMOTE_RELEASE_BYPASS_STARTUP_CHECKS": "1",
51+
},
52+
)
53+
54+
case "publish-rust-prod-stable":
55+
return run_build("promote-release", "prod", "stable")
56+
57+
case action:
58+
raise RuntimeError(f"unsupported action: {action}")
59+
60+
61+
def run_build(action, env, channel, extra_vars=None):
62+
vars = {
63+
"PROMOTE_RELEASE_ACTION": action,
64+
"PROMOTE_RELEASE_CHANNEL": channel,
65+
}
66+
if extra_vars is not None:
67+
vars.update(extra_vars)
68+
69+
build = codebuild.start_build(
70+
projectName=f"promote-release--{env}",
71+
environmentVariablesOverride=[
72+
{"name": name, "value": value, "type": "PLAINTEXT"}
73+
for name, value in vars.items()
74+
],
75+
)["build"]
76+
77+
# Continue fetching information about the build
78+
while "streamName" not in build["logs"]:
79+
time.sleep(1)
80+
build = codebuild.batch_get_builds(ids=[build["id"]])["builds"][0]
81+
82+
return {
83+
"build_id": build["id"],
84+
"logs_group": build["logs"]["groupName"],
85+
"logs_link": build["logs"]["deepLink"],
86+
}

terraform/releases/start-release.tf

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
resource "aws_iam_role" "start_release" {
2+
name = "start-release-lambda"
3+
4+
assume_role_policy = jsonencode({
5+
Version = "2012-10-17"
6+
Statement = [
7+
{
8+
Effect = "Allow"
9+
Action = "sts:AssumeRole"
10+
Principal = {
11+
Service = "lambda.amazonaws.com"
12+
}
13+
}
14+
]
15+
})
16+
17+
inline_policy {
18+
name = "permissions"
19+
policy = jsonencode({
20+
Version = "2012-10-17"
21+
Statement = [
22+
{
23+
Effect = "Allow"
24+
Action = [
25+
"codebuild:StartBuild",
26+
"codebuild:BatchGetBuilds",
27+
]
28+
Resource = [
29+
module.dev.codebuild_project_arn,
30+
module.prod.codebuild_project_arn,
31+
]
32+
}
33+
]
34+
})
35+
}
36+
}
37+
38+
module "lambda_start_release" {
39+
source = "../shared/modules/lambda"
40+
41+
name = "start-release"
42+
source_dir = "lambdas/start-release"
43+
handler = "index.handler"
44+
runtime = "python3.12"
45+
role_arn = aws_iam_role.start_release.arn
46+
timeout_seconds = 900 # 15 minutes
47+
}

terraform/shared/modules/lambda/main.tf

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
terraform {
22
required_providers {
33
aws = {
4-
source = "hashicorp/aws"
5-
version = "~> 4.20"
4+
source = "hashicorp/aws"
5+
// Allow both 4.x and 5.x while we upgrade everything to 5.x.
6+
version = ">= 4.20, < 6"
67
}
78
}
89
}

0 commit comments

Comments
 (0)