平台
Pulumi堆栈为CYC社区帆船中心的共享谷歌云平台:东西不单一 应用程序拥有。运行在它上面的应用程序都在它们自己的仓库里,比如 isthmia.
栈
| 堆栈 | 持有 | 应用的 |
|---|---|---|
bootstrap | 服务帐户和项目IAM, Pulumi状态桶和KMS密钥,以及组织的GitHub仓库和设置 | 具有项目所有者和 gh admin:org. 从不CI。 |
infra | VPC、集群子网及其静态地址上的Cloud NAT、私有服务对等、prod和dev Cloud SQL实例、DNS区域、Artifact Registry、GKE Autopilot集群、共享网关、共享网关的地址、证书和dev的DNS记录 dev 和 prod 名称空间及其配额和网络策略、开发人员的RBAC、生产作业警报以及每个环境的RBAC platform/outputs.json | deploy-runner,从批准后的行动。部署者,使用 mise run deploy,打碎玻璃。 |
smoke | 一个 WebService 在开发中, smoke.dev.cycsail.team,用于集成测试 | deploy-dev,从每个PR的行动,一个部署者,与 PULUMI_STACK=dev mise run deploy,打碎玻璃。 |
backend | Directus,带模式apply from schemas/、它的角色、策略和权限规则、同步机用户、它的OIDC客户端和MCP、Clubspot -sync和gsuite-sync CronJobs,以及开发人员的Clubspot和Workspace冒名 | deploy-dev,从行动的每一个公关,和 deploy-runner 急于做某事 main后, infra. |
@cyc-seattle /平台
src/ 是 @cyc-seattle/platform 包,这里的堆栈和应用程序的堆栈导入:
getPlatformOutputs()读取环境的platform/outputs.json从它的状态桶中。这个infra是Stack写的。它保存环境的名称空间和域、Gateway及其 地址(gatewayAddress(用于应用程序自己的DNS记录),以及云SQL实例的连接 名称及私人IP (sqlHost). Dev栈不能读取prod的后端,所以这个代替了a StackReference平台值(cyc-seattle/isthmia#215)。clusterProvider(platform)为集群构建Kubernetes提供程序。它的kubecconfig运行gke-gcloud-auth-plugin使用应用程序默认凭据,因此Pulumi必须在mise下运行, 哪里mise run install打开插件PATH.Workload运行没有路由的长寿命流程:部署、ServiceAccount,当它运行时 有ports名称空间中的其他pod可以访问的ClusterIP服务host. 有超过 一个副本,spreadAcrossZones传播它们,并且minAvailable添加PodDisruptionBudget。podAnnotations设置注释,例如cluster-autoscaler.kubernetes.io/safe-to-evict.WebService是一个Workload在环境的门户后面hostname. 它的服务暴露port作为端口80,并且它的就绪探测必须是HTTP GET,这表明负载平衡器的运行状况 检查重用。ScheduledJob运行CronJobschedule,在America/Los_Angeles除非timeZone说 否则。默认情况下,运行不会与之前的运行重叠,会获得一个小时,并且不会重试。- 这三个都是非root运行的,使用只读的根文件系统,没有功能,也没有服务帐户
令牌,仅在开发中的Spot pods上使用。他们的极限等于他们的要求。他们的豆荚没有IAM;格兰特
角色
member、工作负载标识主体或集合serviceAccountAnnotations作为…运行 谷歌业务帐户。 enableService启用谷歌云API。
mise run build 把它构建到 dist/,这是它的全部出版内容。 .github/workflows/release.yml
将每个合并释放到 main 使用语义发布,由常规提交进行版本控制。
环境
每个应用程序都运行在一个GKE自动驾驶集群上,在其环境的命名空间中。项目继续进行
常规容量,并在Spot pod上开发。isthmia的应用程序(Authentik, Directus, portal和the
两个同步(如CronJobs)同时运行,dev添加了Mailpit、Clubspot和Workspace fakes。在开发,
平台的 backend 部署Directus,同步和伪造,以及dev的同步CronJobs
暂停:集成功能和 mise run reset 运行它们作为Jobs (cyc-seattle/isthmia#271)。
| 堆栈 | 名称空间 | 域 | 部署身份 |
|---|---|---|---|
dev | dev | dev.cycsail.team | deploy-dev |
prod | prod | cycsail.team | deploy-runner |
除了负载平衡器的名称空间之外,每个名称空间都拒绝来自其他名称空间的访问。戴夫也承认
集成测试使用的Kubernetes API的服务代理拒绝向邮件端口出口
(25,465, 587)在群集外。 infra 写开发者的A记录;每个prod应用程序都有自己的程序,
指着 gatewayAddress.
deploy-dev 读取id以开头的Secret Manager机密 dev-. 阅读它们
gcp.secretmanager.getSecretVersionAccess,它只需要访问器角色。
infra 创建每个应用的开发数据库、用户和密码(dev-db-<name>-password)
cyc-dev,为每一个名字 infra:devDatabases. 要添加应用的开发数据库,请将其名称添加到
平台PR:云SQL忽略用户和数据库调用的IAM条件,所以 deploy-dev 不能
保持角色的作用域为 cyc-dev.
一项失败的工作 prod,或者那里的CronJob在3小时内没有成功的Job,则会发出警报。
它把每个地址都发邮件进来 infra:alertEmails,堆栈配置中的一个秘密,它保存
维护者的地址(#20)。
设置
协定 提供工具。
mise trust
mise run install
mise run auth-adc
mise run auth-adc 将应用程序默认凭据记录为您自己的帐户。Pulumi使用它们
用于GCP和状态桶。 文档/ manual-setup.md 列出了访问
首先是部署者的需求。
部署
从行动
.github/workflows/pull-request.yml 通过组织的可重用性进行部署 deploy.yml,这
使用工作负载标识联合进行身份验证,并且不存储凭据。每个作业运行在
保存其身份和状态桶的GitHub环境:
| 事件 | 工作,按顺序 |
|---|---|
| 把请求 | ci,然后 dev: mise run deploy 作为 deploy-dev,然后 mise run integration |
推动 main | ci, dev,然后 prod-preview,然后 prod,它等待 maintainers 批准 |
prod-preview 运行 mise run preview 作为 deploy-runner 并将困难写在工作总结中。
prod 运行 mise run deploy 在同一个提交上,一旦被批准。它只在预览显示时运行
更改,因此在prod中没有更改的合并不需要批准。Dev构建同步映像
每次提交,prod的CronJobs都会运行为他们构建的,所以直到cyc-seattle/isthmia#258
每个合并预览 backend的克朗乔布斯已经改变了。来自分支的PR没有得到OIDC令牌,所以它
dev 跳过任务。
PULUMI_STACK 选择任务运行的内容(scripts/each-stack): dev 是 smoke,然后 backend,
prod 是 infra,然后 backend. integration 仅限dev。
bootstrap 从未从行动(cyc-seattle/isthmia#118)部署。它包含了恒等式
CI假设,并且具有项目所有者和 gh admin:org 将其应用于下面的任务。
从笔记本电脑
局部部署停留在破玻璃路径上。部署者应用相同的任务:
mise run preview-bootstrap
mise run deploy-bootstrap
mise run preview
mise run deploy
PULUMI_STACK=dev mise run deploy
mise run deploy 适用于 infra,然后 backend. isthmia的prod堆栈通过一个StackReference读取它的输出。
开发栈不能读取prod状态,所以 infra 写入每个环境的平台
值 platform/outputs.json 在该环境的状态桶中。
bootstrap的GitHub提供程序使用 gh auth token,那么log gh 作为cyc-seattle组织的所有者
这个 admin:org 范围: gh auth refresh -h github.com -s admin:org. 首先部署刷新,因此它们
删除手工添加的标签。
状态
每个环境的状态都在自己的桶中, gs://cyc-admin-scripts-pulumi-<stack>,有它的
由 state-<stack> 公里的关键。 stacks/bootstrap/state.ts 创建了两个。
mise.toml 把桶从 PULUMI_STACK,默认为 prod,所以堆栈名称是
organization/<project>/<stack>. 它集 GOOGLE_APPLICATION_CREDENTIALS 共享的 .gcloud/
只在尚未设置时登录,因此Actions的凭据获胜。
bootstrap的自己的状态存在于它创建的桶中。桶和密钥都受到保护。
开发
mise run ci
运行类型检查、Prettier、ESLint和单元测试。测试用
pulumi.runtime.setMocks 永远不要调用实时API。
mise run integration
运行小黄瓜场景 features/ 反对dev, after PULUMI_STACK=dev mise run deploy. 它们的运行方式是
应用程序默认凭据持有的任何身份。隔离方案期望 deploy-dev,
因此,作为一个人,记录应用程序默认凭据 --impersonate-service-account 第一。