Namespace parameters declare required user input for a particular namespace of a template. They are used to dynamically generate the wizard when a user selects a particular template in the UI. Parameters can only be consumed in the manifest file that declared them.
Each parameter declaration needs to have the following defined:
If no other properties are defined, a simple text input type with no input validation will be assumed.
Here's an example namespace manifest using the "local://vsts/namespaces/repos/v1" namespace provider with a basic parameter declaration:
namespace: repos
schema: local://vsts/namespaces/repos/v1
parameters:
- id: RepositoryName
display: Repository name
payload:
repositories:
- id: repository
stage: Incubation
name: '{RepositoryName}'
This manifest declares a single git repository and nothing else. It is expecting the user to supply the name for it using the "RepositoryName" parameter.
The "name" property of the repository resource is defined by the "RepositoryName" parameter. String interpolation is also supported.
The schema URI defines the schema for the payload part of the manifest. Parameters can only be referenced from within the payload.
In most cases, simple text input is not enough. This is where value providers can help.
Here's an example of how a value provider can be used to validate that the user input is a valid AAD email enabled security group:
parameters:
- id: RequiredReviewers
display: Required reviewers email
valueProvider: local://aad/parameters/email?type=group&mailenabled=true&security=true
type: validator
Here's an example of how a value provider can be used to help user select one of available Service Endpoints for ESRP signing:
parameters:
- id: EsrpEndpointId
display: Esrp Service Endpoint
placeHolder: Select the endpoint to use for signing
valueProvider: local://vsts/parameters/serviceendpoints?type=PRSS
As type was not specified, it will default to dropdown.
All value providers support the "validator" type, but the same is not true for other types. You can find all available value providers with documentation and samples in the Reference section.
Files placed in the "artifacts" folder can be referenced from namespace manifest. This is useful when a resource requires a lot of complex configuration that should not be surfaced directly in yml.
Here's an example of an artifact reference to an Azure DevOps build definition json:
namespace: pipelines
schema: local://vsts/namespaces/pipelines/v1
parameters:
- id: QueueId
display: Agent Queue
valueProvider: local://vsts/parameters/agentqueues
- id: RepositoryName
display: Repository Name
- id: RepositoryId
display: Repository Id
artifacts:
- id: BuildDefinitionJson
path: BuildDefinition.json
encoding: base64
payload:
build:
- id: buildDefinition
stage: Incubation
jsonBase64: '{BuildDefinitionJson}'
jsonModel:
queueId: '{QueueId}'
repositoryName: '{RepositoryName}'
repositoryId: '{RepositoryId}'
As you can see from above, the buildDefinition resource declaration contains the "jsonBase64" field which expects a base64 encoded templatized json string. It also contains the jsonModel which will be used to generate the final json. Both base64 decoding and json template expansion are responsibility of the vendorized namespace provider.
In this case, the "BuildDefinitionJson" artifact is configured to be base64 encoded. This is useful because the artifact is treated by the template engine the same way that regular parameters are. The file is loaded, contents encoded, and the resulting base64 string stored in the "BuildDefinitionJson" artifact. This artifact can be referenced the same way one would reference a regular parameter, and the value will be expanded in place in yaml. It is therefore important to encode the contents to avoid breaking yml syntax.
If you look closely at the build definition declaration example from above, you can probably notice a problem. The namespace manifest expects the user to pass in repository name and repository id. This is problematic for several reasons:
Luckily, Coral supports declaring dependencies between any two resources in a single template. Cross namespace dependencies are also supported. In fact, inter-resource dependencies are one of the most important facets of Coral and is what drives the entire resource orchestrator. A dependency can be declared using something called a dynamic variable.
A dynamic variable is similar to a parameter, but instead of referencing a user input value, it is referencing a property of a resource in the same template. The referenceable properties are defined by the model of the referenced resource.
Every resource in a namespace has a corresponding configuration which is determined by a portion of a namespace manifest, parameters, attributes and dynamic variables. This configuration needs to be available at the moment the resource is being created. Once created, we will learn additional information about the new resource. For example, before creating a git repository in Azure DevOps, we need to supply its name, but only after it is created will we learn its Azure DevOps id.
The resource model is an object that contains the entire resource configuration, and additionally some information that is unique to this instance of a resource. These properties are often required when creating dependent resources.
Here's the same example from above, but with above described issues resolved using dynamic variables:
namespace: pipelines
schema: local://vsts/namespaces/pipelines/v1
parameters:
- id: QueueId
display: Agent Queue
valueProvider: local://vsts/parameters/agentqueues
artifacts:
- id: BuildDefinitionJson
path: BuildDefinition.json
encoding: base64
payload:
build:
- id: buildDefinition
stage: Incubation
jsonBase64: '{BuildDefinitionJson}'
jsonModel:
queueId: '{QueueId}'
repositoryName: ''
repositoryId: ''
A dynamic variable consists of 3 parts separated with a dot:
The syntax for dynamic variable references is similar to parameters and artifacts. The only difference is that instead of ‘{}', we must enclose the reference in ‘'. It is important to note for all parameters, artifacts and dynamic variables, that ‘' are required to avoid breaking yml syntax. Since yml is an extension of json, {} is reserved for declaring objects.
When using dynamic variables, one must be careful not to create circular dependencies. If this does happen, Coral will detect it and will invalidate the template and report the issue. These dependencies should also be considered when tagging resources with stages. When the resource dependency graph is collapsed into a stage graph, there shouldn't be any circular dependencies between stages. If there are, Coral will again invalidate the template and report the issue.