Azure Synapse Deployment - Package Based Approach

Objective

We have previously specified how Azure Synapse Artifacts deployment can be achieved using FlexDeploy in this article. In the current article we are going to elaborate more on how to implement package-based deployment for the same.

Design

There are two approaches we follow here:

  • Approach A:

Configuring a Generic Package based project, create and deploy the ARM templates being generated based on those specific resources.

  • Approach B:

First Phase - Configuring a Generic Package based project, create the ARM template based on the specific resources and store it in a repository. This repository may contain all the ARM templates corresponding to different packages. Will showcase it later in this tutorial.

Second Phase - Configuring another package-based project that will fetching the ARM template from the repository and initiate the Synapse Release pipeline.

The benefit of the second approach is there would be more control over the ARM template which can be edited as needed by adding a new parameter or variables or something else.

Flow (Approach A)

Workflow configuration

Build Workflow:

 

image-20240329-072533.png

<?xml version="1.0" encoding="Unicode"?>
<ns0:WorkFlow xmlns:ns1="http://flexagon.com/flexdeploy/workflow/common" xmlns:ns0="http://flexagon.com/flexdeploy/workflow">
<ns1:Name>CreateARMTemplate-Inc</ns1:Name>
<ns1:Description></ns1:Description>
<ns0:Variables/>
<ns0:Steps>
<ns0:Step>
<ns1:Name>publishArtifacts</ns1:Name>
<ns1:StepId>1</ns1:StepId>
<ns0:InvokePlugin>
<ns0:PluginName>FlexagonAzurePlugin</ns0:PluginName>
<ns0:PluginOperation>publishArtifacts</ns0:PluginOperation>
<ns0:EndpointInstanceOverrideExpression>false</ns0:EndpointInstanceOverrideExpression>
<ns0:InvokePluginTypeVersion>v2</ns0:InvokePluginTypeVersion>
<ns0:consumesArtifacts>false</ns0:consumesArtifacts>
<ns0:producesArtifacts>false</ns0:producesArtifacts>
<ns0:EndpointSelection>
<ns0:EndpointSelectionChoice>All</ns0:EndpointSelectionChoice>
</ns0:EndpointSelection>
<ns0:EndpointExecutionChoice>Any</ns0:EndpointExecutionChoice>
<ns0:PluginInputs>
<ns0:PluginInput>
<ns0:Name>FDAZ_DEVOPS_INP_FEED</ns0:Name>
<ns0:ValueType>Expression</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
<ns0:Value>
<ns0:Expression>FEED_NAME</ns0:Expression>
</ns0:Value>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDAZ_DEVOPS_INP_PACKAGE_NAME</ns0:Name>
<ns0:ValueType>Expression</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
<ns0:Value>
<ns0:Expression>FD_PACKAGE_NAME + &quot;-&quot; + ARTIFACTS_PACKAGE_NAME</ns0:Expression>
</ns0:Value>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDAZ_DEVOPS_INP_PACKAGE_VERSION</ns0:Name>
<ns0:ValueType>Expression</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
<ns0:Value>
<ns0:Expression>PACKAGE_VERSION</ns0:Expression>
</ns0:Value>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDAZ_DEVOPS_INP_PACKAGE_DESCRIPTION</ns0:Name>
<ns0:ValueType>Text</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDAZ_DEVOPS_INP_PROJECT_NAME</ns0:Name>
<ns0:ValueType>Expression</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
<ns0:Value>
<ns0:Expression>PROJECT_NAME</ns0:Expression>
</ns0:Value>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDAZ_DEVOPS_INP_PACKAGE_PATH</ns0:Name>
<ns0:ValueType>Expression</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
<ns0:Value>
<ns0:Expression>FD_TEMP_DIR</ns0:Expression>
</ns0:Value>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDAZ_DEVOPS_INP_ADDITIONAL_PARAMS</ns0:Name>
<ns0:ValueType>Text</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
</ns0:PluginInput>
</ns0:PluginInputs>
<ns0:UserInputs/>
<ns0:PluginOutputs>
<ns0:OutputValue>
<ns0:NameInCallee>FDAZ_DEVOPS_OUT_ERR</ns0:NameInCallee>
</ns0:OutputValue>
<ns0:OutputValue>
<ns0:NameInCallee>FDAZ_DEVOPS_OUT_RESP</ns0:NameInCallee>
</ns0:OutputValue>
</ns0:PluginOutputs>
<ns0:UserOutputs/>
</ns0:InvokePlugin>
</ns0:Step>
<ns0:Step>
<ns1:Name>buildPipeline</ns1:Name>
<ns1:StepId>2</ns1:StepId>
<ns0:InvokePlugin>
<ns0:PluginName>FlexagonAzurePlugin</ns0:PluginName>
<ns0:PluginOperation>buildPipeline</ns0:PluginOperation>
<ns0:EndpointInstanceOverrideExpression>false</ns0:EndpointInstanceOverrideExpression>
<ns0:InvokePluginTypeVersion>v2</ns0:InvokePluginTypeVersion>
<ns0:consumesArtifacts>false</ns0:consumesArtifacts>
<ns0:producesArtifacts>false</ns0:producesArtifacts>
<ns0:EndpointSelection>
<ns0:EndpointSelectionChoice>All</ns0:EndpointSelectionChoice>
</ns0:EndpointSelection>
<ns0:EndpointExecutionChoice>Any</ns0:EndpointExecutionChoice>
<ns0:PluginInputs>
<ns0:PluginInput>
<ns0:Name>FDAZ_DEVOPS_INP_BUILD_DEFINITION_ID</ns0:Name>
<ns0:ValueType>Text</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
<ns0:Text></ns0:Text>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDAZ_DEVOPS_INP_DEFINITION_NAME</ns0:Name>
<ns0:ValueType>Expression</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
<ns0:Value>
<ns0:Expression>BUILD_DEFINITION_NAME</ns0:Expression>
</ns0:Value>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDAZ_DEVOPS_INP_QUEUE_ID</ns0:Name>
<ns0:ValueType>Text</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDAZ_DEVOPS_INP_COMMIT_ID</ns0:Name>
<ns0:ValueType>Text</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDAZ_DEVOPS_INP_BRANCH_NAME</ns0:Name>
<ns0:ValueType>Text</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDAZ_DEVOPS_INP_PROJECT_NAME</ns0:Name>
<ns0:ValueType>Expression</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
<ns0:Value>
<ns0:Expression>PROJECT_NAME</ns0:Expression>
</ns0:Value>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDAZ_DEVOPS_INP_VARIABLES_LIST</ns0:Name>
<ns0:ValueType>Expression</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
<ns0:Value>
<ns0:Expression>VARIABLES_LIST + &quot;##artifactsPackageName:&quot; + FD_PACKAGE_NAME + &quot;-&quot; + ARTIFACTS_PACKAGE_NAME + &quot;##feedName:&quot; + PROJECT_NAME + &quot;/&quot; + FEED_NAME</ns0:Expression>
</ns0:Value>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDAZ_DEVOPS_INP_PACKAGE_NAME</ns0:Name>
<ns0:ValueType>Expression</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
<ns0:Value>
<ns0:Expression>FD_PACKAGE_NAME + &quot;-&quot; + PACKAGE_NAME</ns0:Expression>
</ns0:Value>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDAZ_DEVOPS_INP_ADDITIONAL_PARAMS</ns0:Name>
<ns0:ValueType>Text</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
</ns0:PluginInput>
</ns0:PluginInputs>
<ns0:UserInputs/>
<ns0:PluginOutputs>
<ns0:OutputValue>
<ns0:NameInCallee>FDAZ_DEVOPS_OUT_ERR</ns0:NameInCallee>
</ns0:OutputValue>
<ns0:OutputValue>
<ns0:NameInCallee>FDAZ_DEVOPS_OUT_RESP</ns0:NameInCallee>
</ns0:OutputValue>
<ns0:OutputValue>
<ns0:NameInCallee>FDAZ_DEVOPS_OUT_BUILD_PIPELINE_WEB_URL</ns0:NameInCallee>
</ns0:OutputValue>
</ns0:PluginOutputs>
<ns0:UserOutputs/>
</ns0:InvokePlugin>
</ns0:Step>
<ns0:Step>
<ns1:Name>downloadArtifacts</ns1:Name>
<ns1:StepId>3</ns1:StepId>
<ns0:InvokePlugin>
<ns0:PluginName>FlexagonAzurePlugin</ns0:PluginName>
<ns0:PluginOperation>downloadArtifacts</ns0:PluginOperation>
<ns0:EndpointInstanceOverrideExpression>false</ns0:EndpointInstanceOverrideExpression>
<ns0:InvokePluginTypeVersion>v2</ns0:InvokePluginTypeVersion>
<ns0:consumesArtifacts>false</ns0:consumesArtifacts>
<ns0:producesArtifacts>true</ns0:producesArtifacts>
<ns0:EndpointSelection>
<ns0:EndpointSelectionChoice>All</ns0:EndpointSelectionChoice>
</ns0:EndpointSelection>
<ns0:EndpointExecutionChoice>Any</ns0:EndpointExecutionChoice>
<ns0:PluginInputs>
<ns0:PluginInput>
<ns0:Name>FDAZ_DEVOPS_INP_FEED</ns0:Name>
<ns0:ValueType>Expression</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
<ns0:Value>
<ns0:Expression>FEED_NAME</ns0:Expression>
</ns0:Value>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDAZ_DEVOPS_INP_PACKAGE_NAME</ns0:Name>
<ns0:ValueType>Expression</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
<ns0:Value>
<ns0:Expression>FD_PACKAGE_NAME + &quot;-&quot; + PACKAGE_NAME</ns0:Expression>
</ns0:Value>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDAZ_DEVOPS_INP_PACKAGE_VERSION</ns0:Name>
<ns0:ValueType>Expression</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
<ns0:Value>
<ns0:Expression>PACKAGE_VERSION</ns0:Expression>
</ns0:Value>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDAZ_DEVOPS_INP_PROJECT_NAME</ns0:Name>
<ns0:ValueType>Expression</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
<ns0:Value>
<ns0:Expression>PROJECT_NAME</ns0:Expression>
</ns0:Value>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDAZ_DEVOPS_INP_PACKAGE_PATH</ns0:Name>
<ns0:ValueType>Text</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDAZ_DEVOPS_INP_ADDITIONAL_PARAMS</ns0:Name>
<ns0:ValueType>Text</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
</ns0:PluginInput>
</ns0:PluginInputs>
<ns0:UserInputs/>
<ns0:PluginOutputs>
<ns0:OutputValue>
<ns0:NameInCallee>FDAZ_DEVOPS_OUT_ERR</ns0:NameInCallee>
</ns0:OutputValue>
<ns0:OutputValue>
<ns0:NameInCallee>FDAZ_DEVOPS_OUT_RESP</ns0:NameInCallee>
</ns0:OutputValue>
</ns0:PluginOutputs>
<ns0:UserOutputs/>
</ns0:InvokePlugin>
</ns0:Step>
</ns0:Steps>
</ns0:WorkFlow>

 

Deploy Workflow:

 

image-20240329-073217.png

<?xml version="1.0" encoding="Unicode"?>
<ns0:WorkFlow xmlns:ns1="http://flexagon.com/flexdeploy/workflow/common" xmlns:ns0="http://flexagon.com/flexdeploy/workflow">
<ns1:Name>DeploySynapseArtifacts-Inc</ns1:Name>
<ns1:Description></ns1:Description>
<ns0:Variables>
<ns0:Variable>
<ns1:Name>ENV_DETAILS</ns1:Name>
<ns1:Type>String</ns1:Type>
<ns0:returnAsOutput>true</ns0:returnAsOutput>
<ns1:isConstant>false</ns1:isConstant>
</ns0:Variable>
<ns0:Variable>
<ns1:Name>RELEASE_ID</ns1:Name>
<ns1:Type>String</ns1:Type>
<ns0:returnAsOutput>true</ns0:returnAsOutput>
<ns1:isConstant>false</ns1:isConstant>
</ns0:Variable>
<ns0:Variable>
<ns1:Name>ENVIRONMENT_ID</ns1:Name>
<ns1:Type>String</ns1:Type>
<ns0:returnAsOutput>true</ns0:returnAsOutput>
<ns1:isConstant>false</ns1:isConstant>
</ns0:Variable>
<ns0:Variable>
<ns1:Name>RELEASE_URL</ns1:Name>
<ns1:Type>String</ns1:Type>
<ns0:returnAsOutput>true</ns0:returnAsOutput>
<ns1:isConstant>false</ns1:isConstant>
</ns0:Variable>
</ns0:Variables>
<ns0:Steps>
<ns0:Step>
<ns1:Name>createRelease</ns1:Name>
<ns1:StepId>1</ns1:StepId>
<ns0:InvokePlugin>
<ns0:PluginName>FlexagonAzurePlugin</ns0:PluginName>
<ns0:PluginOperation>createRelease</ns0:PluginOperation>
<ns0:EndpointInstanceOverrideExpression>false</ns0:EndpointInstanceOverrideExpression>
<ns0:InvokePluginTypeVersion>v2</ns0:InvokePluginTypeVersion>
<ns0:consumesArtifacts>false</ns0:consumesArtifacts>
<ns0:producesArtifacts>false</ns0:producesArtifacts>
<ns0:EndpointSelection>
<ns0:EndpointSelectionChoice>All</ns0:EndpointSelectionChoice>
</ns0:EndpointSelection>
<ns0:EndpointExecutionChoice>Any</ns0:EndpointExecutionChoice>
<ns0:PluginInputs>
<ns0:PluginInput>
<ns0:Name>FDAZ_DEVOPS_INP_RELEASE_DEFINITION_ID</ns0:Name>
<ns0:ValueType>Expression</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
<ns0:Value>
<ns0:Expression>RELEASE_DEFINITION_ID</ns0:Expression>
</ns0:Value>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDAZ_DEVOPS_INP_ARTIFACTS_PAYLOAD</ns0:Name>
<ns0:ValueType>Text</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
<ns0:Text></ns0:Text>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDAZ_DEVOPS_INP_PROJECT_NAME</ns0:Name>
<ns0:ValueType>Expression</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
<ns0:Value>
<ns0:Expression>PROJECT_NAME</ns0:Expression>
</ns0:Value>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDAZ_DEVOPS_INP_VARIABLES_LIST</ns0:Name>
<ns0:ValueType>Expression</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
<ns0:Value>
<ns0:Expression>&quot;feedName:&quot; + PROJECT_NAME + &quot;/&quot; + FEED_NAME + &quot;##packageName:&quot; + PACKAGE_NAME + &quot;##packageVersion:&quot; + PACKAGE_VERSION</ns0:Expression>
</ns0:Value>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDAZ_DEVOPS_INP_PROPERTIES</ns0:Name>
<ns0:ValueType>Text</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDAZ_DEVOPS_INP_MANUAL_ENVIRONMENTS</ns0:Name>
<ns0:ValueType>Text</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDAZ_DEVOPS_INP_RELEASE_STATUS_CHECK</ns0:Name>
<ns0:ValueType>Text</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>Boolean</ns1:Type>
<ns0:Text>false</ns0:Text>
</ns0:PluginInput>
</ns0:PluginInputs>
<ns0:UserInputs/>
<ns0:PluginOutputs>
<ns0:OutputValue>
<ns0:NameInCallee>FDAZ_DEVOPS_OUT_RESP</ns0:NameInCallee>
</ns0:OutputValue>
<ns0:OutputValue>
<ns0:NameInCallee>FDAZ_DEVOPS_OUT_RELEASE_WEB_URL</ns0:NameInCallee>
</ns0:OutputValue>
<ns0:OutputValue>
<ns0:NameInCallee>FDAZ_DEVOPS_OUT_REL_ENV_STAGE_DETAILS</ns0:NameInCallee>
<ns0:NameInCaller>ENV_DETAILS</ns0:NameInCaller>
</ns0:OutputValue>
<ns0:OutputValue>
<ns0:NameInCallee>FDAZ_DEVOPS_OUT_RELEASE_ID</ns0:NameInCallee>
<ns0:NameInCaller>RELEASE_ID</ns0:NameInCaller>
</ns0:OutputValue>
</ns0:PluginOutputs>
<ns0:UserOutputs/>
</ns0:InvokePlugin>
</ns0:Step>
<ns0:Step>
<ns1:Name>Parse Environment specific Id</ns1:Name>
<ns1:StepId>2</ns1:StepId>
<ns0:InvokePlugin>
<ns0:PluginName>FlexagonXPathPlugin</ns0:PluginName>
<ns0:PluginOperation>parseJson</ns0:PluginOperation>
<ns0:EndpointInstanceOverrideExpression>false</ns0:EndpointInstanceOverrideExpression>
<ns0:InvokePluginTypeVersion>v2</ns0:InvokePluginTypeVersion>
<ns0:consumesArtifacts>false</ns0:consumesArtifacts>
<ns0:producesArtifacts>false</ns0:producesArtifacts>
<ns0:EndpointSelection>
<ns0:EndpointSelectionChoice>All</ns0:EndpointSelectionChoice>
</ns0:EndpointSelection>
<ns0:EndpointExecutionChoice>Any</ns0:EndpointExecutionChoice>
<ns0:PluginInputs>
<ns0:PluginInput>
<ns0:Name>FDP_SOURCE</ns0:Name>
<ns0:ValueType>Expression</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
<ns0:Value>
<ns0:Expression>ENV_DETAILS</ns0:Expression>
</ns0:Value>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDP_XPATH</ns0:Name>
<ns0:ValueType>Expression</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
<ns0:Value>
<ns0:Expression>'$..[?(@.name==\''+FD_ENVIRONMENT_NAME+'\')].id'</ns0:Expression>
</ns0:Value>
</ns0:PluginInput>
</ns0:PluginInputs>
<ns0:UserInputs/>
<ns0:PluginOutputs>
<ns0:OutputValue>
<ns0:NameInCallee>FDP_VALUE</ns0:NameInCallee>
<ns0:NameInCaller>ENVIRONMENT_ID</ns0:NameInCaller>
</ns0:OutputValue>
</ns0:PluginOutputs>
<ns0:UserOutputs/>
</ns0:InvokePlugin>
</ns0:Step>
<ns0:Step>
<ns1:Name>updateReleaseEnvStatus</ns1:Name>
<ns1:StepId>3</ns1:StepId>
<ns0:InvokePlugin>
<ns0:PluginName>FlexagonAzurePlugin</ns0:PluginName>
<ns0:PluginOperation>updateReleaseEnvStatus</ns0:PluginOperation>
<ns0:EndpointInstanceOverrideExpression>false</ns0:EndpointInstanceOverrideExpression>
<ns0:InvokePluginTypeVersion>v2</ns0:InvokePluginTypeVersion>
<ns0:consumesArtifacts>false</ns0:consumesArtifacts>
<ns0:producesArtifacts>false</ns0:producesArtifacts>
<ns0:EndpointSelection>
<ns0:EndpointSelectionChoice>All</ns0:EndpointSelectionChoice>
</ns0:EndpointSelection>
<ns0:EndpointExecutionChoice>Any</ns0:EndpointExecutionChoice>
<ns0:PluginInputs>
<ns0:PluginInput>
<ns0:Name>FDAZ_DEVOPS_INP_RELEASE_ID</ns0:Name>
<ns0:ValueType>Expression</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>Integer</ns1:Type>
<ns0:Value>
<ns0:Expression>RELEASE_ID</ns0:Expression>
</ns0:Value>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDAZ_DEVOPS_INP_RELEASE_ENVIRONMENT_ID</ns0:Name>
<ns0:ValueType>Expression</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>Integer</ns1:Type>
<ns0:Value>
<ns0:Expression>ENVIRONMENT_ID.substring(1,ENVIRONMENT_ID.length()-1)</ns0:Expression>
</ns0:Value>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDAZ_DEVOPS_INP_PROJECT_NAME</ns0:Name>
<ns0:ValueType>Expression</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
<ns0:Value>
<ns0:Expression>PROJECT_NAME</ns0:Expression>
</ns0:Value>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDAZ_DEVOPS_INP_RELEASE_ENVIRONMENT_STATUS</ns0:Name>
<ns0:ValueType>Text</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
<ns0:Text>InProgress</ns0:Text>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDAZ_DEVOPS_INP_VARIABLES_LIST</ns0:Name>
<ns0:ValueType>Expression</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
<ns0:Value>
<ns0:Expression>ENVIRONMENT_VARIABLES_LIST</ns0:Expression>
</ns0:Value>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDAZ_DEVOPS_INP_RELEASE_COMMENT</ns0:Name>
<ns0:ValueType>Text</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDAZ_DEVOPS_INP_SCHEDULED_DEPLOYMENT_TIME</ns0:Name>
<ns0:ValueType>Text</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDAZ_DEVOPS_INP_REL_ENV_STATUS_CHECK</ns0:Name>
<ns0:ValueType>Text</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>Boolean</ns1:Type>
<ns0:Text>true</ns0:Text>
</ns0:PluginInput>
</ns0:PluginInputs>
<ns0:UserInputs/>
<ns0:PluginOutputs>
<ns0:OutputValue>
<ns0:NameInCallee>FDAZ_DEVOPS_OUT_RESP</ns0:NameInCallee>
</ns0:OutputValue>
<ns0:OutputValue>
<ns0:NameInCallee>FDAZ_DEVOPS_OUT_REL_ENV_WEB_URL</ns0:NameInCallee>
<ns0:NameInCaller>RELEASE_URL</ns0:NameInCaller>
</ns0:OutputValue>
</ns0:PluginOutputs>
<ns0:UserOutputs/>
</ns0:InvokePlugin>
</ns0:Step>
</ns0:Steps>
</ns0:WorkFlow>

Project Configuration

Create a Project by choosing the Classification: Package-based and Project Types as Generic

Once it is created the Source Control needs to be configured, so that we can discover the files from the respective repository.

 

For example, this is how the repository looks like where we have all the artifacts uploaded from Synapse Dev Workspace.

Discover the files using File Catalog tab

Now we can create Package upon selecting specific files for which the ARM template should get generated and the specific resources would be deployed to the Target Synapse Workspace.

Say we have two pipelines in repository but want to deploy only one to the target workspace, in that case we can create a package and add the pipeline file in it.

 

Click on the Configuration tab, select General and update the Build and Deploy workflows along with respective Target groups.

Execution

Initiate Build on the selected Package “pipeline”.

Note: The ARM templates are published to Azure DevOps Feed as Artifacts with the package name as a keyword in it. Example: if the FD project name is SynapseOrchestration-Incremental and the package name is “pipeline” then the artifacts package name would be “pipeline-synapseorchestration-incremental-armtemplate“. Now Microsoft has certain restrictions on the naming of the Azure Artifacts, hence please follow the guide before you name the package that you create in FD or else adjust your workflow to be in compliance. https://learn.microsoft.com/en-us/azure/devops/organizations/settings/naming-restrictions?view=azure-devops

To verify, clicked on the Artifacts tab and verified the ARM template and it shows up with just one selected pipeline.

Now initiated the Deploy.

Flow (Approach B)

Workflow configuration for creating ARM template and upload to Repository

Build Workflow:

 

Note: For uploading the ARM template to repository, we have created another DevOps repository as az-synapse-arm and configured it in FlexDeploy-Integration with the code SYNAPSEARM.

If you have some other repository present in GITHUB or Azure DevOps anywhere and want to use that, then please create accordingly and use the correct Instance Code in the workflow pasted below.

 

<?xml version="1.0" encoding="Unicode"?>
<ns0:WorkFlow xmlns:ns1="http://flexagon.com/flexdeploy/workflow/common" xmlns:ns0="http://flexagon.com/flexdeploy/workflow">
<ns1:Name>ExportAndUploadtoGIT</ns1:Name>
<ns1:Description></ns1:Description>
<ns0:Steps>
<ns0:Step>
<ns1:Name>clone</ns1:Name>
<ns1:StepId>1</ns1:StepId>
<ns0:InvokePlugin>
<ns0:PluginName>FlexagonGITPlugin</ns0:PluginName>
<ns0:PluginOperation>clone</ns0:PluginOperation>
<ns0:EndpointInstanceOverrideExpression>false</ns0:EndpointInstanceOverrideExpression>
<ns0:InvokePluginTypeVersion>v2</ns0:InvokePluginTypeVersion>
<ns0:consumesArtifacts>false</ns0:consumesArtifacts>
<ns0:producesArtifacts>false</ns0:producesArtifacts>
<ns0:EndpointSelection>
<ns0:EndpointSelectionChoice>All</ns0:EndpointSelectionChoice>
</ns0:EndpointSelection>
<ns0:EndpointExecutionChoice>Any</ns0:EndpointExecutionChoice>
<ns0:PluginInputs>
<ns0:PluginInput>
<ns0:Name>FDGIT_INP_INSTANCE_CODE</ns0:Name>
<ns0:ValueType>Text</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
<ns0:Text>SYNAPSEARM</ns0:Text>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDGIT_INP_DEST_SUBFOLDER</ns0:Name>
<ns0:ValueType>Text</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
<ns0:Text>ARMTemplates</ns0:Text>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDGIT_INP_BRANCH</ns0:Name>
<ns0:ValueType>Text</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
<ns0:Text>flexdeploy</ns0:Text>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDGIT_INP_TREELESS_CLONE</ns0:Name>
<ns0:ValueType>Text</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>Boolean</ns1:Type>
<ns0:Text>false</ns0:Text>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDGIT_INP_DEPTH</ns0:Name>
<ns0:ValueType>Text</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>Integer</ns1:Type>
<ns0:Text></ns0:Text>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDGIT_INP_SPARSE_CHECKOUT_FOLDERS</ns0:Name>
<ns0:ValueType>Text</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
</ns0:PluginInput>
</ns0:PluginInputs>
<ns0:UserInputs/>
<ns0:PluginOutputs/>
<ns0:UserOutputs/>
</ns0:InvokePlugin>
</ns0:Step>
<ns0:Step>
<ns1:Name>InvokeWorkflow</ns1:Name>
<ns1:StepId>2</ns1:StepId>
<ns0:InvokeWorkflow>
<ns0:WorkflowName>CreateARMTemplate-Inc</ns0:WorkflowName>
<ns0:OverrideVersion>1.1</ns0:OverrideVersion>
<ns0:InputValues/>
<ns0:OutputValues/>
</ns0:InvokeWorkflow>
</ns0:Step>
<ns0:Step>
<ns1:Name>copy</ns1:Name>
<ns1:StepId>3</ns1:StepId>
<ns0:InvokePlugin>
<ns0:PluginName>FlexagonFilePlugin</ns0:PluginName>
<ns0:PluginOperation>copy</ns0:PluginOperation>
<ns0:EndpointInstanceOverrideExpression>false</ns0:EndpointInstanceOverrideExpression>
<ns0:InvokePluginTypeVersion>v2</ns0:InvokePluginTypeVersion>
<ns0:consumesArtifacts>false</ns0:consumesArtifacts>
<ns0:producesArtifacts>false</ns0:producesArtifacts>
<ns0:EndpointSelection>
<ns0:EndpointSelectionChoice>All</ns0:EndpointSelectionChoice>
</ns0:EndpointSelection>
<ns0:EndpointExecutionChoice>Any</ns0:EndpointExecutionChoice>
<ns0:PluginInputs>
<ns0:PluginInput>
<ns0:Name>FDFILE_INP_FILE_FILTER</ns0:Name>
<ns0:ValueType>Text</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
<ns0:Text>Template*.json</ns0:Text>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDFILE_INP_FILE_FILTER_EXCLUDED</ns0:Name>
<ns0:ValueType>Text</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDFILE_INP_SOURCE_PATH</ns0:Name>
<ns0:ValueType>Expression</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
<ns0:Value>
<ns0:Expression>FD_ARTIFACTS_DIR</ns0:Expression>
</ns0:Value>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDFILE_INP_TARGET_PATH</ns0:Name>
<ns0:ValueType>Expression</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
<ns0:Value>
<ns0:Expression>FD_TEMP_DIR+&quot;/ARMTemplates/&quot;+FD_PACKAGE_NAME</ns0:Expression>
</ns0:Value>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDFILE_INP_CLEAN_DIRECTORY</ns0:Name>
<ns0:ValueType>Text</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>Boolean</ns1:Type>
<ns0:Text>true</ns0:Text>
</ns0:PluginInput>
</ns0:PluginInputs>
<ns0:UserInputs/>
<ns0:PluginOutputs/>
<ns0:UserOutputs/>
</ns0:InvokePlugin>
</ns0:Step>
<ns0:Step>
<ns1:Name>add</ns1:Name>
<ns1:StepId>4</ns1:StepId>
<ns0:InvokePlugin>
<ns0:PluginName>FlexagonGITPlugin</ns0:PluginName>
<ns0:PluginOperation>add</ns0:PluginOperation>
<ns0:EndpointInstanceOverrideExpression>false</ns0:EndpointInstanceOverrideExpression>
<ns0:InvokePluginTypeVersion>v2</ns0:InvokePluginTypeVersion>
<ns0:consumesArtifacts>false</ns0:consumesArtifacts>
<ns0:producesArtifacts>false</ns0:producesArtifacts>
<ns0:EndpointSelection>
<ns0:EndpointSelectionChoice>All</ns0:EndpointSelectionChoice>
</ns0:EndpointSelection>
<ns0:EndpointExecutionChoice>Any</ns0:EndpointExecutionChoice>
<ns0:PluginInputs>
<ns0:PluginInput>
<ns0:Name>FDGIT_INP_INSTANCE_CODE</ns0:Name>
<ns0:ValueType>Text</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
<ns0:Text>SYNAPSEARM</ns0:Text>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDGIT_INP_DEST_SUBFOLDER</ns0:Name>
<ns0:ValueType>Text</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
<ns0:Text>ARMTemplates</ns0:Text>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDGIT_INP_FILELIST</ns0:Name>
<ns0:ValueType>Text</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
<ns0:Text>.</ns0:Text>
</ns0:PluginInput>
</ns0:PluginInputs>
<ns0:UserInputs/>
<ns0:PluginOutputs/>
<ns0:UserOutputs/>
</ns0:InvokePlugin>
</ns0:Step>
<ns0:Step>
<ns1:Name>commit</ns1:Name>
<ns1:StepId>5</ns1:StepId>
<ns0:InvokePlugin>
<ns0:PluginName>FlexagonGITPlugin</ns0:PluginName>
<ns0:PluginOperation>commit</ns0:PluginOperation>
<ns0:EndpointInstanceOverrideExpression>false</ns0:EndpointInstanceOverrideExpression>
<ns0:InvokePluginTypeVersion>v2</ns0:InvokePluginTypeVersion>
<ns0:consumesArtifacts>false</ns0:consumesArtifacts>
<ns0:producesArtifacts>false</ns0:producesArtifacts>
<ns0:EndpointSelection>
<ns0:EndpointSelectionChoice>All</ns0:EndpointSelectionChoice>
</ns0:EndpointSelection>
<ns0:EndpointExecutionChoice>Any</ns0:EndpointExecutionChoice>
<ns0:PluginInputs>
<ns0:PluginInput>
<ns0:Name>FDGIT_INP_INSTANCE_CODE</ns0:Name>
<ns0:ValueType>Text</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
<ns0:Text>SYNAPSEARM</ns0:Text>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDGIT_INP_DEST_SUBFOLDER</ns0:Name>
<ns0:ValueType>Text</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
<ns0:Text>ARMTemplates</ns0:Text>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDGIT_INP_NAME</ns0:Name>
<ns0:ValueType>Text</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDGIT_INP_EMAIL</ns0:Name>
<ns0:ValueType>Text</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDGIT_INP_REVISION_MESSAGE</ns0:Name>
<ns0:ValueType>Expression</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
<ns0:Value>
<ns0:Expression>&quot;ARM Template updated: &quot;+ FD_PROJECT_VERSION</ns0:Expression>
</ns0:Value>
</ns0:PluginInput>
</ns0:PluginInputs>
<ns0:UserInputs/>
<ns0:PluginOutputs/>
<ns0:UserOutputs/>
</ns0:InvokePlugin>
</ns0:Step>
<ns0:Step>
<ns1:Name>push</ns1:Name>
<ns1:StepId>6</ns1:StepId>
<ns0:InvokePlugin>
<ns0:PluginName>FlexagonGITPlugin</ns0:PluginName>
<ns0:PluginOperation>push</ns0:PluginOperation>
<ns0:EndpointInstanceOverrideExpression>false</ns0:EndpointInstanceOverrideExpression>
<ns0:InvokePluginTypeVersion>v2</ns0:InvokePluginTypeVersion>
<ns0:consumesArtifacts>false</ns0:consumesArtifacts>
<ns0:producesArtifacts>false</ns0:producesArtifacts>
<ns0:EndpointSelection>
<ns0:EndpointSelectionChoice>All</ns0:EndpointSelectionChoice>
</ns0:EndpointSelection>
<ns0:EndpointExecutionChoice>Any</ns0:EndpointExecutionChoice>
<ns0:PluginInputs>
<ns0:PluginInput>
<ns0:Name>FDGIT_INP_INSTANCE_CODE</ns0:Name>
<ns0:ValueType>Text</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
<ns0:Text>SYNAPSEARM</ns0:Text>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDGIT_INP_DEST_SUBFOLDER</ns0:Name>
<ns0:ValueType>Text</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
<ns0:Text>ARMTemplates</ns0:Text>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDGIT_INP_BRANCH</ns0:Name>
<ns0:ValueType>Text</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
<ns0:Text>flexdeploy</ns0:Text>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDGIT_INP_FOLLOW_TAGS</ns0:Name>
<ns0:ValueType>Text</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>Boolean</ns1:Type>
<ns0:Text>false</ns0:Text>
</ns0:PluginInput>
</ns0:PluginInputs>
<ns0:UserInputs/>
<ns0:PluginOutputs/>
<ns0:UserOutputs/>
</ns0:InvokePlugin>
</ns0:Step>
</ns0:Steps>
</ns0:WorkFlow>

Project Configuration

Create a Project by choosing the Classification: Package-based and Project Types as Generic

Once it is created the Source Control needs to be configured, so that we can discover the files from the respective repository.

 

For example, this is how the repository looks like where we have all the artifacts uploaded from Synapse Dev Workspace.

Discover the files using File Catalog tab

Now we can create Package upon selecting specific files for which the ARM template should get generated and the specific resources would be deployed to the Target Synapse Workspace.

Say we want to selectively migrate the linkedservice AzureBlobStorageDemo to the target workspace, in that case we can create a package linkedservice and add it in.

Click on the Configuration tab, select General and update the Build workflow with respective Target groups.

We are not configuring any Deploy workflow in this Project for the purpose of this Tutorial, as all we need is to create the ARM template and upload it to GIT.

Execution

Initiate Build on the selected Package “linkedservice”.

Note: The ARM templates are published to Azure DevOps Feed as Artifacts with the package name as a keyword in it. Example: if the FD project name is ExtractSynapseArtifacts and the package name is “linkedservice” then the artifacts package name would be “linkedservice-extractsynapseartifacts-armtemplate“. Now Microsoft has certain restrictions on the naming of the Azure Artifacts, hence please follow the guide before you name the package that you create in FD or else adjust your workflow to be in compliance. https://learn.microsoft.com/en-us/azure/devops/organizations/settings/naming-restrictions?view=azure-devops

To verify, clicked on the Artifacts tab and verified the ARM template and it shows up with just one selected pipeline.

The ARM template is now uploaded to repository

The folder name is following the naming we selected for the package name in FD for right control. If any parameter is to be added/updated or some other manipulation is to be done in the ARM template json in terms of variables or parameters, it can be done. But the integrity of the json file should remain intact.

Workflow configuration for fetching the ARM template from the repository and initiate the Synapse Release pipeline

Build Workflow:

 

<?xml version="1.0" encoding="Unicode"?>
<ns0:WorkFlow xmlns:ns1="http://flexagon.com/flexdeploy/workflow/common" xmlns:ns0="http://flexagon.com/flexdeploy/workflow">
<ns1:Name>SynapseBuild</ns1:Name>
<ns1:Description></ns1:Description>
<ns0:Steps>
<ns0:Step>
<ns1:Name>saveArtifacts</ns1:Name>
<ns1:StepId>1</ns1:StepId>
<ns0:InvokePlugin>
<ns0:PluginName>FlexagonFilePlugin</ns0:PluginName>
<ns0:PluginOperation>saveArtifacts</ns0:PluginOperation>
<ns0:EndpointInstanceOverrideExpression>false</ns0:EndpointInstanceOverrideExpression>
<ns0:InvokePluginTypeVersion>v2</ns0:InvokePluginTypeVersion>
<ns0:consumesArtifacts>false</ns0:consumesArtifacts>
<ns0:producesArtifacts>true</ns0:producesArtifacts>
<ns0:EndpointSelection>
<ns0:EndpointSelectionChoice>All</ns0:EndpointSelectionChoice>
</ns0:EndpointSelection>
<ns0:EndpointExecutionChoice>Any</ns0:EndpointExecutionChoice>
<ns0:PluginInputs>
<ns0:PluginInput>
<ns0:Name>FDFILE_INP_SOURCE_SUBFOLDER</ns0:Name>
<ns0:ValueType>Text</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDFILE_INP_FILE_FILTER</ns0:Name>
<ns0:ValueType>Text</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDFILE_INP_FILE_FILTER_EXCLUDED</ns0:Name>
<ns0:ValueType>Text</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDFILE_INP_TARGET_SUBFOLDER</ns0:Name>
<ns0:ValueType>Text</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
</ns0:PluginInput>
</ns0:PluginInputs>
<ns0:UserInputs/>
<ns0:PluginOutputs/>
<ns0:UserOutputs/>
</ns0:InvokePlugin>
</ns0:Step>
</ns0:Steps>
</ns0:WorkFlow>

Deploy Workflow:

 

<?xml version="1.0" encoding="Unicode"?>
<ns0:WorkFlow xmlns:ns1="http://flexagon.com/flexdeploy/workflow/common" xmlns:ns0="http://flexagon.com/flexdeploy/workflow">
<ns1:Name>SynapseARMDeploy</ns1:Name>
<ns1:Description></ns1:Description>
<ns0:Variables>
<ns0:Variable>
<ns1:Name>ENV_DETAILS</ns1:Name>
<ns1:Type>String</ns1:Type>
<ns0:returnAsOutput>true</ns0:returnAsOutput>
<ns1:isConstant>false</ns1:isConstant>
</ns0:Variable>
<ns0:Variable>
<ns1:Name>RELEASE_ID</ns1:Name>
<ns1:Type>String</ns1:Type>
<ns0:returnAsOutput>true</ns0:returnAsOutput>
<ns1:isConstant>false</ns1:isConstant>
</ns0:Variable>
<ns0:Variable>
<ns1:Name>ENVIRONMENT_ID</ns1:Name>
<ns1:Type>String</ns1:Type>
<ns0:returnAsOutput>true</ns0:returnAsOutput>
<ns1:isConstant>false</ns1:isConstant>
</ns0:Variable>
<ns0:Variable>
<ns1:Name>RELEASE_URL</ns1:Name>
<ns1:Type>String</ns1:Type>
<ns0:returnAsOutput>true</ns0:returnAsOutput>
<ns1:isConstant>false</ns1:isConstant>
</ns0:Variable>
<ns0:Variable>
<ns1:Name>FINALVERSION</ns1:Name>
<ns1:Type>String</ns1:Type>
<ns0:returnAsOutput>true</ns0:returnAsOutput>
<ns1:isConstant>false</ns1:isConstant>
</ns0:Variable>
</ns0:Variables>
<ns0:Steps>
<ns0:Step>
<ns1:Name>execute</ns1:Name>
<ns1:StepId>1</ns1:StepId>
<ns0:InvokePlugin>
<ns0:PluginName>FlexagonShellPlugin</ns0:PluginName>
<ns0:PluginOperation>execute</ns0:PluginOperation>
<ns0:EndpointInstanceOverrideExpression>false</ns0:EndpointInstanceOverrideExpression>
<ns0:InvokePluginTypeVersion>v2</ns0:InvokePluginTypeVersion>
<ns0:consumesArtifacts>true</ns0:consumesArtifacts>
<ns0:producesArtifacts>false</ns0:producesArtifacts>
<ns0:EndpointSelection>
<ns0:EndpointSelectionChoice>All</ns0:EndpointSelectionChoice>
</ns0:EndpointSelection>
<ns0:EndpointExecutionChoice>Any</ns0:EndpointExecutionChoice>
<ns0:PluginInputs>
<ns0:PluginInput>
<ns0:Name>FDSHELL_INP_CODE_SNIPPET</ns0:Name>
<ns0:ValueType>Text</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
<ns0:Text>mkdir -p $FD_TEMP_DIR/ARMTEMPLATES
find $FD_ARTIFACTS_DIR -type f -name &quot;Template*.json&quot; -exec cp {} $FD_TEMP_DIR/ARMTEMPLATES \;</ns0:Text>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDSHELL_INP_STOP_ON_ERROR</ns0:Name>
<ns0:ValueType>Text</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>Boolean</ns1:Type>
<ns0:Text>false</ns0:Text>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDSHELL_INP_DISABLE_ECHO</ns0:Name>
<ns0:ValueType>Text</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>Boolean</ns1:Type>
<ns0:Text>false</ns0:Text>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDSHELL_INP_RESTRICT_ENVIRONMENT</ns0:Name>
<ns0:ValueType>Text</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDSHELL_INP_NO_SECURE_VARIABLES</ns0:Name>
<ns0:ValueType>Text</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>Boolean</ns1:Type>
<ns0:Text>false</ns0:Text>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDSHELL_INP_LOCK</ns0:Name>
<ns0:ValueType>Text</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
</ns0:PluginInput>
</ns0:PluginInputs>
<ns0:UserInputs/>
<ns0:PluginOutputs/>
<ns0:UserOutputs/>
</ns0:InvokePlugin>
</ns0:Step>
<ns0:Step>
<ns1:Name>Assign</ns1:Name>
<ns1:StepId>2</ns1:StepId>
<ns0:Assign>
<ns0:From>
<ns0:Expression>PACKAGE_VERSION.substring(0,PACKAGE_VERSION.lastIndexOf(&quot;.&quot;) +1) + FD_WORKFLOW_EXECUTION_ID</ns0:Expression>
</ns0:From>
<ns0:To>FINALVERSION</ns0:To>
</ns0:Assign>
</ns0:Step>
<ns0:Step>
<ns1:Name>publishArtifacts</ns1:Name>
<ns1:StepId>3</ns1:StepId>
<ns0:InvokePlugin>
<ns0:PluginName>FlexagonAzurePlugin</ns0:PluginName>
<ns0:PluginOperation>publishArtifacts</ns0:PluginOperation>
<ns0:EndpointInstanceOverrideExpression>false</ns0:EndpointInstanceOverrideExpression>
<ns0:InvokePluginTypeVersion>v2</ns0:InvokePluginTypeVersion>
<ns0:consumesArtifacts>false</ns0:consumesArtifacts>
<ns0:producesArtifacts>false</ns0:producesArtifacts>
<ns0:EndpointSelection>
<ns0:EndpointSelectionChoice>All</ns0:EndpointSelectionChoice>
</ns0:EndpointSelection>
<ns0:EndpointExecutionChoice>Any</ns0:EndpointExecutionChoice>
<ns0:PluginInputs>
<ns0:PluginInput>
<ns0:Name>FDAZ_DEVOPS_INP_FEED</ns0:Name>
<ns0:ValueType>Expression</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
<ns0:Value>
<ns0:Expression>FEED_NAME</ns0:Expression>
</ns0:Value>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDAZ_DEVOPS_INP_PACKAGE_NAME</ns0:Name>
<ns0:ValueType>Expression</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
<ns0:Value>
<ns0:Expression>FD_PACKAGE_NAME + &quot;-&quot; + PACKAGE_NAME</ns0:Expression>
</ns0:Value>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDAZ_DEVOPS_INP_PACKAGE_VERSION</ns0:Name>
<ns0:ValueType>Expression</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
<ns0:Value>
<ns0:Expression>FINALVERSION</ns0:Expression>
</ns0:Value>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDAZ_DEVOPS_INP_PACKAGE_DESCRIPTION</ns0:Name>
<ns0:ValueType>Text</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDAZ_DEVOPS_INP_PROJECT_NAME</ns0:Name>
<ns0:ValueType>Expression</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
<ns0:Value>
<ns0:Expression>PROJECT_NAME</ns0:Expression>
</ns0:Value>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDAZ_DEVOPS_INP_PACKAGE_PATH</ns0:Name>
<ns0:ValueType>Expression</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
<ns0:Value>
<ns0:Expression>FD_TEMP_DIR + &quot;/ARMTEMPLATES&quot;</ns0:Expression>
</ns0:Value>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDAZ_DEVOPS_INP_ADDITIONAL_PARAMS</ns0:Name>
<ns0:ValueType>Text</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
</ns0:PluginInput>
</ns0:PluginInputs>
<ns0:UserInputs/>
<ns0:PluginOutputs>
<ns0:OutputValue>
<ns0:NameInCallee>FDAZ_DEVOPS_OUT_ERR</ns0:NameInCallee>
</ns0:OutputValue>
<ns0:OutputValue>
<ns0:NameInCallee>FDAZ_DEVOPS_OUT_RESP</ns0:NameInCallee>
</ns0:OutputValue>
</ns0:PluginOutputs>
<ns0:UserOutputs/>
</ns0:InvokePlugin>
</ns0:Step>
<ns0:Step>
<ns1:Name>createRelease</ns1:Name>
<ns1:StepId>4</ns1:StepId>
<ns0:InvokePlugin>
<ns0:PluginName>FlexagonAzurePlugin</ns0:PluginName>
<ns0:PluginOperation>createRelease</ns0:PluginOperation>
<ns0:EndpointInstanceOverrideExpression>false</ns0:EndpointInstanceOverrideExpression>
<ns0:InvokePluginTypeVersion>v2</ns0:InvokePluginTypeVersion>
<ns0:consumesArtifacts>false</ns0:consumesArtifacts>
<ns0:producesArtifacts>false</ns0:producesArtifacts>
<ns0:EndpointSelection>
<ns0:EndpointSelectionChoice>All</ns0:EndpointSelectionChoice>
</ns0:EndpointSelection>
<ns0:EndpointExecutionChoice>Any</ns0:EndpointExecutionChoice>
<ns0:PluginInputs>
<ns0:PluginInput>
<ns0:Name>FDAZ_DEVOPS_INP_RELEASE_DEFINITION_ID</ns0:Name>
<ns0:ValueType>Expression</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
<ns0:Value>
<ns0:Expression>RELEASE_DEFINITION_ID</ns0:Expression>
</ns0:Value>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDAZ_DEVOPS_INP_ARTIFACTS_PAYLOAD</ns0:Name>
<ns0:ValueType>Text</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDAZ_DEVOPS_INP_PROJECT_NAME</ns0:Name>
<ns0:ValueType>Expression</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
<ns0:Value>
<ns0:Expression>PROJECT_NAME</ns0:Expression>
</ns0:Value>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDAZ_DEVOPS_INP_VARIABLES_LIST</ns0:Name>
<ns0:ValueType>Expression</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
<ns0:Value>
<ns0:Expression>&quot;feedName:&quot; + PROJECT_NAME + &quot;/&quot; + FEED_NAME + &quot;##packageName:&quot; + FD_PACKAGE_NAME + &quot;-&quot; + PACKAGE_NAME + &quot;##packageVersion:&quot; + FINALVERSION</ns0:Expression>
</ns0:Value>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDAZ_DEVOPS_INP_PROPERTIES</ns0:Name>
<ns0:ValueType>Text</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDAZ_DEVOPS_INP_MANUAL_ENVIRONMENTS</ns0:Name>
<ns0:ValueType>Text</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDAZ_DEVOPS_INP_RELEASE_STATUS_CHECK</ns0:Name>
<ns0:ValueType>Text</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>Boolean</ns1:Type>
<ns0:Text>false</ns0:Text>
</ns0:PluginInput>
</ns0:PluginInputs>
<ns0:UserInputs/>
<ns0:PluginOutputs>
<ns0:OutputValue>
<ns0:NameInCallee>FDAZ_DEVOPS_OUT_RESP</ns0:NameInCallee>
</ns0:OutputValue>
<ns0:OutputValue>
<ns0:NameInCallee>FDAZ_DEVOPS_OUT_RELEASE_WEB_URL</ns0:NameInCallee>
</ns0:OutputValue>
<ns0:OutputValue>
<ns0:NameInCallee>FDAZ_DEVOPS_OUT_REL_ENV_STAGE_DETAILS</ns0:NameInCallee>
<ns0:NameInCaller>ENV_DETAILS</ns0:NameInCaller>
</ns0:OutputValue>
<ns0:OutputValue>
<ns0:NameInCallee>FDAZ_DEVOPS_OUT_RELEASE_ID</ns0:NameInCallee>
<ns0:NameInCaller>RELEASE_ID</ns0:NameInCaller>
</ns0:OutputValue>
</ns0:PluginOutputs>
<ns0:UserOutputs/>
</ns0:InvokePlugin>
</ns0:Step>
<ns0:Step>
<ns1:Name>parseJson</ns1:Name>
<ns1:StepId>5</ns1:StepId>
<ns0:InvokePlugin>
<ns0:PluginName>FlexagonXPathPlugin</ns0:PluginName>
<ns0:PluginOperation>parseJson</ns0:PluginOperation>
<ns0:EndpointInstanceOverrideExpression>false</ns0:EndpointInstanceOverrideExpression>
<ns0:InvokePluginTypeVersion>v2</ns0:InvokePluginTypeVersion>
<ns0:consumesArtifacts>false</ns0:consumesArtifacts>
<ns0:producesArtifacts>false</ns0:producesArtifacts>
<ns0:EndpointSelection>
<ns0:EndpointSelectionChoice>All</ns0:EndpointSelectionChoice>
</ns0:EndpointSelection>
<ns0:EndpointExecutionChoice>Any</ns0:EndpointExecutionChoice>
<ns0:PluginInputs>
<ns0:PluginInput>
<ns0:Name>FDP_SOURCE</ns0:Name>
<ns0:ValueType>Expression</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
<ns0:Value>
<ns0:Expression>ENV_DETAILS</ns0:Expression>
</ns0:Value>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDP_XPATH</ns0:Name>
<ns0:ValueType>Expression</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
<ns0:Value>
<ns0:Expression>'$..[?(@.name==\''+FD_ENVIRONMENT_NAME+'\')].id'</ns0:Expression>
</ns0:Value>
</ns0:PluginInput>
</ns0:PluginInputs>
<ns0:UserInputs/>
<ns0:PluginOutputs>
<ns0:OutputValue>
<ns0:NameInCallee>FDP_VALUE</ns0:NameInCallee>
<ns0:NameInCaller>ENVIRONMENT_ID</ns0:NameInCaller>
</ns0:OutputValue>
</ns0:PluginOutputs>
<ns0:UserOutputs/>
</ns0:InvokePlugin>
</ns0:Step>
<ns0:Step>
<ns1:Name>updateReleaseEnvStatus</ns1:Name>
<ns1:StepId>6</ns1:StepId>
<ns0:InvokePlugin>
<ns0:PluginName>FlexagonAzurePlugin</ns0:PluginName>
<ns0:PluginOperation>updateReleaseEnvStatus</ns0:PluginOperation>
<ns0:EndpointInstanceOverrideExpression>false</ns0:EndpointInstanceOverrideExpression>
<ns0:InvokePluginTypeVersion>v2</ns0:InvokePluginTypeVersion>
<ns0:consumesArtifacts>false</ns0:consumesArtifacts>
<ns0:producesArtifacts>false</ns0:producesArtifacts>
<ns0:EndpointSelection>
<ns0:EndpointSelectionChoice>All</ns0:EndpointSelectionChoice>
</ns0:EndpointSelection>
<ns0:EndpointExecutionChoice>Any</ns0:EndpointExecutionChoice>
<ns0:PluginInputs>
<ns0:PluginInput>
<ns0:Name>FDAZ_DEVOPS_INP_RELEASE_ID</ns0:Name>
<ns0:ValueType>Expression</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>Integer</ns1:Type>
<ns0:Value>
<ns0:Expression>RELEASE_ID</ns0:Expression>
</ns0:Value>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDAZ_DEVOPS_INP_RELEASE_ENVIRONMENT_ID</ns0:Name>
<ns0:ValueType>Expression</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>Integer</ns1:Type>
<ns0:Value>
<ns0:Expression>ENVIRONMENT_ID.substring(1,ENVIRONMENT_ID.length()-1)</ns0:Expression>
</ns0:Value>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDAZ_DEVOPS_INP_PROJECT_NAME</ns0:Name>
<ns0:ValueType>Expression</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
<ns0:Value>
<ns0:Expression>PROJECT_NAME</ns0:Expression>
</ns0:Value>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDAZ_DEVOPS_INP_RELEASE_ENVIRONMENT_STATUS</ns0:Name>
<ns0:ValueType>Text</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
<ns0:Text>InProgress</ns0:Text>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDAZ_DEVOPS_INP_VARIABLES_LIST</ns0:Name>
<ns0:ValueType>Expression</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
<ns0:Value>
<ns0:Expression>ENVIRONMENT_VARIABLES_LIST</ns0:Expression>
</ns0:Value>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDAZ_DEVOPS_INP_RELEASE_COMMENT</ns0:Name>
<ns0:ValueType>Text</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDAZ_DEVOPS_INP_SCHEDULED_DEPLOYMENT_TIME</ns0:Name>
<ns0:ValueType>Text</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>String</ns1:Type>
</ns0:PluginInput>
<ns0:PluginInput>
<ns0:Name>FDAZ_DEVOPS_INP_REL_ENV_STATUS_CHECK</ns0:Name>
<ns0:ValueType>Text</ns0:ValueType>
<ns0:Encrypted>false</ns0:Encrypted>
<ns1:Type>Boolean</ns1:Type>
<ns0:Text>true</ns0:Text>
</ns0:PluginInput>
</ns0:PluginInputs>
<ns0:UserInputs/>
<ns0:PluginOutputs>
<ns0:OutputValue>
<ns0:NameInCallee>FDAZ_DEVOPS_OUT_RESP</ns0:NameInCallee>
</ns0:OutputValue>
<ns0:OutputValue>
<ns0:NameInCallee>FDAZ_DEVOPS_OUT_REL_ENV_WEB_URL</ns0:NameInCallee>
<ns0:NameInCaller>RELEASE_URL</ns0:NameInCaller>
</ns0:OutputValue>
</ns0:PluginOutputs>
<ns0:UserOutputs/>
</ns0:InvokePlugin>
</ns0:Step>
</ns0:Steps>
</ns0:WorkFlow>

Project Configuration

Create a Project by choosing the Classification: Package-based and Project Types as Generic

Once it is created the Source Control needs to be configured, so that we can discover the files from the respective repository. This time the source control is the one where we have uploaded the ARM template.

Discover the files using File Catalog tab

Now we can create Package upon selecting specific ARM template that to be deployed to the Target Synapse Workspace.

Click on the Configuration tab, select General and update the Build and Deploy workflows with respective Target groups.

Parameterizing the values

Replacement configuration on Project

Starting 7.0 we have a new feature that allows us to replace a string in any file with another string based on as it is executed to different environment. Ref: Replacements - FlexDeploy 7.0 - Confluence (atlassian.net)

For our use-case a specific parameter as below is created in the Linked Service:

 

Our objective is that when this linked service gets deployed to target cicd-demo-uat workspace, the value would get replaced with “UAT”.

In the ARM template that we stored in repository, it shows up like this:

Using Environment Variables for the parameters

Say the linked service we are using is having the connection params in the source workspace as the following:

 

The parameter file in ARM template folder looks like:

If the value for the Storage Account is to be changed then the parameter needs to be passed in AzureBlobStorageDemo_connectionString.

Hence, we can configure the below connection string with the parameter name in the Target Group properties for the code: ENVIRONMENT_VARIABLES_LIST.

{ "resourceGroup": { "value": "synapse-demo" }, "workspaceName": { "value": "cicd-demo-uat" }, "overrideParams": { "value": "-AzureBlobStorageDemo_connectionString DefaultEndpointsProtocol=https;AccountName=syndlakeacntuat;EndpointSuffix=core.windows.net;" } }

Anything that is specified as parameter in the ARM templates, can be parameterized like above during deployment to Target Workspace

Execution

Initiate Build on the selected Package “linkedservice”.

To verify, clicked on the Artifacts tab and verified the ARM template.

 

Click on Deploy for the same

Post deployment if we verify the Linked Service in UAT workspace, we see the updated values in there:

 

 

The following macros are not currently supported in the footer:
  • style