Configuring Applications
To define an Application, create a Prodvana config.
application:
name: my-app # replace with your desired app name
releaseChannels:
- name: staging
runtimes:
- runtime: my-runtime
- name: production
runtimes:
- runtime: my-other-runtime # can be the same runtime as the previous step
preconditions:
- releaseChannelStable:
releaseChannel: staging
- manualApproval: {}
# add or remove release channels as needed
preconditions
control what must be confirmed before Services can deploy in that Release Channel. In the config above, staging must be deployed before production, and a manual approval must be submitted.
Use pvnctl to apply this config file:
pvnctl configs apply path/to/my-app.pvn.yaml
Once applied, you can see your newly created Application in my-demo-organization.runprodvana.com -> Applications.
Common Examples
Using an Existing Namespace
Each Release Channel maps to a namespace in Kubernetes. By default, Prodvana will automatically create and use a namespace of the format pvn-{app}-rc-{release_channel}
. To use an already existing namespace instead, set the following in the Release Channel config as part of the Runtimes section:
application:
name: my-app # replace with your desired app name
releaseChannels:
- name: staging
runtimes:
- runtime: my-runtime
containerOrchestration:
k8s:
namespace: my-existing-staging-namespace
- name: production
runtimes:
- runtime: my-other-runtime # can be same or different runtime as previous step
containerOrchestration:
k8s:
namespace: my-existing-production-namespace
preconditions:
- releaseChannelStable:
releaseChannel: staging
- manualApproval: {}
Namespace Must Be Created Outside of Prodvana
If the namespace is explicitly set, you are responsible for ensuring the namespace exists before running
pvnctl configs apply
, and for deleting it if the release channel is deleted.If the namespace is not explicitly set, then Prodvana will manage the namespace lifecycle for you automatically.
Beware of Collisions
Prodvana will allow multiple Release Channels to be set to the same namespace in the same runtime, both within the same Application and across multiple Applications. In these cases, you are responsible for making sure the Kubernetes objects do not collide, e.g. by using templated names via constants (see below) or explicitly providing different configs per Release Channel.
With Metadata
Applications can have metadata like descriptions, Application links, and per-Service links. This should be included in the same config file.
application:
... # app config here
applicationMetadata:
description: "description here"
links: # Application level links
- url: "http link for your app"
displayName: "display name"
serviceLinks: # links each Service gets automatically. variables $application and $service gets substituted with application and service names
- url: "http link for your service"
displayName: "display name"
Set Default Env Variables per Release Channel
As part of defining Release Channels, it is possible to define env variables every Service should get. This can be useful for defining variables that should be different per Release Channel, such as a database address.
application:
name: my-app
releaseChannels:
- name: production
policy:
defaultEnv:
MY_ENV_VAR:
value: env-var-value
... # more release channels here
For Kubernetes and Kustomize configs, Prodvana will automatically try to inject these variables into objects it knows about (at the time of this writing, Deployment
, Job
, and Argo Rollout
are supported).
Defining Constants For Templating
As part of defining Release Channels, it is possible to define constants that Services can reference via templates. This can be useful for Release-Channel-specific values, not directly derivable from the Release Channel name, and cannot be passed as environment variables.
application:
name: my-app
releaseChannels:
- name: production
constants:
- name: myConstant
string:
value: myValueForProduction
... # rest of production config here
- name: staging
constants:
- name: myConstant
string:
value: myValueForStaging
... # rest of staging config here
The constant can then be used by Services belonging to the Application in Service configs and external configs such as Kubernetes. Using constants in templating allows most configs to be written once and reused for all Release Channels without pulling in a complex templating language like kustomize.
service:
name: my-service
program:
cmd: [my-cmd, "--arg={{.Constants.myConstant}}"]
...
...
service:
name: my-service
kubernetesConfig:
local:
path: deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 1
template:
metadata:
labels:
app: nginx
myLabelFromConstant: "{{.Constants.myConstant}}"
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
Defining Shared Approvals Between Release Channels
manualApproval
preconditions are scoped to Release Channels. To define approvals that are shared between Release Channels (that is, approving one would approve all), use thesharedManualApproval
.
application:
name: my-app
releaseChannels:
- name: staging
runtimes:
- runtime: my-runtime
- name: production-1
runtimes:
- runtime: my-runtime
preconditions:
- releaseChannelStable:
releaseChannel: staging
- sharedManualApproval:
name: production # name is required and has to match what is defined in other release channels to share approval with
- name: production-2
runtimes:
- runtime: my-runtime
preconditions:
- releaseChannelStable:
releaseChannel: staging
- sharedManualApproval:
name: production # name is required and has to match what is defined in other release channels to share approval with
Requiring a Minimum Number of Unique Approvers
For each approval precondition, you can define that a unique number of approvers must approve before the precondition is marked as satisfied. This can be useful, e.g., for compliance purposes to ensure that more than one person approves a production deployment.
application:
name: my-app
releaseChannels:
- name: staging
runtimes:
- runtime: my-runtime
- name: production
runtimes:
- runtime: my-other-runtime # can be same or different runtime as previous step
preconditions:
- releaseChannelStable:
releaseChannel: staging
- manualApproval:
minApprovers: 2 # this means two different users must approve
minApprovers
also works for sharedManualApproval
. In that case, minApprovers
must be set to the same value across all Release Channels using the shared precondition, otherwise one value arbitrarily wins.
application:
name: my-app
releaseChannels:
- name: staging
runtimes:
- runtime: my-runtime
- name: production-1
runtimes:
- runtime: my-runtime
preconditions:
- releaseChannelStable:
releaseChannel: staging
- sharedManualApproval:
name: production
minApprovers: 2 # must match all other declarations of `sharedManualApproval` with the name `production`
- name: production-2
runtimes:
- runtime: my-runtime
preconditions:
- releaseChannelStable:
releaseChannel: staging
- sharedManualApproval:
name: production
minApprovers: 2
Customizing Rollback and Fast Release Behavior
By default, rollbacks will skip any preconditions, protections, and convergence extensions. The same behavior is also available via our UI when creating a release, with a toggle. To customize this behavior, add the following to your application configuration:
application:
name: my-app
releaseSettings:
bypassSettings: # selectively set these fields as needed
noBypassApprovals: true
noBypassReleaseChannelOrdering: true
noBypassProtections: true
noBypassConvergenceExtensions: true
...
Using Multiple Runtimes of the Same Type in a Single Release Channel
If you have multiple Runtimes of the same type, you can add them all to a Release Channel and have the Service pick which Runtime it should deploy to. This is especially useful if you have multiple Custom Runtimes that serve different types of Services or different Service Instances pick different types of Runtime.
First, add all your Runtimes to a Release Channel. Note that you must come up with a name for each type of Runtime connection to a Release Channel, so you can uniquely identify them.
application:
name: my-app
releaseChannels:
- name: staging
runtimes:
- runtime: my-runtime-type-1-for-staging
name: connection-name-1 # this name is how your Service will choose which Runtime to use. It must be present in all Release Channels.
- runtime: my-runtime-type-2-for-staging
name: connection-name-2
- name: prod
runtimes:
- runtime: my-runtime-type-1-for-prod
name: connection-name-1
- runtime: my-runtime-type-2-for-prod
name: connection-name-2
... # preconditions, protections, other settings as needed
Next, in your Service configuration, identify the Runtime you want via runtimeConnection
.
service:
name: my-service
runtimeConnection: connection-name-1 # this will cause Prodvana to select the Runtime in the Release Channel with this connection name
... # other settings as needed for your Service
If you want, you can also select a different Runtime for each Release Channel, either via template variables or via perReleaseChannel
.
service:
name: my-service
runtimeConnection: connection-name-1
perReleaseChannel:
- releaseChannel: prod
runtimeConnection: connection-name-2
FAQs
Removing Release Channels connected to broken Runtimes
If a Release Channel is connected to a broken or disconnected Runtime, further updates to the Application config will fail until all the broken Release Channels are removed. Make sure to remove all broken release channels simultaneously in a single config update.
Updated 8 months ago