Installing Invictus Framework
- Prerequisites
- Download
- Deploy
To access the resources stored on Azure Storage and Azure Container Registry you have to request an SAS-token and Azure Container Registry password from coditproducts@codit.eu.
We use Multiple Revision mode in our Container App deployments, which means that older revisions could clutter the Container App Environment. We provide a clean-up script that should be run after logging in on the correct subscription, but can be ran in Azure DevOps Pipelines as well.
Include VNET support Shared
Invictus includes functionality which allows all its resources to run within an Azure Virtual Network (VNET).
Required deployment
-
An Azure Virtual Network
- Including two subnets, one each for:
- Private Endpoints
- Container App Environment
- The subnets must have the following services enabled
Microsoft.AzureCosmosDBMicrosoft.EventHubMicrosoft.KeyVaultMicrosoft.ServiceBusMicrosoft.Storage
- The Container App subnet must also have the delegation
Microsoft.App/environments
- Including two subnets, one each for:
-
Private DNS Zones (Bicep template)
privatelink.azurecr.ioprivatelink.blob.core.windows.netprivatelink.file.core.windows.netprivatelink.mongo.cosmos.azure.comprivatelink.queue.core.windows.netprivatelink.servicebus.windows.netprivatelink.table.core.windows.netprivatelink.table.cosmos.azure.comprivatelink.vaultcore.azure.netprivatelink.{regionName}.azurecontainerapps.io
-
To be able to deploy the app code from an Azure DevOps pipeline you will need a self hosted agent running on the same VNET with the following software installed:
- PowerShell
- Azure PowerShell
- Bicep CLI
Required role assignment
If the Invictus resources and the VNET are on different resource groups, then the Invictus resource group will need to be assigned the role of Network Contributor onto the VNET resource group.
Migrating older pipelines to v2.4+
Migrate to Framework v2.4+
Build pipeline
Nothing changes for the build pipeline.
The difference lies in the artifacts that the build produces, everything needed for the release is now included in the build (scripts, resources, etc..), which greatly simplifies the release pipeline.
Release pipeline
The task group is now replaced by a single Azure PowerShell task included in the build artifacts. Please refer to the Framework release pipeline installation step for more information.
The following task group parameters should be used as the PowerShell's arguments:
- ArtifactsPath:
-ArtifactsPath - ResourcePrefix:
-ResourcePrefix - AzureResourceGroup:
-ResourceGroupName - Location:
-ResourceGroupLocation
The AdditionalTemplateParameters can simply be copied and added to the Script Arguments.
If you are using the Azure PowerShell task to retrieve the access policies from key vault, then this task should also be removed from the release pipeline as it is now also included in the deployment script.
You can copy the -keyvaultName argument to the new PowerShell arguments.
Save installation script to your repository Shared
The Invictus-GetSources.ps1 script will pull the latest Invictus resources needed to deploy the Framework.
Add variables to variable group Shared
Secrets are required for authentication. These should be provided to you by Codit Software. Create a variable group for them:
- {prefix}.Invictus.Installation
Invictus.Installation.StorageAccount.Name:invictusreleasesInvictus.Installation.StorageAccount.Dashboard.SasToken: value provided by Codit Software (if you're also deploying the Dashboard)Invictus.Installation.StorageAccount.Framework.SasToken: value provided by Codit SoftwareInfra.Environment.ACRUsername: value provided by Codit SoftwareInfra.Environment.ACRPassword: value provided by Codit Software
YAML Pipeline
Next step is to add YAML pipelines to build the Invictus for Azure Framework. Change the following example file according to your needs, for example change the trigger path:
paths:
include:
- /src/customer.azure.invictus
Full YAML build pipeline example
pr: none
trigger:
branches:
include:
- main
- feature/*
paths:
include:
- /src/customer.azure.invictus
parameters:
- name: Version
displayName: Invictus Version
type: string
default: '*'
- name: useBeta
displayName: Use Beta
type: string
default: $False
pool:
vmImage: 'windows-latest'
stages:
- stage: Package
displayName: Package
dependsOn: []
variables:
- group: prefix.invictus.installation
jobs:
- job: publish
displayName: Build and Publish Framework
steps:
- checkout: self
clean: true
persistCredentials: true
- task: PowerShell@2
displayName: 'Pull Invictus sources'
inputs:
targetType: filePath
filePath: './scripts/Invictus-GetSources.ps1'
arguments: >
-StorageAccountName '$(Invictus.Installation.StorageAccount.Name)'
-StorageSasToken '$(Invictus.Installation.StorageAccount.Framework.SasToken)'
-StorageContainerName 'framework'
-SaveLocation '$(Build.ArtifactStagingDirectory)'
-UseBeta ${{ parameters.useBeta }}
-Version ${{ parameters.version }}
- task: PublishPipelineArtifact@1
inputs:
TargetPath: $(Build.ArtifactStagingDirectory)
ArtifactName: framework
publishLocation: 'pipeline'
Create variable group Shared
Create a variable group (recommended: {prefix}.Invictus.{env}) for each the environments. The deployment uses this variable group and edits/adds variables based on the Bicep deployment output.
Make sure the Project Collection Build Service has Administrator access to these variable groups (Pipelines > Library > Security)
Use Deploy.ps1 script for deployment
The Deploy.ps1 PowerShell script is available in the downloaded Invictus sources and is the central point of contact for deploying Invictus products.
Mandatory Parameters
| Argument name | Description |
|---|---|
arcPath | The Azure Container App registry base path to form the source image location of the container images. |
arcUsername | The username credential to authenticate the Docker CLI. |
arcPassword | The password credential to authenticate into the Docker CLI. |
resourcePrefix | An abbreviation to include in all the Azure resource names that Invictus deploys, often an environment name. |
resourceGroupName | The name of the Azure resource group where the main Invictus components deploys to. |
variableGroupName | DevOps variable group to write the Bicep outputs to (i.e. Invictus_CosmosDb_DbName) |
useBeta | Indicates the environment of the Azure Container App registry where the deployment gets its container images. |
Optional Parameters
| Argument name | Default value | Description |
|---|---|---|
artifactsPath | $PSScriptRoot | Path on the Azure DevOps agent that stores the downloaded Invictus artifacts (publish and download build artifacts) |
resourceGroupLocation | 'West Europe' | In case no resource group is available with the name resourceGroupName, the deployment uses this location to create such resource group. |
additionalTemplateParameters | [] | Custom named parameters for the Bicep template you wish to override. More on this below. |
version | latest | Version of the published Invictus artifacts that the deployment should download and deploy on the client environment. |
Full YAML task example
- task: AzureCLI@2
displayName: 'Azure CLI'
env:
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
inputs:
azureSubscription: '[YOUR_SERVICE_CONNECTION]'
scriptType: 'pscore'
scriptLocation: 'inlineScript'
inlineScript: |
# Determine where the the provided Invictus 'Deploy.ps1' script is located
$artifactsPath = ${{ variables['Pipeline.Workspace'] }} + '/_build/framework'
$scriptPath = $artifactsPath + '/Deploy.ps1'
& $scriptPath `
-artifactsPath $artifactsPath `
-version ${{parameters.Version}} `
-useBeta false `
-acrPath "invictusreleases.azurecr.io" `
-acrUsername 'admin' `
-acrPassword '<password>' `
-resourcePrefix 'dev' `
-resourceGroupName 'my-client-dev-rg' `
-variableGroupName 'My.Client.Dev' `
-identityProviderApplicationId '<app-id>' `
-identityProviderClientSecret '<secret>' `
Full YAML release pipeline example
pr: none
trigger: none
resources:
pipelines:
# Name of the pipeline resource inside this workflow. Used to reference the pipeline resources later on (e.g. download artifacts).
- pipeline: _build
# Name of the pipeline in Azure Pipelines
source: 'customer.azure.invictus.framework.build'
trigger: true
parameters:
- name: "Version"
type: string
default: "latest"
- name: "UseBeta"
type: string
default: "$false"
pool:
vmImage: 'ubuntu-latest'
stages:
- stage: deploy_dev
displayName: 'Deploy to Development'
variables:
- group: infra.dev
- group: prefix.invictus.dev
- group: prefix.invictus.installation
jobs:
- deployment: deploy_development
displayName: 'Deploy to Development'
environment: Development
strategy:
runOnce:
deploy:
steps:
- download: '_build'
displayName: Download Artifact
- task: AzureCLI@2
env:
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
inputs:
azureSubscription: 'NameOfYourServiceConnection'
scriptType: 'pscore'
scriptLocation: 'scriptPath'
ScriptPath: '$(Pipeline.Workspace)/_build/framework/Deploy.ps1'
ScriptArguments: '-version ${{parameters.Version}} -location "West Europe" -useBeta ${{parameters.UseBeta}} -acrPath "invictusreleases.azurecr.io" -acrUsername $(Infra.Environment.ACRUsername) -acrPassword $(Infra.Environment.ACRPassword) -resourcePrefix $(Infra.Environment.ResourcePrefix) -artifactsPath $(Pipeline.Workspace)/_build/framework -resourceGroupName $(Infra.Environment.ResourceGroup) -variableGroupName invictus.$(Infra.Environment.ShortName) -devOpsObjectId "$(Infra.DevOps.Object.Id)" -identityProviderApplicationId "$(Infra.AzAD.Client.IdentityProviderApplicationId)" -identityProviderClientSecret "$(Infra.AzAD.Client.IdentityProviderClientSecret)" -containerAppsEnvironmentLocation "$(Infra.Environment.ContainerAppsEnvironmentLocation)"'
- stage: deploy_prd
displayName: 'Deploy to Production'
dependsOn: deploy_acc
variables:
- group: infra.prd
- group: prefix.invictus.prd
- group: prefix.invictus.installation
jobs:
- deployment: deploy_prd
displayName: 'Deploy to Production'
environment: Production
strategy:
runOnce:
deploy:
steps:
- download: '_build'
displayName: Download Artifact
- task: AzureCLI@2
env:
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
inputs:
azureSubscription: 'NameOfYourServiceConnection'
scriptType: 'pscore'
scriptLocation: 'scriptPath'
ScriptPath: '$(Pipeline.Workspace)/_build/framework/Deploy.ps1'
ScriptArguments: '-version ${{parameters.Version}} -location "West Europe" -useBeta ${{parameters.UseBeta}} -acrPath "invictusreleases.azurecr.io" -acrUsername $(Infra.Environment.ACRUsername) -acrPassword $(Infra.Environment.ACRPassword) -resourcePrefix $(Infra.Environment.ResourcePrefix) -artifactsPath $(Pipeline.Workspace)/_build/framework -resourceGroupName $(Infra.Environment.ResourceGroup) -variableGroupName invictus.$(Infra.Environment.ShortName) -devOpsObjectId "$(Infra.DevOps.Object.Id)" -identityProviderApplicationId "$(Infra.AzAD.Client.IdentityProviderApplicationId)" -identityProviderClientSecret "$(Infra.AzAD.Client.IdentityProviderClientSecret)" -containerAppsEnvironmentLocation "$(Infra.Environment.ContainerAppsEnvironmentLocation)"'
Bicep Template Parameters
| Name | Description | Tags |
|---|---|---|
acaIdentityNamedefault: invictus-${resourcePrefix}-aca-identity | The name of the user-assigned identity that pulls the container images from the Azure Container Registry. | container-apps |
aiServicesSubnets | A list of subnet names to form the network rules for the Azure AI Foundry resource, useful for VNET deployments. | networkingvnet |
allowStorageAccountSharedKeyAccessdefault: null | Indicates whether the shared Azure Storage Account allows authentication via a shared key access. | storagesecurity |
appInsightsNamedefault: invictus-${resourcePrefix}-appins | The name of the Azure Application Insights resource that tracks the general telemetry of the Framework components. | monitoring |
appInsightsSamplingPercentagedefault: 1 | The sampling percentage for the Azure Application Insights that tracks the general telemetry of the Framework components. | monitoring |
approvedMessageSizeInBytesdefault: 200000 | The maximum byte threshold where the PubSub component applies the claim-check functionality. | comp:pubsubmessaging |
autoResubmitDeferredMessagesdefault: false | Indicates whether the PubSub component should automatically resubmit/recover an Azure Service Bus message older than the deferral time limit. | comp:pubsubmessaging |
blobContainerPrefixdefault: invictus | An custom abbreviation to include in the claim-check Azure Blob Storage container name, used by the PubSub component. | storage |
caeVnetInfraRgNamedefault: invictus-${resourcePrefix}-cae-infra | The name of the Azure Container Apps infrastructure resource group (when VNET is enabled). | container-appsnetworkingvnet |
containerAppEnvironmentSubnets | A list of subnet names to form the network rules of all the Azure Container App resources, useful for VNET deployments. | networkingvnetcontainer-apps |
containerAppsEnvironmentLocationdefault: resourceGroup().location | The Azure location for the Azure Container Apps and their environment. | container-apps |
containerAppsEnvironmentNamedefault: invictus-${resourcePrefix}-cae | The name of the Azure Container App environment. | container-apps |
containerRegistryName | The name of the Azure Container Apps registry that hosts the Framework components' container images. | container-apps |
containerRegistryUrldefault: ${resourcePrefix}.acr.azurecr.io | The server URL of the Azure Container Apps registry that hosts the Framework components' container images. | container-apps |
customApplicationIdsdefault: [] | A list of additional IDs referring to custom Microsoft Entra ID applications that should also be able to access the Azure Container Apps hosting the Framework components. | security |
customTagsdefault: {} | A set of Azure resource tags to apply to all to the deployed Invictus resources. | governance |
deferralMessageThresholdInMinutesdefault: 30 | The PubSub component will try to recover Azure Service Bus messages older than this time limit that were stuck in deferral. | comp:pubsubmessaging |
delegatedContainerAppEnvironmentSubnetName | The name of the subnet to form the network rules of the Azure Container App environment, useful for VNET deployments. | networkingvnetcontainer-apps |
devOpsObjectIddefault: deployer().objectId | The object ID associated with the service principal of the enterprise application that the Azure DevOps service connection is created for. | security |
disableStorageAccountPublicNetworkAccessdefault: false | Indicates whether the shared Azure Storage Account should disable public network access. If | storagenetworkingsecurityvnet |
dnsZoneResourceGroupNamedefault: resourceGroup().name | The name of the Azure resource group where the private DNS zone deploys to. | networkingvnet |
dnsZoneSubscriptionIddefault: subscription().subscriptionId | The Azure subscription ID to control the private DNS zone throughout, useful for VNET deployments. | networkingvnet |
enableVnetSupportdefault: false | Feature flag to control whether the Framework deploys within a VNET. | networkingvnet |
exceptionHandlerFunctionNamedefault: inv-${resourcePrefix}-exceptionhandler | The name of the Azure Container App deployed for the Exception Handler component. | comp:exception-handlercontainer-apps |
exceptionHandlerScaling | The Azure Container App scaling options of the Exception Handler component. | comp:exception-handlerscalingcontainer-apps |
identityProviderApplicationId | The application ID of the Microsoft Entra ID app registration that facilitates managed identity authentication for the Azure Container Apps, hosting the Framework components. | security |
identityProviderClientSecret | The client secret of the Microsoft Entra ID app registration that facilitates managed identity authentication for the Azure Container Apps, hosting the Framework components. | security |
invictusExceptionHandlerFunctionLocalContainerImage | The URL that navigates to the Azure Container App image of the Exception Handler component. | comp:exception-handlercontainer-apps |
invictusPubSubV2FunctionLocalContainerImage | The URL that navigates to the Azure Container App image of the PubSub component. | comp:pubsubcontainer-apps |
invictusRegexTranslatorFunctionLocalContainerImage | The URL that navigates to the Azure Container App image of the Regex Translator component. | comp:regex-translatorcontainer-apps |
invictusSequenceControllerFunctionLocalContainerImage | The URL that navigates to the Azure Container App image of the Sequence Controller component. | comp:sequence-controllercontainer-apps |
invictusTimeSequencerFunctionLocalContainerImage | The URL that navigates to the Azure Container App image of the Time Sequencer component. | comp:time-sequencercontainer-apps |
invictusTranscoV2FunctionLocalContainerImage | The URL that navigates to the Azure Container App image of the Transco component. | comp:transcocontainer-apps |
invictusUserManagedIdentityNamedefault: invictus-user-managed-identity | The name of the Azure user managed identity that has access to all the deployed Azure Container App components. | security |
invictusXmlJsonConverterFunctionLocalContainerImage | The URL that navigates to the Azure Container App image of the XML-JSON Converter component. | comp:xml-json-convertercontainer-apps |
invictusXsdValidatorFunctionLocalContainerImage | The URL that navigates to the Azure Container App image of the XSD Validator component. | comp:xsd-validatorcontainer-apps |
keyVaultEnablePurgeProtectiondefault: false | Indicates whether the shared Azure Key Vault should be protected against purging. | security |
keyVaultNamedefault: invictus-${resourcePrefix}-vlt | The name of the shared Azure Key Vault, used by all Framework components. | security |
keyVaultSubnets | A list of subnet names to form the Azure Key Vault resource, useful for VNET deployments. | networkingvnet |
locationdefault: resourceGroup().location | The main Azure location where Invictus deploys its resources, some advanced resources can be configured with their own location. | governance |
LogAnalyticsWorkspaceAppInsightsNamedefault: invictus-${resourcePrefix}-loganalytics-appinsights | The name of the Azure Log Analytics workspace that collects all Azure Application Insights resources deployed. | monitoring |
messageStatusCacheDeleteAfterDaysdefault: 30 | The time period (in days) after which the storage policy deletes the message status Azure Storage Account table. | storage |
pubSubSubscriptionLockTimeoutInMinutesdefault: 1 | The amount of time in minutes the PubSub component locks an Azure Service Bus message received on a topic subscription. | comp:pubsubmessaging |
pubsubV2FunctionNamedefault: inv-${resourcePrefix}-pubsub-v2 | The name of the Azure Container App deployed for the PubSub component. | comp:pubsubcontainer-apps |
pubSubV2Scaling | The Azure Container App scaling options of the PubSub component. | comp:pubsubscalingcontainer-apps |
pubSubV2TopicNamedefault: pubsubv2router | The name of the Azure Service Bus topic, used by the PubSub component to send/receive messages from. | comp:pubsubmessaging |
regexTranslatorFunctionNamedefault: inv-${resourcePrefix}-regextranslator | The name of the Azure Container App deployed for the Regex Translator component. | comp:regex-translatorcontainer-apps |
regexTranslatorScaling | The Azure Container App scaling options of the Regex Translator component. | comp:regex-translatorscalingcontainer-apps |
resourcePrefixrequired | An abbreviation to include in all the Azure resource names that Invictus deploys, often an environment name. | governance |
sequenceControllerFunctionNamedefault: inv-${resourcePrefix}-seqcontroller | The name of the Azure Container App deployed for the Sequence Controller component. | comp:sequence-controllercontainer-apps |
sequenceControllerScaling | The Azure Container App scaling options of the Sequence Controller component. | comp:sequence-controllerscalingcontainer-apps |
serviceBusMessageTimeToLiveMinutesdefault: 43200 | The time limit of the send Azure Service Bus messages by the PubSub component, see Microsoft's messages expiration for more details. | comp:pubsubmessaging |
serviceBusNamespaceNamedefault: invictus-${resourcePrefix}-sbs | The name of the Azure Service Bus namespace resource where the PubSub component controls its messages. | comp:pubsubmessaging |
serviceBusSkuNamedefault: enableVnetSupport ? Premium : Standard | The pricing tier of the Azure Service Bus, used by the PubSub component. | comp:pubsubmessaging |
serviceBusSubnets | A list of subnet names to form the Azure Service Bus namespace resource, useful for VNET deployments. | networkingvnet |
storageAccountMinimumTLSVersiondefault: TLS1_2 | The minimum allowed TLS version of the shared Azure Storage Account, used by all Framework components. | storagesecurity |
storageAccountNamedefault: invictus${resourcePrefix}store | The name of the shared Azure Storage Account, used by all Framework components. | comp:pubsubcomp:transcocomp:regex-translatorcomp:xsd-validatorcomp:xml-json-convertercomp:time-sequencercomp:sequence-controllerstorage |
storageAccountSubnets | A list of subnet names to form the Azure Storage Account resource, useful for VNET deployments. | networkingvnetstorage |
storageAccountTypedefault: Standard_LRS | The pricing tier of the shared Azure Storage Account, used by all Framework components. | storage |
timesequencerFunctionNamedefault: inv-${resourcePrefix}-timesequencer | The name of the Azure Container App deployed for the Time Sequencer component. | comp:time-sequencercontainer-apps |
timeSequencerScaling | The Azure Container App scaling options of the Time Sequencer component. | comp:time-sequencerscalingcontainer-apps |
transcoV2FunctionNamedefault: inv-${resourcePrefix}-transco-v2 | The name of the Azure Container App deployed for the Transco component. | comp:transcocontainer-apps |
transcoV2Scaling | The Azure Container App scaling options of the Transco component. | comp:transcoscalingcontainer-apps |
useAIExceptionHandlerInterpreterdefault: false | Feature flag to control whether the Framework deploys with Azure AI Foundry services, useful for the Exception Handler component. | comp:exception-handler |
useResourceLocksdefault: false | Feature flag to control whether the deployed Azure resources have resource locks. | governance |
virtualNetworkResourceGroupNamedefault: resourceGroup().name | The name of the Azure resource group where the VNET network rules deploys to. | networkingvnet |
vnetName | The name of the Azure Virtual Network (VNET) resource that forms the base for all network-related rules and subnets throughout. | networkingvnet |
xmlJsonConverterFunctionNamedefault: inv-${resourcePrefix}-xmljsonconverter | The name of the Azure Container App deployed for the XML-JSON Converter component. | comp:xml-json-convertercontainer-apps |
xmlJsonConverterScaling | The Azure Container App scaling options of the XML-JSON Converter component. | comp:xml-json-converterscalingcontainer-apps |
xsdValidatorFunctionNamedefault: inv-${resourcePrefix}-xsdvalidator | The name of the Azure Container App deployed for the XML-JSON Converter component. | comp:xsd-validatorcontainer-apps |
xsdValidatorScaling | The Azure Container App scaling options of the XSD Validator component. | comp:xsd-validatorscalingcontainer-apps |