apiVersion: quai.dev/v1beta1 kind: ResourceType metadata: name: vm title: Virtual machine (Terraform) description: One YAML file per VM under envs//vms/. Each environment is a Terraform stack that turns those files into module instances. icon: server category: Compute version: 1.0.0 tags: [terraform, brownfield] spec: locate: strategy: file path: envs/{env}/vms/{name}.yaml params: - name: env title: Environment type: enum discover: true # offer the environments that exist in the repository - name: name title: VM name description: Becomes the file name and the Terraform for_each key. pattern: "[a-z][a-z0-9-]{1,30}" # The contract CI validates every VM file against; the form is generated from it. schema: catalog/schemas/vm.schema.json generate: { kind: identity } ownership: { field: owner } stack: envs/{env} address: module.vm["{name}"] deletion: approval ui: order: [description, template, cpu, memory_gb, disks, network, backup, backup_policy, tags] fields: template: { immutable: true } network.vlan: { immutable: true } backup_policy: { visibleIf: "has(inputs.backup) && inputs.backup" } approval: rules: - name: cost when: params.env == 'prod' && plan.cost.monthlyDelta > 500 approvers: [group:finops] - name: production when: params.env == 'prod' approvers: [group:platform-admins] - name: large-vm # Only when a VM becomes large, not on every change to an already large one. when: inputs.cpu > 8 && !(has(previous.cpu) && previous.cpu > 8) approvers: [group:finops] actions: - name: resize title: Resize icon: maximize inputs: - { name: cpu, title: vCPUs, type: integer, min: 1, max: 32, required: true } - { name: memory_gb, title: Memory (GB), type: integer, min: 1, max: 256, required: true } set: cpu: ${{ action.cpu }} memory_gb: ${{ action.memory_gb }} - name: extend-disk title: Extend system disk icon: hard-drive inputs: - { name: size_gb, title: Size (GB), type: integer, min: 10, max: 4096, required: true } set: disks.0.size_gb: ${{ action.size_gb }}