Domains
A Domain is a logical container for a collection of related Workloads within a Platform and is further subdivided by Environment. Workloads can be added to whatever Domain suits the business, reporting, or development needs of your organization. A Domain consists of one or more Environments, e.g. dev, stage, and prod, which are used to support different stages of a Workload's lifecycle.
Domains are loosely modeled after the notion of Domain-Driven Design (DDD). While Konfigurate does not take a particularly strong stance on DDD or how you structure Workloads, it does encourage the use of APIs to connect services versus sharing databases between them. This is a best practice that Konfigurate embraces because it reduces coupling which makes it easier to evolve services independently. A key aspect of this grouping will make certain tasks harder (though not necessarily impossible), on purpose, such as sharing a database between Domains. It also promotes more durable, product-aligned teams who own different parts of a system.
Domain-Driven Design (DDD) is a software development approach that focuses on modeling software closely around the business domain, using collaboration between developers and domain experts to ensure the software aligns with the business's needs.
Like Platforms, Domains play a critical role in Konfigurate's security and governance story. They allow us to assign permissions to different teams within a Platform. For example, if we have an Ecommerce Platform, we may have an Ecommerce group we grant basic permissions to at the Platform level, then specific Ecommerce teams may have ownership or elevated access within their respective Domains. We can also restrict which cloud services and APIs are available at the Domain level.
The Konfigurate hierarchy that Platforms and Domains provide facilitates a powerful way to enforce enterprise standards for a large organization while allowing for a high degree of flexibility and autonomy for a small organization. Basically, it allows for governance when you need it (and autonomy when you don't). This is particularly valuable for organizations with regulatory or compliance requirements, but it's equally valuable for companies wanting to enforce a "golden path"—that is, an opinionated and supported way of building something within your organization. It supports a DevOps model with significantly more standardization, structure, and efficiency.
Domains comprise several different resources which are created and managed by the Control Plane:
- A Domain GCP folder which houses a project for each of the Domain's Environments
- GCP projects for each Environment
- A Domain CI/CD Service Account
- A Domain GitLab group which houses the repositories for Domain Workloads
- GitLab CI/CD variables set on the Domain group to support Workload Identity Federation
- GitLab SAML group links which map identity provider groups specified on the Domain to GitLab roles
- Environments, which in turn create Domain-Environment Service Accounts
The state of these items, along with the overall status of the Domain, can be viewed in the Konfigurate UI, as shown below.
Domains are managed declaratively using YAML definitions. These definitions live in the Control Plane repository and specify metadata and configuration for the Domain. This configuration includes a number of things:
- Display name of the Domain
- Environments (if not specified, uses the Platform's defaults)
- Cloud services to enable (restricted by Platform's
allowed
list) or disable if relying on the Platform'sdefaults
list (see here) - Group access management
Create a Domain
Domains are created via GitOps. When a Domain YAML definition is committed to the Control Plane's main branch, Konfigurate creates the Domain and all of its associated resources. This YAML can be created directly or using either the Konfigurate UI or Konfigurate CLI.
Below is an example demonstrating how to create a Domain which has dev, stage, and prod environments, enables several GCP services, and sets group permissions.
Refer to the Domain spec for the complete set of Domain configurations.
- YAML
- Konfigurate UI
- Konfigurate CLI
You can create a Domain by applying the YAML definition to the Control Plane repository.
apiVersion: konfig.realkinetic.com/v1alpha8
kind: Domain
metadata:
name: [DOMAIN ID]
namespace: konfig-control-plane
labels:
konfig.realkinetic.com/platform: [PLATFORM ID]
spec:
domainName: [DOMAIN DISPLAY NAME]
gcp:
envs:
- label: dev
- label: stage
- label: prod
services:
enabled:
- cloud-run
- cloud-sql
- pubsub
- redis
groups:
dev:
- dev@example.com
maintainer:
- maintainer@example.com
owner:
- owner@example.com
- Navigate to the homepage of the Konfigurate UI.
- Navigate to the Platform you want to create the Domain within by clicking the Platform in either the side navigation or in the main viewport.
- Click the + DOMAIN button.
- In the Create Domain dialog, enter your Domain information.
- Click SUBMIT.
- This will create a merge request in the Control Plane repository. Once merged, the Domain will be created.
- Ensure the Konfigurate CLI is installed and initialized.
- Run the
konfig domains create
command:
konfig domains create \
--envs=dev,stage,prod \
--enabled-services=cloud-run,cloud-sql,pubsub,redis \
--dev=dev@example.com \
--maintainer=maintainer@example.com \
--owner=owner@example.com \
[PLATFORM ID] [DOMAIN DISPLAY NAME]
- This will create a merge request in the Control Plane repository. Once merged, the Domain will be created.
List Domains
The available Domains within a Platform can be viewed either with the Konfigurate UI or Konfigurate CLI.
- Konfigurate UI
- Konfigurate CLI
- Navigate to the homepage of the Konfigurate UI.
- Navigate to the Platform you want to list Domains for by clicking the Platform in either the side navigation or in the main viewport.
- Domains will be displayed in both the side navigation and in the main viewport.
- Ensure the Konfigurate CLI is installed and initialized.
- Run the
konfig domains list
command:
konfig domains list [PLATFORM ID]
The response looks like the following example:
ID NAME ENVIRONMENTS CREATED READY
menu Menu dev 2024-06-07 20:53:55 +0000 UTC TRUE
ordering Ordering dev 2024-06-07 19:58:50 +0000 UTC TRUE
payment Payment dev 2024-06-07 19:58:50 +0000 UTC TRUE
Get Domain Details
Metadata for a Domain can be retrieved either with the Konfigurate UI or Konfigurate CLI.
- Konfigurate UI
- Konfigurate CLI
- Navigate to the homepage of the Konfigurate UI.
- Navigate to the Platform containing the desired Domain by clicking the Platform in either the side navigation or in the main viewport.
- Locate the desired Domain in the main viewport and click the status icon.
- This will expand a sidebar containing information about the Domain such as links to the Domain in GitLab and GCP as well as its source definition, the Domain status, and the Domain's YAML applied to the Control Plane.
- Ensure the Konfigurate CLI is installed and initialized.
- Run the
konfig domains describe
command:
konfig domains describe [PLATFORM ID] [DOMAIN ID]
The response looks like the following example:
apiVersion: konfig.realkinetic.com/v1alpha8
kind: Domain
metadata:
name: menu
creationTimestamp: 2024-06-07T20:53:55Z
labels:
konfig.realkinetic.com/platform: ecommerce
spec:
domainName: Menu
gcp:
createProjects: true
enableWorkloadIdentity: true
manageFolder: true
envs:
- label: dev
gitlab:
manageCIVars: true
manageGroup: true
serviceAccountNameVar: GCP_SA_EMAIL
groups:
dev:
- ecomm-menu-devs@realkinetic.com
maintainer:
- ecomm-menu-maintainers@realkinetic.com
owner:
- gitlab-owners@realkinetic.com
status:
conditions:
- lastTransitionTime: 2024-06-11T22:33:35.443387Z
lastUpdateTime: 2024-08-09T15:55:52.528737Z
message: Konfigurate Platform ready
reason: Ready
status: "True"
type: Platform
- lastTransitionTime: 2024-06-11T22:33:35.443422Z
lastUpdateTime: 2024-08-09T15:55:52.528798Z
message: Domain GCP Folder ready
reason: Ready
status: "True"
type: DomainFolder
- lastTransitionTime: 2024-06-11T22:33:35.443451Z
lastUpdateTime: 2024-08-09T15:55:52.528854Z
message: Domain Gitlab Group ready
reason: Ready
status: "True"
type: GitlabGroup
- lastTransitionTime: 2024-06-11T22:33:35.443483Z
lastUpdateTime: 2024-08-09T15:55:52.528909Z
message: Gitlab Group SAML Links ready
reason: Ready
status: "True"
type: GitlabGroupSAML
- lastTransitionTime: 2024-06-11T22:33:35.443519Z
lastUpdateTime: 2024-08-09T15:55:52.528961Z
message: Gitlab Group Variables ready
reason: Ready
status: "True"
type: GitlabCIVariables
- lastTransitionTime: 2024-06-11T22:33:35.443571Z
lastUpdateTime: 2024-08-09T15:55:52.529016Z
message: Gitlab CICD Service Account ready
reason: Ready
status: "True"
type: DomainGitlabServiceAccount
- lastTransitionTime: 2024-06-11T22:33:35.44364Z
lastUpdateTime: 2024-08-09T15:55:52.529076Z
message: Domain GCP environments ready
reason: Ready
status: "True"
type: GCPEnvironments
- lastTransitionTime: 2024-06-11T22:33:35.443751Z
lastUpdateTime: 2024-08-09T15:55:52.529298Z
message: Domain ready
reason: Ready
status: "True"
type: Ready
- lastTransitionTime: 2024-06-11T22:34:14.04908Z
lastUpdateTime: 2024-08-09T15:55:52.529139Z
message: GCP dev project ready
reason: Ready
status: "True"
type: GCPEnvironmentDev
state:
gcp:
domainFolderId: "341116298313"
domainServiceAccount:
email: menu-gitlab@konfig-control-plane-mr91es6om.iam.gserviceaccount.com
name: menu-gitlab
namespace: konfig-control-plane
projectResources:
- env: dev
name: menu-dev
namespace: konfig-control-plane
reason: Ready
status: "True"
projects:
- env: dev
id: menu-dev-xahlq
number: "739697333575"
resource_name: menu-dev
services:
- pubsub
- redis
- cloud-run
- cloud-sql
- firestore
gitlab:
group:
gcpSAVarName: GCP_SA_EMAIL
id: "88529853"
path: realkinetic/konfig-demo/ecommerce/menu
saml_links:
dev:
- ecomm-menu-devs
maintainer:
- ecomm-menu-maintainers
owner:
- gitlab-owners
lastReconciled:
generation: 24839
timestamp: 2024-08-09T15:55:52.528633
ready: true
Domain Custom Resource Definition
- v1alpha8
Name | Type | Description | Required |
---|---|---|---|
apiVersion | string | konfig.realkinetic.com/v1alpha8 | true |
kind | string | Domain | true |
metadata | object | Refer to the Kubernetes API documentation for the fields of the metadata field. | true |
spec | object | false | |
status | object | false |
Domain.spec
Name | Type | Description | Required |
---|---|---|---|
domainName | string | Human readable name for the Domain. This must be unique within the Platform because the GCP Folder and Gitlab Group will have this name. Defaults to metadata.name. | true |
gcp | object | Default: map[] | false |
gitlab | object | Default: map[] | false |
groups | object | false |
Domain.spec.gcp
Name | Type | Description | Required |
---|---|---|---|
createProjects | boolean | GCP Projects should be managed by Konfigurate. Default: true | false |
enableWorkloadIdentity | boolean | Setup Workload Identity Federation mapping (and restriction to) the Domain's Gitlab CICD Service Account. Default: true | false |
envs | []object | The (authoritative) set of enviornments to create for this Domain. If not set, the Platform's defaultEnvs will be used. | false |
manageFolder | boolean | GCP Folder should be managed by Konfigurate. Default: true | false |
services | object | false | |
workloadIdentity | object | Default: map[] | false |
Domain.spec.gcp.envs[index]
Name | Type | Description | Required |
---|---|---|---|
label | enum | Enum: dev, stage, prod | true |
name | string | false | |
namespace | string | false | |
subnetName | string | The name of the subnet to associate with this environment. | false |
Domain.spec.gcp.services
Name | Type | Description | Required |
---|---|---|---|
disabled | []enum | List of services to disable for this Domain. This is used to remove services from the Platform's defaults (spec.gcp.services.defaults) list for this Domain. | false |
enabled | []enum | The authoritative list of services to enable for this Domain. This is restricted by the Platform's spec.gcp.services.allowed list. Defaults to the Platform's spec.gcp.services.defaults if not set. Default: [cloud-run cloud-sql pubsub redis firestore bigquery] | false |
Domain.spec.gcp.workloadIdentity
Name | Type | Description | Required |
---|---|---|---|
enabled | boolean | Setup Workload Identity Federation mapping (and restriction to) the Domain's Gitlab CICD Service Account. Default: true | false |
Domain.spec.gitlab
Name | Type | Description | Required |
---|---|---|---|
manageCIVars | boolean | Gitlab CI Vars should be managed by Konfigurate. Default: true | false |
manageGroup | boolean | Gitlab Group should be managed by Konfigurate. Default: true | false |
serviceAccountNameVar | string | The Gitlab project CICD variable that will store the GCP IAM Service Account name (email). Default: GCP_SA_EMAIL | false |
Domain.spec.groups
Name | Type | Description | Required |
---|---|---|---|
dev | []string | If set, this group will be added to the dev GCP Project as 'Editor', and 'Viewer' to non-dev Projects. It will be added to the Gitlab Group as developer. | false |
maintainer | []string | If set, this group will be added to the dev GCP Project as 'Editor', and 'Viewer' to non-dev Projects. It will be added to the Gitlab Group as maintainer. | false |
owner | []string | If set, this group will be added to all GCP Projects as 'Editor'. It will be added to the Gitlab Group as maintainer. | false |
Domain.status
Name | Type | Description | Required |
---|---|---|---|
gcp | object | false | |
gitlab | object | false | |
lastReconciled | object | false | |
ready | boolean | false |
Domain.status.gcp
Name | Type | Description | Required |
---|---|---|---|
domainFolderId | string | false | |
domainServiceAccount | string | false | |
projectResources | []object | false |
Domain.status.gcp.projectResources[index]
Name | Type | Description | Required |
---|---|---|---|
env | string | false | |
name | string | false | |
namespace | string | false | |
reason | string | false | |
status | string | false |
Domain.status.gitlab
Name | Type | Description | Required |
---|---|---|---|
group | object | false |
Domain.status.gitlab.group
Name | Type | Description | Required |
---|---|---|---|
configsProjectId | string | false | |
gcpSAVarName | string | false | |
id | string | false | |
path | string | false |
Domain.status.lastReconciled
Name | Type | Description | Required |
---|---|---|---|
generation | integer | false | |
timestamp | string | false |