{ "$ref": "#/definitions/stage", "$schema": "http://json-schema.org/draft-07/schema#", "definitions": { "app": { "$id": "#app", "additionalProperties": false, "properties": { "container": { "type": "object", "$ref": "#/definitions/container" }, "custom_domains": { "type": "object", "patternProperties": { "^(\\*\\.)?[a-z][a-z0-9-.]{3,}$": { "$ref": "#/definitions/custom_domain" } }, "additionalProperties": false }, "env": { "$comment": "The namespace starting with 'SETOPS_' is reserved and can not be used.", "patternProperties": { "^SETOPS_": { "not": {} }, "^[a-zA-Z_][a-zA-Z0-9_]{0,255}$": { "$ref": "#/definitions/env_variable" } }, "additionalProperties": false }, "links": { "patternProperties": { "^[a-z][a-z0-9-]{2,17}$": { "oneOf": [ { "$ref": "#/definitions/env_link" }, { "$ref": "#/definitions/volume_link" } ] } }, "additionalProperties": false }, "network": { "type": "object", "$ref": "#/definitions/network" }, "resources": { "type": "object", "$ref": "#/definitions/resources" }, "schedule": { "patternProperties": { "^[a-z][a-z0-9-]{2,53}$": { "$ref": "#/definitions/app_schedule" } }, "additionalProperties": false } }, "type": "object" }, "app_schedule": { "$id": "#app_schedule", "type": "object", "required": [ "command", "entrypoint", "schedule" ], "properties": { "command": { "type": "array", "items": { "type": "string" } }, "entrypoint": { "type": "array", "items": { "type": "string" } }, "schedule": { "type": "string" }, "resources": { "$ref": "#/definitions/app_schedule_resources" }, "retry": { "type": "object", "properties": { "max_attempts": { "type": "integer", "minimum": 0, "maximum": 185, "default": 60 }, "max_time_in_seconds": { "type": "integer", "minimum": 60, "maximum": 86400, "default": 86400 } }, "additionalProperties": false } }, "additionalProperties": false }, "app_schedule_resources": { "$id": "#resources", "type": "object", "properties": { "cpu": { "type": "integer", "multipleOf": 128, "minimum": 128, "maximum": 10240, "default": 128 }, "memory": { "type": "integer", "multipleOf": 128, "minimum": 128, "maximum": 30720, "default": 128 } }, "additionalProperties": false }, "container": { "$id": "#container", "type": "object", "properties": { "command": { "type": "array", "items": { "type": "string" } }, "entrypoint": { "type": "array", "items": { "type": "string" } }, "health_check": { "type": "object", "$ref": "#/definitions/container_health_check" } }, "additionalProperties": false }, "container_health_check": { "$id": "#container_health_check", "type": "object", "required": [ "command", "interval", "timeout", "retries", "start_period" ], "properties": { "command": { "type": "array", "items": { "type": "string" }, "minItems": 1 }, "interval": { "type": "number" }, "timeout": { "type": "number" }, "retries": { "type": "number" }, "start_period": { "type": "number" } }, "additionalProperties": false }, "custom_domain": { "$id": "#custom_domain", "type": "object", "required": [ "primary", "validated" ], "anyOf": [ { "properties": { "primary": { "type": "boolean", "const": true }, "static_ips": { "type": "boolean", "default": false }, "validated": { "type": "boolean" } }, "additionalProperties": false }, { "properties": { "primary": { "type": "boolean", "const": false }, "redirect_to_primary": { "type": "boolean", "default": true }, "static_ips": { "type": "boolean", "default": false }, "validated": { "type": "boolean" } }, "additionalProperties": false } ] }, "env_link": { "$id": "#env_link", "$comment": "The namespace starting with 'SETOPS_' is reserved and can not be used.", "type": "object", "required": [ "env_key" ], "properties": { "env_key": { "type": "string", "pattern": "^[a-zA-Z_][a-zA-Z0-9_]{0,255}$", "not": { "pattern": "^SETOPS_" } } }, "additionalProperties": false }, "env_variable": { "$id": "#env_variable", "type": "object", "required": [ "value" ], "properties": { "value": { "type": "string", "minLength": 1, "maxLength": 8192 }, "description": { "type": "string" } }, "additionalProperties": false }, "network": { "$id": "#network", "type": "object", "required": [ "protocol", "ports" ], "properties": { "protocol": { "type": "string", "enum": [ "http", "tcp" ] }, "public": { "type": "boolean", "default": false }, "public_ipv4_allowlist": { "type": "array", "minItems": 1, "items": { "type": "string", "pattern": "^(([0-9]|[0-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[0-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\/([0-9]|[1-2][0-9]|3[0-2])$" }, "default": [ "0.0.0.0/0" ] }, "public_ipv6_allowlist": { "type": "array", "minItems": 1, "items": { "type": "string", "pattern": "^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*(\/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8]))?$" }, "default": [ "::/0" ] }, "ports": { "type": "array", "items": { "type": "number", "minimum": 1, "maximum": 65535 }, "uniqueItems": true, "default": [ 8000 ] }, "health_check": { "type": "object", "$ref": "#/definitions/network_health_check" } }, "anyOf": [ { "properties": { "protocol": { "const": "http" }, "ports": { "minItems": 1, "maxItems": 1 } } }, { "properties": { "protocol": { "const": "tcp" }, "ports": { "minItems": 1 } } } ], "default": { "protocol": "http", "ports": [ 8000 ] }, "additionalProperties": false }, "network_health_check": { "$id": "#network_health_check", "type": "object", "required": [ "path", "status" ], "properties": { "path": { "type": "string", "pattern": "^/.*$" }, "status": { "type": "string", "pattern": "^([1-4][0-9][0-9](-[1-4][0-9][0-9])?)+(,[1-4][0-9][0-9](-[1-4][0-9][0-9])?)*$" } }, "default": { "path": "/", "status": "200-499" }, "additionalProperties": false }, "notification": { "$id": "#notification", "type": "object", "required": [ "type", "target" ], "properties": { "type": { "type": "string", "enum": [ "webhook", "email" ] }, "target": { "type": "string" } }, "allOf": [ { "if": { "properties": { "type": { "const": "webhook" } } }, "then": { "properties": { "target": { "pattern": "^(http|https)://.*$" } } } }, { "if": { "properties": { "type": { "const": "email" } } }, "then": { "properties": { "target": { "format": "email" } } } } ], "additionalProperties": false }, "resources": { "$id": "#resources", "type": "object", "properties": { "cpu": { "type": "integer", "multipleOf": 128, "minimum": 128, "maximum": 10240, "default": 128 }, "memory": { "type": "integer", "multipleOf": 128, "minimum": 128, "maximum": 30720, "default": 128 }, "scale": { "type": "integer", "minimum": 0, "maximum": 16, "default": 1 } }, "additionalProperties": false }, "service": { "$id": "#service", "type": "object", "oneOf": [ { "$ref": "#/definitions/service_elasticsearch" }, { "$ref": "#/definitions/service_postgresql_shared" }, { "$ref": "#/definitions/service_postgresql" }, { "$ref": "#/definitions/service_s3" }, { "$ref": "#/definitions/service_redis" }, { "$ref": "#/definitions/service_documentdb" }, { "$ref": "#/definitions/service_volume" } ] }, "service_documentdb": { "$id": "#service_documentdb", "type": "object", "required": [ "type", "plan", "version" ], "properties": { "type": { "type": "string", "const": "documentdb" }, "plan": { "type": "string", "enum": [ "db.t3.medium", "db.r5.large", "db.r5.xlarge", "db.r5.2xlarge" ] }, "version": { "type": "string", "enum": [ "4", "5" ] }, "options": { "type": "object", "properties": { "scale": { "type": "integer", "minimum": 0, "maximum": 14, "default": 1 } }, "additionalProperties": false }, "backup_retention_days": { "type": "integer", "default": 14, "minimum": 0, "maximum": 36500 } }, "additionalProperties": false }, "service_elasticsearch": { "$id": "#service_elasticsearch", "type": "object", "required": [ "type", "plan", "version", "options" ], "properties": { "type": { "type": "string", "const": "elasticsearch" }, "plan": { "type": "string", "pattern": "^[a-z0-9]{2,3}\\.[a-z0-9]+\\.elasticsearch(\\.sharded|\\.ha)?$" }, "version": { "type": "string", "const": "7" }, "options": { "type": "object", "required": [ "storage" ], "properties": { "storage": { "type": "integer", "minimum": 10, "maximum": 16384, "default": 10 }, "storage_iops": { "type": "integer", "minimum": 3000, "maximum": 16000, "default": 3000 }, "storage_throughput": { "type": "integer", "minimum": 125, "maximum": 1000, "default": "125" } }, "additionalProperties": false }, "backup_retention_days": { "type": "integer", "const": 14, "default": 14 } }, "additionalProperties": false }, "service_postgresql": { "$id": "#service_postgresql", "type": "object", "required": [ "plan", "options", "version" ], "properties": { "type": { "type": "string", "const": "postgresql" }, "plan": { "type": "string", "enum": [ "db.m6g.16xlarge", "db.m6g.12xlarge", "db.m6g.8xlarge", "db.m6g.4xlarge", "db.m6g.2xlarge", "db.m6g.xlarge", "db.m6g.large", "db.m5.24xlarge", "db.m5.16xlarge", "db.m5.12xlarge", "db.m5.8xlarge", "db.m5.4xlarge", "db.m5.2xlarge", "db.m5.xlarge", "db.m5.large", "db.r6g.16xlarge", "db.r6g.12xlarge", "db.r6g.8xlarge", "db.r6g.4xlarge", "db.r6g.2xlarge", "db.r6g.xlarge", "db.r6g.large", "db.r5.24xlarge", "db.r5.16xlarge", "db.r5.12xlarge", "db.r5.8xlarge", "db.r5.4xlarge", "db.r5.2xlarge", "db.r5.xlarge", "db.r5.large", "db.t3.2xlarge", "db.t3.xlarge", "db.t3.large", "db.t3.medium", "db.t3.small", "db.t3.micro", "db.m6g.16xlarge.ha", "db.m6g.12xlarge.ha", "db.m6g.8xlarge.ha", "db.m6g.4xlarge.ha", "db.m6g.2xlarge.ha", "db.m6g.xlarge.ha", "db.m6g.large.ha", "db.m5.24xlarge.ha", "db.m5.16xlarge.ha", "db.m5.12xlarge.ha", "db.m5.8xlarge.ha", "db.m5.4xlarge.ha", "db.m5.2xlarge.ha", "db.m5.xlarge.ha", "db.m5.large.ha", "db.r6g.16xlarge.ha", "db.r6g.12xlarge.ha", "db.r6g.8xlarge.ha", "db.r6g.4xlarge.ha", "db.r6g.2xlarge.ha", "db.r6g.xlarge.ha", "db.r6g.large.ha", "db.r5.24xlarge.ha", "db.r5.16xlarge.ha", "db.r5.12xlarge.ha", "db.r5.8xlarge.ha", "db.r5.4xlarge.ha", "db.r5.2xlarge.ha", "db.r5.xlarge.ha", "db.r5.large.ha", "db.t3.2xlarge.ha", "db.t3.xlarge.ha", "db.t3.large.ha", "db.t3.medium.ha", "db.t3.small.ha", "db.t3.micro.ha", "db.t4g.micro", "db.t4g.small", "db.t4g.medium", "db.t4g.large", "db.t4g.xlarge", "db.t4g.2xlarge", "db.t4g.micro.ha", "db.t4g.small.ha", "db.t4g.medium.ha", "db.t4g.large.ha", "db.t4g.xlarge.ha", "db.t4g.2xlarge.ha" ] }, "version": { "type": "string", "pattern": "^(13|14|15)\\.[0-9]+$" }, "options": { "type": "object", "properties": { "extensions": { "type": "array", "items": { "type": "string", "enum": [ "address_standardizer", "address_standardizer_data_us", "amcheck", "autoinc", "auto_explain", "aws_commons", "aws_lambda", "aws_s3", "aws_s3.table_import_from_s3", "bloom", "bool_plperl", "btree_gin", "btree_gist", "citext", "cube", "dblink", "dict_int", "dict_xsyn", "earthdistance", "flow_control", "fuzzystrmatch", "hll", "hstore", "hstore_plperl", "hypopg", "icu-modul", "insert_username", "intagg", "intarray", "ip4r", "isn", "jsonb_plperl", "lo", "log_fdw", "ltree", "mysql_fdw", "moddatetime", "alter_Snapshot", "oracle_fdw", "orafce", "pageinspect", "pg_bigm", "pg_buffercache", "pg_cron", "pg_freespacemap", "pg_hint_plan", "pg_partman", "pg_prewarm", "pg_proctab", "pg_repack", "pg_similarity", "pg_stat_statements", "pg_tle", "pg_transport", "pg_trgm", "pg_visibility", "pg_walinspect", "pgaudit", "pgcrypto", "pglogical", "pgrouting", "pgrowlocks", "pgstattuple", "pgtap", "pg-vektor", "plcoffee", "plls", "plperl", "plpgsql", "plprofiler", "plust", "pltcl", "plv", "postgis", "postgis_raster", "postgis_tiger_geocoder", "postgis_topology", "postgres_fdw", "prefix", "rdkit", "rds_tools", "refint", "seg", "sslinfo", "tablefunc", "tcn", "tds_fdw", "test_parser", "tsm_system_rows", "tsm_system_time", "unaccent", "uuid-ossp", "wal2json" ] } }, "min_storage": { "type": "integer", "minimum": 20, "maximum": 16383, "default": 20 }, "max_storage": { "type": "integer", "minimum": 21, "maximum": 16384, "default": 20 }, "storage_iops": { "type": "integer", "minimum": 3000, "maximum": 16000, "default": 3000 }, "storage_throughput": { "type": "integer", "minimum": 125, "maximum": 1000, "default": 125 } }, "additionalProperties": false }, "backup_retention_days": { "type": "integer", "default": 14, "minimum": 0, "maximum": 3650 } }, "additionalProperties": false }, "service_postgresql_shared": { "$id": "#service_postgresql_shared", "type": "object", "required": [ "type", "plan" ], "properties": { "type": { "type": "string", "const": "postgresql" }, "plan": { "type": "string", "const": "shared" }, "version": { "$comment": "the version field is ignored for shared plans but reserved for future version selection", "type": "string" }, "options": { "type": "object", "properties": { "extensions": { "type": "array", "items": { "type": "string", "enum": [ "address_standardizer", "address_standardizer_data_us", "amcheck", "autoinc", "auto_explain", "aws_commons", "aws_lambda", "aws_s3", "aws_s3.table_import_from_s3", "bloom", "bool_plperl", "btree_gin", "btree_gist", "citext", "cube", "dblink", "dict_int", "dict_xsyn", "earthdistance", "flow_control", "fuzzystrmatch", "hll", "hstore", "hstore_plperl", "hypopg", "icu-modul", "insert_username", "intagg", "intarray", "ip4r", "isn", "jsonb_plperl", "lo", "log_fdw", "ltree", "mysql_fdw", "moddatetime", "alter_Snapshot", "oracle_fdw", "orafce", "pageinspect", "pg_bigm", "pg_buffercache", "pg_cron", "pg_freespacemap", "pg_hint_plan", "pg_partman", "pg_prewarm", "pg_proctab", "pg_repack", "pg_similarity", "pg_stat_statements", "pg_tle", "pg_transport", "pg_trgm", "pg_visibility", "pg_walinspect", "pgaudit", "pgcrypto", "pglogical", "pgrouting", "pgrowlocks", "pgstattuple", "pgtap", "pg-vektor", "plcoffee", "plls", "plperl", "plpgsql", "plprofiler", "plust", "pltcl", "plv", "postgis", "postgis_raster", "postgis_tiger_geocoder", "postgis_topology", "postgres_fdw", "prefix", "rdkit", "rds_tools", "refint", "seg", "sslinfo", "tablefunc", "tcn", "tds_fdw", "test_parser", "tsm_system_rows", "tsm_system_time", "unaccent", "uuid-ossp", "wal2json" ] }, "uniqueItems": true } }, "additionalProperties": false } }, "additionalProperties": false }, "service_redis": { "$id": "#service_redis", "type": "object", "required": [ "type", "plan", "version" ], "properties": { "type": { "type": "string", "const": "redis" }, "plan": { "type": "string", "pattern": "^cache\\.[a-z0-9]{2,3}\\.[a-z0-9]+$" }, "version": { "type": "string", "pattern": "^(6|7)\\.[0-9]+$" }, "options": { "type": "object" }, "backup_retention_days": { "type": "integer", "default": 14, "minimum": 0, "maximum": 35 } }, "additionalProperties": false }, "service_s3": { "$id": "#service_s3", "type": "object", "required": [ "type" ], "properties": { "type": { "type": "string", "const": "s3" }, "options": { "type": "object", "properties": { "block_public_access": { "type": "boolean", "default": "true" }, "cors_rules": { "type": "array", "items": { "type": "object", "required": [ "allowed_headers", "allowed_methods", "allowed_origins" ], "properties": { "allowed_headers": { "type": "array", "items": { "type": "string", "minLength": 1 } }, "allowed_methods": { "type": "array", "minItems": 1, "items": { "type": "string", "enum": [ "GET", "PUT", "POST", "DELETE", "HEAD" ] } }, "allowed_origins": { "type": "array", "minItems": 1, "items": { "type": "string", "minLength": 1 } }, "expose_headers": { "type": "array", "items": { "type": "string", "minLength": 1 } }, "max_age_seconds": { "type": "integer", "minimum": 0, "maximum": 86400 } } } } }, "additionalProperties": false }, "backup_retention_days": { "type": "integer", "default": 14, "minimum": 0, "maximum": 36500 } }, "additionalProperties": false }, "service_volume": { "$id": "#service_volume", "type": "object", "required": [ "type" ], "properties": { "type": { "type": "string", "enum": [ "volume" ] }, "plan": { "type": "string", "enum": [ "" ] }, "options": { "type": "object" }, "backup_retention_days": { "type": "integer", "default": 14, "minimum": 0, "maximum": 36500 } }, "additionalProperties": false }, "stage": { "$id": "#stage", "type": "object", "required": [ "schema_version", "project", "stage" ], "properties": { "schema_version": { "type": "string", "const": "2" }, "project": { "type": "string", "minLength": 3, "maxLength": 20, "pattern": "^[a-z][a-z0-9]{2,19}$" }, "stage": { "type": "string", "minLength": 3, "maxLength": 12, "pattern": "^[a-z][a-z0-9]{2,11}$" }, "apps": { "type": "object", "minProperties": 0, "minLength": 3, "maxLength": 16, "patternProperties": { "^[a-z][a-z0-9-]{2,15}$": { "$ref": "#/definitions/app" } }, "default": {}, "additionalProperties": false }, "services": { "type": "object", "patternProperties": { "^[a-z][a-z0-9-]{2,17}$": { "$ref": "#/definitions/service" } }, "default": {}, "additionalProperties": false }, "log_retention": { "type": "number", "minimum": 0, "maximum": 365, "default": 14 }, "notifications": { "type": "object", "minLength": 3, "maxLength": 32, "patternProperties": { "^[a-z][a-z0-9-]{2,31}$": { "$ref": "#/definitions/notification" } }, "additionalProperties": false } }, "additionalProperties": false }, "volume_link": { "$id": "#volume_link", "type": "object", "required": [ "path", "read_only" ], "properties": { "path": { "type": "string", "pattern": "^/.+$" }, "read_only": { "type": "boolean" } }, "additionalProperties": false } }, "title": "SetOps Schema" }