Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit08f0eaa

Browse files
authored
feat: add new scaletest infrastructure (#15573)
Closescoder/internal#148This has been validated to have working proxies with the `small`scenario.- [x] multi-region gcp infrastructure- [x] use cloudflare provider to automate dns entries- [x] automate proxy registration- [x] multi-regional proxies- [x] move scenarios into localsThis excludes the infrastructure for `cert-manager` and `otel-collector`and those will be included in followup PRs.
1 parentd31c2f1 commit08f0eaa

14 files changed

+1327
-0
lines changed

‎scaletest/terraform/action/cf_dns.tf

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
resource"cloudflare_record""coder" {
2+
for_each=local.deployments
3+
zone_id=var.cloudflare_zone_id
4+
name=each.value.subdomain
5+
content=google_compute_address.coder[each.key].address
6+
type="A"
7+
ttl=3600
8+
}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
coder:
2+
workspaceProxy: ${workspace_proxy}
3+
affinity:
4+
nodeAffinity:
5+
requiredDuringSchedulingIgnoredDuringExecution:
6+
nodeSelectorTerms:
7+
- matchExpressions:
8+
- key:"cloud.google.com/gke-nodepool"
9+
operator:"In"
10+
values: ["${node_pool}"]
11+
podAntiAffinity:
12+
preferredDuringSchedulingIgnoredDuringExecution:
13+
- weight:1
14+
podAffinityTerm:
15+
topologyKey:"kubernetes.io/hostname"
16+
labelSelector:
17+
matchExpressions:
18+
- key:"app.kubernetes.io/instance"
19+
operator:"In"
20+
values: ["${release_name}"]
21+
env:
22+
%{~ifworkspace_proxy ~}
23+
- name:"CODER_ACCESS_URL"
24+
value:"${access_url}"
25+
- name: CODER_PRIMARY_ACCESS_URL
26+
value:"${primary_url}"
27+
- name: CODER_PROXY_SESSION_TOKEN
28+
valueFrom:
29+
secretKeyRef:
30+
key: token
31+
name:"${proxy_token}"
32+
%{~ endif ~}
33+
%{~ifprovisionerd ~}
34+
- name:"CODER_URL"
35+
value:"${access_url}"
36+
- name:"CODER_PROVISIONERD_TAGS"
37+
value:"scope=organization"
38+
- name:"CODER_CONFIG_DIR"
39+
value:"/tmp/config"
40+
%{~ endif ~}
41+
%{~if!workspace_proxy&&!provisionerd ~}
42+
- name:"CODER_ACCESS_URL"
43+
value:"${access_url}"
44+
- name:"CODER_PG_CONNECTION_URL"
45+
valueFrom:
46+
secretKeyRef:
47+
name:"${db_secret}"
48+
key: url
49+
- name:"CODER_PROVISIONER_DAEMONS"
50+
value:"0"
51+
- name: CODER_PROVISIONER_DAEMON_PSK
52+
valueFrom:
53+
secretKeyRef:
54+
key: psk
55+
name:"${provisionerd_psk}"
56+
- name:"CODER_PROMETHEUS_COLLECT_AGENT_STATS"
57+
value:"true"
58+
- name:"CODER_PROMETHEUS_COLLECT_DB_METRICS"
59+
value:"true"
60+
- name:"CODER_PPROF_ENABLE"
61+
value:"true"
62+
%{~ endif ~}
63+
- name:"CODER_CACHE_DIRECTORY"
64+
value:"/tmp/coder"
65+
- name:"CODER_TELEMETRY_ENABLE"
66+
value:"false"
67+
- name:"CODER_LOGGING_HUMAN"
68+
value:"/dev/null"
69+
- name:"CODER_LOGGING_STACKDRIVER"
70+
value:"/dev/stderr"
71+
- name:"CODER_PROMETHEUS_ENABLE"
72+
value:"true"
73+
- name:"CODER_VERBOSE"
74+
value:"true"
75+
- name:"CODER_EXPERIMENTS"
76+
value:"${experiments}"
77+
- name:"CODER_DANGEROUS_DISABLE_RATE_LIMITS"
78+
value:"true"
79+
image:
80+
repo: ${image_repo}
81+
tag: ${image_tag}
82+
replicaCount:"${replicas}"
83+
resources:
84+
requests:
85+
cpu:"${cpu_request}"
86+
memory:"${mem_request}"
87+
limits:
88+
cpu:"${cpu_limit}"
89+
memory:"${mem_limit}"
90+
securityContext:
91+
readOnlyRootFilesystem:true
92+
%{~if!provisionerd ~}
93+
service:
94+
enable:true
95+
sessionAffinity: None
96+
loadBalancerIP:"${ip_address}"
97+
%{~ endif ~}
98+
volumeMounts:
99+
- mountPath:"/tmp"
100+
name: cache
101+
readOnly:false
102+
volumes:
103+
- emptyDir:
104+
sizeLimit: 1024Mi
105+
name: cache
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
data"http""coder_healthy" {
2+
url=local.deployments.primary.url
3+
// Wait up to 5 minutes for DNS to propagate
4+
retry {
5+
attempts=30
6+
min_delay_ms=10000
7+
}
8+
9+
lifecycle {
10+
postcondition {
11+
condition=self.status_code==200
12+
error_message="${self.url} returned an unhealthy status code"
13+
}
14+
}
15+
16+
depends_on=[helm_release.coder_primary,cloudflare_record.coder["primary"]]
17+
}
18+
19+
resource"null_resource""api_key" {
20+
provisioner"local-exec" {
21+
interpreter=["/bin/bash","-c"]
22+
command=<<EOF
23+
set -e
24+
25+
curl '${local.deployments.primary.url}/api/v2/users/first' \
26+
--data-raw $'{"email":"${local.coder_admin_email}","password":"${local.coder_admin_password}","username":"${local.coder_admin_user}","name":"${local.coder_admin_full_name}","trial":false}' \
27+
--insecure --silent --output /dev/null
28+
29+
session_token=$(curl '${local.deployments.primary.url}/api/v2/users/login' \
30+
--data-raw $'{"email":"${local.coder_admin_email}","password":"${local.coder_admin_password}"}' \
31+
--insecure --silent | jq -r .session_token)
32+
33+
echo -n $${session_token} >${path.module}/.coderv2/session_token
34+
35+
api_key=$(curl '${local.deployments.primary.url}/api/v2/users/me/keys/tokens' \
36+
-H "Coder-Session-Token: $${session_token}" \
37+
--data-raw '{"token_name":"terraform","scope":"all"}' \
38+
--insecure --silent | jq -r .key)
39+
40+
echo -n $${api_key} >${path.module}/.coderv2/api_key
41+
EOF
42+
}
43+
44+
depends_on=[data.http.coder_healthy]
45+
}
46+
47+
data"local_file""api_key" {
48+
filename="${path.module}/.coderv2/api_key"
49+
depends_on=[null_resource.api_key]
50+
}
51+
52+
resource"null_resource""license" {
53+
provisioner"local-exec" {
54+
interpreter=["/bin/bash","-c"]
55+
command=<<EOF
56+
curl '${local.deployments.primary.url}/api/v2/licenses' \
57+
-H "Coder-Session-Token:${trimspace(data.local_file.api_key.content)}" \
58+
--data-raw '{"license":"${var.coder_license}"}' \
59+
--insecure --silent --output /dev/null
60+
EOF
61+
}
62+
}
63+
64+
resource"null_resource""europe_proxy_token" {
65+
provisioner"local-exec" {
66+
interpreter=["/bin/bash","-c"]
67+
command=<<EOF
68+
curl '${local.deployments.primary.url}/api/v2/workspaceproxies' \
69+
-H "Coder-Session-Token:${trimspace(data.local_file.api_key.content)}" \
70+
--data-raw '{"name":"europe","display_name":"Europe","icon":"/emojis/1f950.png"}' \
71+
--insecure --silent \
72+
| jq -r .proxy_token >${path.module}/.coderv2/europe_proxy_token
73+
EOF
74+
}
75+
76+
depends_on=[null_resource.license]
77+
}
78+
79+
data"local_file""europe_proxy_token" {
80+
filename="${path.module}/.coderv2/europe_proxy_token"
81+
depends_on=[null_resource.europe_proxy_token]
82+
}
83+
84+
resource"null_resource""asia_proxy_token" {
85+
provisioner"local-exec" {
86+
interpreter=["/bin/bash","-c"]
87+
command=<<EOF
88+
curl '${local.deployments.primary.url}/api/v2/workspaceproxies' \
89+
-H "Coder-Session-Token:${trimspace(data.local_file.api_key.content)}" \
90+
--data-raw '{"name":"asia","display_name":"Asia","icon":"/emojis/1f35b.png"}' \
91+
--insecure --silent \
92+
| jq -r .proxy_token >${path.module}/.coderv2/asia_proxy_token
93+
EOF
94+
}
95+
96+
depends_on=[null_resource.license]
97+
}
98+
99+
data"local_file""asia_proxy_token" {
100+
filename="${path.module}/.coderv2/asia_proxy_token"
101+
depends_on=[null_resource.asia_proxy_token]
102+
}
Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
resource"local_file""kubernetes_template" {
2+
filename="${path.module}/.coderv2/templates/kubernetes/main.tf"
3+
content=<<EOF
4+
terraform {
5+
required_providers {
6+
coder = {
7+
source = "coder/coder"
8+
version = "~> 0.23.0"
9+
}
10+
kubernetes = {
11+
source = "hashicorp/kubernetes"
12+
version = "~> 2.30"
13+
}
14+
}
15+
}
16+
17+
provider "coder" {}
18+
19+
provider "kubernetes" {
20+
config_path = null # always use host
21+
}
22+
23+
data "coder_workspace" "me" {}
24+
data "coder_workspace_owner" "me" {}
25+
26+
resource "coder_agent" "main" {
27+
os = "linux"
28+
arch = "amd64"
29+
}
30+
31+
resource "kubernetes_pod" "main" {
32+
count = data.coder_workspace.me.start_count
33+
metadata {
34+
name = "coder-$${lower(data.coder_workspace_owner.me.name)}-$${lower(data.coder_workspace.me.name)}"
35+
namespace = "${local.coder_namespace}"
36+
labels = {
37+
"app.kubernetes.io/name" = "coder-workspace"
38+
"app.kubernetes.io/instance" = "coder-workspace-$${lower(data.coder_workspace_owner.me.name)}-$${lower(data.coder_workspace.me.name)}"
39+
}
40+
}
41+
spec {
42+
security_context {
43+
run_as_user = "1000"
44+
fs_group = "1000"
45+
}
46+
container {
47+
name = "dev"
48+
image = "${var.workspace_image}"
49+
image_pull_policy = "Always"
50+
command = ["sh", "-c", coder_agent.main.init_script]
51+
security_context {
52+
run_as_user = "1000"
53+
}
54+
env {
55+
name = "CODER_AGENT_TOKEN"
56+
value = coder_agent.main.token
57+
}
58+
resources {
59+
requests = {
60+
"cpu" = "${local.scenarios[var.scenario].workspaces.cpu_request}"
61+
"memory" = "${local.scenarios[var.scenario].workspaces.mem_request}"
62+
}
63+
limits = {
64+
"cpu" = "${local.scenarios[var.scenario].workspaces.cpu_limit}"
65+
"memory" = "${local.scenarios[var.scenario].workspaces.mem_limit}"
66+
}
67+
}
68+
}
69+
70+
affinity {
71+
node_affinity {
72+
required_during_scheduling_ignored_during_execution {
73+
node_selector_term {
74+
match_expressions {
75+
key = "cloud.google.com/gke-nodepool"
76+
operator = "In"
77+
values = ["${google_container_node_pool.node_pool["primary_workspaces"].name}","${google_container_node_pool.node_pool["europe_workspaces"].name}","${google_container_node_pool.node_pool["asia_workspaces"].name}"]
78+
}
79+
}
80+
}
81+
}
82+
}
83+
}
84+
}
85+
EOF
86+
}
87+
88+
resource"kubernetes_config_map""template" {
89+
provider=kubernetes.primary
90+
91+
metadata {
92+
name="coder-template"
93+
namespace=kubernetes_namespace.coder_primary.metadata.0.name
94+
}
95+
96+
data={
97+
"main.tf"= local_file.kubernetes_template.content
98+
}
99+
}
100+
101+
resource"kubernetes_job""push_template" {
102+
provider=kubernetes.primary
103+
104+
metadata {
105+
name="${var.name}-push-template"
106+
namespace=kubernetes_namespace.coder_primary.metadata.0.name
107+
labels={
108+
"app.kubernetes.io/name"="${var.name}-push-template"
109+
}
110+
}
111+
spec {
112+
completions=1
113+
template {
114+
metadata {}
115+
spec {
116+
affinity {
117+
node_affinity {
118+
required_during_scheduling_ignored_during_execution {
119+
node_selector_term {
120+
match_expressions {
121+
key="cloud.google.com/gke-nodepool"
122+
operator="In"
123+
values=["${google_container_node_pool.node_pool["primary_misc"].name}"]
124+
}
125+
}
126+
}
127+
}
128+
}
129+
container {
130+
name="cli"
131+
image="${var.coder_image_repo}:${var.coder_image_tag}"
132+
command=[
133+
"/opt/coder",
134+
"--verbose",
135+
"--url=${local.deployments.primary.url}",
136+
"--token=${trimspace(data.local_file.api_key.content)}",
137+
"templates",
138+
"push",
139+
"--directory=/home/coder/template",
140+
"--yes",
141+
"kubernetes"
142+
]
143+
volume_mount {
144+
name="coder-template"
145+
mount_path="/home/coder/template/main.tf"
146+
sub_path="main.tf"
147+
}
148+
}
149+
volume {
150+
name="coder-template"
151+
config_map {
152+
name=kubernetes_config_map.template.metadata.0.name
153+
}
154+
}
155+
restart_policy="Never"
156+
}
157+
}
158+
}
159+
wait_for_completion=true
160+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp