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:
Configuring a Generic Package based project, create and deploy the ARM templates being generated based on those specific resources.
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-20240402-085158.png](https://flexagon.atlassian.net/wiki/download/thumbnails/10926708845/image-20240402-085158.png?version=1&modificationDate=1724704139184&cacheVersion=1&api=v2&width=1541&height=807)
CreateARMTemplate-Inc
steps:
- id: '1'
name: publishArtifacts
type: INVOKE_PLUGIN
data:
pluginName: FlexagonAzurePlugin
pluginOperation: publishArtifacts
inputs:
- name: FDAZ_DEVOPS_INP_FEED
value:
value: FEED_NAME
isExpression: true
isEncrypted: false
- name: FDAZ_DEVOPS_INP_PACKAGE_NAME
value:
value: FD_PACKAGE_NAME + "-" + ARTIFACTS_PACKAGE_NAME
isExpression: true
isEncrypted: false
- name: FDAZ_DEVOPS_INP_PACKAGE_VERSION
value:
value: PACKAGE_VERSION
isExpression: true
isEncrypted: false
- name: FDAZ_DEVOPS_INP_PACKAGE_DESCRIPTION
value:
isExpression: false
isEncrypted: false
- name: FDAZ_DEVOPS_INP_PROJECT_NAME
value:
value: PROJECT_NAME
isExpression: true
isEncrypted: false
- name: FDAZ_DEVOPS_INP_PACKAGE_PATH
value:
value: FD_TEMP_DIR
isExpression: true
isEncrypted: false
- name: FDAZ_DEVOPS_INP_ADDITIONAL_PARAMS
value:
isExpression: false
isEncrypted: false
endpointInstanceOverride:
isExpression: false
consumesArtifacts: false
producesArtifacts: false
endpointSelection:
choice: All
endpointExecution:
choice: Any
stopOnError: false
outputs:
- output: FDAZ_DEVOPS_OUT_ERR
- output: FDAZ_DEVOPS_OUT_RESP
userInputs: []
userOutputs: []
- id: '2'
name: buildPipeline
type: INVOKE_PLUGIN
data:
pluginName: FlexagonAzurePlugin
pluginOperation: buildPipeline
inputs:
- name: FDAZ_DEVOPS_INP_DEFINITION_NAME
value:
value: BUILD_DEFINITION_NAME
isExpression: true
isEncrypted: false
- name: FDAZ_DEVOPS_INP_BUILD_DEFINITION_ID
value:
isExpression: false
isEncrypted: false
- name: FDAZ_DEVOPS_INP_QUEUE_ID
value:
isExpression: false
isEncrypted: false
- name: FDAZ_DEVOPS_INP_COMMIT_ID
value:
isExpression: false
isEncrypted: false
- name: FDAZ_DEVOPS_INP_BRANCH_NAME
value:
isExpression: false
isEncrypted: false
- name: FDAZ_DEVOPS_INP_PROJECT_NAME
value:
value: PROJECT_NAME
isExpression: true
isEncrypted: false
- name: FDAZ_DEVOPS_INP_VARIABLES_LIST
value:
value: >-
VARIABLES_LIST + "##artifactsPackageName:" + FD_PACKAGE_NAME + "-"
+ ARTIFACTS_PACKAGE_NAME + "##feedName:" + PROJECT_NAME + "/" +
FEED_NAME
isExpression: true
isEncrypted: false
- name: FDAZ_DEVOPS_INP_PACKAGE_NAME
value:
value: FD_PACKAGE_NAME + "-" + PACKAGE_NAME
isExpression: true
isEncrypted: false
- name: FDAZ_DEVOPS_INP_ADDITIONAL_PARAMS
value:
isExpression: false
isEncrypted: false
endpointInstanceOverride:
isExpression: false
consumesArtifacts: false
producesArtifacts: false
endpointSelection:
choice: All
endpointExecution:
choice: Any
stopOnError: false
outputs:
- output: FDAZ_DEVOPS_OUT_ERR
- output: FDAZ_DEVOPS_OUT_RESP
- output: FDAZ_DEVOPS_OUT_BUILD_PIPELINE_WEB_URL
userInputs: []
userOutputs: []
- id: '3'
name: downloadArtifacts
type: INVOKE_PLUGIN
data:
pluginName: FlexagonAzurePlugin
pluginOperation: downloadArtifacts
inputs:
- name: FDAZ_DEVOPS_INP_FEED
value:
value: FEED_NAME
isExpression: true
isEncrypted: false
- name: FDAZ_DEVOPS_INP_PACKAGE_NAME
value:
value: FD_PACKAGE_NAME + "-" + PACKAGE_NAME
isExpression: true
isEncrypted: false
- name: FDAZ_DEVOPS_INP_PACKAGE_VERSION
value:
value: PACKAGE_VERSION
isExpression: true
isEncrypted: false
- name: FDAZ_DEVOPS_INP_PROJECT_NAME
value:
value: PROJECT_NAME
isExpression: true
isEncrypted: false
- name: FDAZ_DEVOPS_INP_PACKAGE_PATH
value:
isExpression: false
isEncrypted: false
- name: FDAZ_DEVOPS_INP_ADDITIONAL_PARAMS
value:
isExpression: false
isEncrypted: false
endpointInstanceOverride:
isExpression: false
consumesArtifacts: false
producesArtifacts: true
endpointSelection:
choice: All
endpointExecution:
choice: Any
stopOnError: false
outputs:
- output: FDAZ_DEVOPS_OUT_ERR
- output: FDAZ_DEVOPS_OUT_RESP
userInputs: []
userOutputs: []
Deploy Workflow:
![image-20240402-085311.png](https://flexagon.atlassian.net/wiki/download/thumbnails/10926708845/image-20240402-085311.png?version=1&modificationDate=1724704138700&cacheVersion=1&api=v2&width=1541&height=802)
DeploySynapseArtifacts-Inc
variables:
- code: ENV_DETAILS
dataType: String
returnAsOutput: true
constant: false
encrypted: false
scope: LOCAL
- code: RELEASE_ID
dataType: String
returnAsOutput: true
constant: false
encrypted: false
scope: LOCAL
- code: ENVIRONMENT_ID
dataType: String
returnAsOutput: true
constant: false
encrypted: false
scope: LOCAL
- code: RELEASE_URL
dataType: String
returnAsOutput: true
constant: false
encrypted: false
scope: LOCAL
steps:
- id: '1'
name: createRelease
type: INVOKE_PLUGIN
data:
pluginName: FlexagonAzurePlugin
pluginOperation: createRelease
inputs:
- name: FDAZ_DEVOPS_INP_RELEASE_DEFINITION_ID
value:
value: RELEASE_DEFINITION_ID
isExpression: true
isEncrypted: false
- name: FDAZ_DEVOPS_INP_ARTIFACTS_PAYLOAD
value:
isExpression: false
isEncrypted: false
- name: FDAZ_DEVOPS_INP_PROJECT_NAME
value:
value: PROJECT_NAME
isExpression: true
isEncrypted: false
- name: FDAZ_DEVOPS_INP_VARIABLES_LIST
value:
value: >-
"feedName:" + PROJECT_NAME + "/" + FEED_NAME + "##packageName:" +
FD_PACKAGE_NAME + "-" + PACKAGE_NAME + "##packageVersion:" +
PACKAGE_VERSION
isExpression: true
isEncrypted: false
- name: FDAZ_DEVOPS_INP_PROPERTIES
value:
isExpression: false
isEncrypted: false
- name: FDAZ_DEVOPS_INP_MANUAL_ENVIRONMENTS
value:
isExpression: false
isEncrypted: false
- name: FDAZ_DEVOPS_INP_RELEASE_STATUS_CHECK
value:
value: 'false'
isExpression: false
isEncrypted: false
endpointInstanceOverride:
isExpression: false
consumesArtifacts: false
producesArtifacts: false
endpointSelection:
choice: All
endpointExecution:
choice: Any
stopOnError: false
outputs:
- output: FDAZ_DEVOPS_OUT_RESP
- output: FDAZ_DEVOPS_OUT_RELEASE_WEB_URL
- output: FDAZ_DEVOPS_OUT_REL_ENV_STAGE_DETAILS
variable: ENV_DETAILS
- output: FDAZ_DEVOPS_OUT_RELEASE_ID
variable: RELEASE_ID
userInputs: []
userOutputs: []
- id: '2'
name: Parse Environment specific Id
type: INVOKE_PLUGIN
data:
pluginName: FlexagonXPathPlugin
pluginOperation: parseJson
inputs:
- name: FDP_SOURCE
value:
value: ENV_DETAILS
isExpression: true
isEncrypted: false
- name: FDP_XPATH
value:
value: '''$..[?(@.name==\''''+FD_ENVIRONMENT_NAME+''\'')].id'''
isExpression: true
isEncrypted: false
endpointInstanceOverride:
isExpression: false
consumesArtifacts: false
producesArtifacts: false
endpointSelection:
choice: All
endpointExecution:
choice: Any
stopOnError: false
outputs:
- output: FDP_VALUE
variable: ENVIRONMENT_ID
userInputs: []
userOutputs: []
- id: '3'
name: updateReleaseEnvStatus
type: INVOKE_PLUGIN
data:
pluginName: FlexagonAzurePlugin
pluginOperation: updateReleaseEnvStatus
inputs:
- name: FDAZ_DEVOPS_INP_RELEASE_ID
value:
value: RELEASE_ID
isExpression: true
isEncrypted: false
- name: FDAZ_DEVOPS_INP_RELEASE_ENVIRONMENT_ID
value:
value: ENVIRONMENT_ID.substring(1,ENVIRONMENT_ID.length()-1)
isExpression: true
isEncrypted: false
- name: FDAZ_DEVOPS_INP_PROJECT_NAME
value:
value: PROJECT_NAME
isExpression: true
isEncrypted: false
- name: FDAZ_DEVOPS_INP_RELEASE_ENVIRONMENT_STATUS
value:
value: InProgress
isExpression: false
isEncrypted: false
- name: FDAZ_DEVOPS_INP_VARIABLES_LIST
value:
value: ENVIRONMENT_VARIABLES_LIST
isExpression: true
isEncrypted: false
- name: FDAZ_DEVOPS_INP_RELEASE_COMMENT
value:
isExpression: false
isEncrypted: false
- name: FDAZ_DEVOPS_INP_SCHEDULED_DEPLOYMENT_TIME
value:
isExpression: false
isEncrypted: false
- name: FDAZ_DEVOPS_INP_REL_ENV_STATUS_CHECK
value:
value: 'true'
isExpression: false
isEncrypted: false
endpointInstanceOverride:
isExpression: false
consumesArtifacts: false
producesArtifacts: false
endpointSelection:
choice: All
endpointExecution:
choice: Any
stopOnError: false
outputs:
- output: FDAZ_DEVOPS_OUT_RESP
- output: FDAZ_DEVOPS_OUT_REL_ENV_WEB_URL
variable: RELEASE_URL
userInputs: []
userOutputs: []
Project Configuration
Create a Project by choosing the Classification: Package-based and Project Types as Generic
![image-20240329-064826.png](https://flexagon.atlassian.net/wiki/download/thumbnails/10926708845/image-20240329-064826.png?version=1&modificationDate=1724704130929&cacheVersion=1&api=v2&width=760&height=270)
Once it is created the Source Control needs to be configured, so that we can discover the files from the respective repository.
![image-20240329-065458.png](https://flexagon.atlassian.net/wiki/download/thumbnails/10926708845/image-20240329-065458.png?version=1&modificationDate=1724704134537&cacheVersion=1&api=v2&width=760&height=226)
For example, this is how the repository looks like where we have all the artifacts uploaded from Synapse Dev Workspace.
![image-20240329-065647.png](https://flexagon.atlassian.net/wiki/download/thumbnails/10926708845/image-20240329-065647.png?version=1&modificationDate=1724704134108&cacheVersion=1&api=v2&width=760&height=357)
Discover the files using File Catalog tab
![image-20240329-065810.png](https://flexagon.atlassian.net/wiki/download/thumbnails/10926708845/image-20240329-065810.png?version=1&modificationDate=1724704133609&cacheVersion=1&api=v2&width=760&height=292)
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.
![image-20240329-072318.png](https://flexagon.atlassian.net/wiki/download/thumbnails/10926708845/image-20240329-072318.png?version=1&modificationDate=1724704137833&cacheVersion=1&api=v2&width=760&height=154)
Click on the Configuration tab, select General and update the Build and Deploy workflows along with respective Target groups.
![image-20240329-073458.png](https://flexagon.atlassian.net/wiki/download/thumbnails/10926708845/image-20240329-073458.png?version=1&modificationDate=1724704137389&cacheVersion=1&api=v2&width=760&height=334)
Execution
Initiate Build on the selected Package “pipeline”.
![image-20240329-074407.png](https://flexagon.atlassian.net/wiki/download/thumbnails/10926708845/image-20240329-074407.png?version=1&modificationDate=1724704136944&cacheVersion=1&api=v2&width=760&height=283)
To verify, clicked on the Artifacts tab and verified the ARM template and it shows up with just one selected pipeline.
![image-20240329-074601.png](https://flexagon.atlassian.net/wiki/download/thumbnails/10926708845/image-20240329-074601.png?version=1&modificationDate=1724704136469&cacheVersion=1&api=v2&width=760&height=418)
Now initiated the Deploy.
![image-20240329-075310.png](https://flexagon.atlassian.net/wiki/download/thumbnails/10926708845/image-20240329-075310.png?version=1&modificationDate=1724704136016&cacheVersion=1&api=v2&width=760&height=266)
![image-20240329-075452.png](https://flexagon.atlassian.net/wiki/download/thumbnails/10926708845/image-20240329-075452.png?version=1&modificationDate=1724704135542&cacheVersion=1&api=v2&width=760&height=152)
Flow (Approach B)
Workflow configuration for creating ARM template and upload to Repository
Build Workflow:
![image-20240329-080026.png](https://flexagon.atlassian.net/wiki/download/thumbnails/10926708845/image-20240329-080026.png?version=1&modificationDate=1724704135009&cacheVersion=1&api=v2&width=760&height=583)
ExportAndUploadtoGIT
steps:
- id: '1'
name: clone
type: INVOKE_PLUGIN
data:
pluginName: FlexagonGITPlugin
pluginOperation: clone
inputs:
- name: FDGIT_INP_INSTANCE_CODE
value:
value: SYNAPSEARM
isExpression: false
isEncrypted: false
- name: FDGIT_INP_DEST_SUBFOLDER
value:
value: ARMTemplates
isExpression: false
isEncrypted: false
- name: FDGIT_INP_BRANCH
value:
value: flexdeploy
isExpression: false
isEncrypted: false
- name: FDGIT_INP_TREELESS_CLONE
value:
value: 'false'
isExpression: false
isEncrypted: false
- name: FDGIT_INP_DEPTH
value:
value: ''
isExpression: false
isEncrypted: false
- name: FDGIT_INP_SPARSE_CHECKOUT_FOLDERS
value:
isExpression: false
isEncrypted: false
endpointInstanceOverride:
isExpression: false
consumesArtifacts: false
producesArtifacts: false
endpointSelection:
choice: All
endpointExecution:
choice: Any
stopOnError: false
outputs: []
userInputs: []
userOutputs: []
- id: '2'
name: Invoke Workflow
type: INVOKE_WORKFLOW
data:
inputs: []
workflowId: 7080183
outputs: []
- id: '3'
name: copy
type: INVOKE_PLUGIN
data:
pluginName: FlexagonFilePlugin
pluginOperation: copy
inputs:
- name: FDFILE_INP_FILE_FILTER
value:
value: Template*.json
isExpression: false
isEncrypted: false
- name: FDFILE_INP_FILE_FILTER_EXCLUDED
value:
isExpression: false
isEncrypted: false
- name: FDFILE_INP_SOURCE_PATH
value:
value: FD_ARTIFACTS_DIR
isExpression: true
isEncrypted: false
- name: FDFILE_INP_TARGET_PATH
value:
value: FD_TEMP_DIR+"/ARMTemplates/"+FD_PACKAGE_NAME
isExpression: true
isEncrypted: false
- name: FDFILE_INP_CLEAN_DIRECTORY
value:
value: 'true'
isExpression: false
isEncrypted: false
endpointInstanceOverride:
isExpression: false
consumesArtifacts: false
producesArtifacts: false
endpointSelection:
choice: All
endpointExecution:
choice: Any
stopOnError: false
outputs: []
userInputs: []
userOutputs: []
- id: '4'
name: add
type: INVOKE_PLUGIN
data:
pluginName: FlexagonGITPlugin
pluginOperation: add
inputs:
- name: FDGIT_INP_INSTANCE_CODE
value:
value: SYNAPSEARM
isExpression: false
isEncrypted: false
- name: FDGIT_INP_DEST_SUBFOLDER
value:
value: ARMTemplates
isExpression: false
isEncrypted: false
- name: FDGIT_INP_FILELIST
value:
value: .
isExpression: false
isEncrypted: false
endpointInstanceOverride:
isExpression: false
consumesArtifacts: false
producesArtifacts: false
endpointSelection:
choice: All
endpointExecution:
choice: Any
stopOnError: false
outputs: []
userInputs: []
userOutputs: []
- id: '5'
name: commit
type: INVOKE_PLUGIN
data:
pluginName: FlexagonGITPlugin
pluginOperation: commit
inputs:
- name: FDGIT_INP_INSTANCE_CODE
value:
value: SYNAPSEARM
isExpression: false
isEncrypted: false
- name: FDGIT_INP_DEST_SUBFOLDER
value:
value: ARMTemplates
isExpression: false
isEncrypted: false
- name: FDGIT_INP_NAME
value:
isExpression: false
isEncrypted: false
- name: FDGIT_INP_EMAIL
value:
isExpression: false
isEncrypted: false
- name: FDGIT_INP_REVISION_MESSAGE
value:
value: '"ARM Template updated: "+ FD_PROJECT_VERSION'
isExpression: true
isEncrypted: false
endpointInstanceOverride:
isExpression: false
consumesArtifacts: false
producesArtifacts: false
endpointSelection:
choice: All
endpointExecution:
choice: Any
stopOnError: false
outputs: []
userInputs: []
userOutputs: []
- id: '6'
name: push
type: INVOKE_PLUGIN
data:
pluginName: FlexagonGITPlugin
pluginOperation: push
inputs:
- name: FDGIT_INP_INSTANCE_CODE
value:
value: SYNAPSEARM
isExpression: false
isEncrypted: false
- name: FDGIT_INP_DEST_SUBFOLDER
value:
value: ARMTemplates
isExpression: false
isEncrypted: false
- name: FDGIT_INP_BRANCH
value:
value: flexdeploy
isExpression: false
isEncrypted: false
- name: FDGIT_INP_FOLLOW_TAGS
value:
value: 'false'
isExpression: false
isEncrypted: false
endpointInstanceOverride:
isExpression: false
consumesArtifacts: false
producesArtifacts: false
endpointSelection:
choice: All
endpointExecution:
choice: Any
stopOnError: false
outputs: []
userInputs: []
userOutputs: []
Project Configuration
Create a Project by choosing the Classification: Package-based and Project Types as Generic
![image-20240329-064826.png](https://flexagon.atlassian.net/wiki/download/thumbnails/10926708845/image-20240329-064826.png?version=1&modificationDate=1724704130929&cacheVersion=1&api=v2&width=760&height=270)
Once it is created the Source Control needs to be configured, so that we can discover the files from the respective repository.
![image-20240329-065458.png](https://flexagon.atlassian.net/wiki/download/thumbnails/10926708845/image-20240329-065458.png?version=1&modificationDate=1724704134537&cacheVersion=1&api=v2&width=760&height=226)
For example, this is how the repository looks like where we have all the artifacts uploaded from Synapse Dev Workspace.
![image-20240329-065647.png](https://flexagon.atlassian.net/wiki/download/thumbnails/10926708845/image-20240329-065647.png?version=1&modificationDate=1724704134108&cacheVersion=1&api=v2&width=760&height=357)
Discover the files using File Catalog tab
![image-20240329-065810.png](https://flexagon.atlassian.net/wiki/download/thumbnails/10926708845/image-20240329-065810.png?version=1&modificationDate=1724704133609&cacheVersion=1&api=v2&width=760&height=292)
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.
![image-20240329-080502.png](https://flexagon.atlassian.net/wiki/download/thumbnails/10926708845/image-20240329-080502.png?version=1&modificationDate=1724704133178&cacheVersion=1&api=v2&width=760&height=158)
Click on the Configuration tab, select General and update the Build workflow with respective Target groups.
![image-20240329-080557.png](https://flexagon.atlassian.net/wiki/download/thumbnails/10926708845/image-20240329-080557.png?version=1&modificationDate=1724704132762&cacheVersion=1&api=v2&width=760&height=144)
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”.
![image-20240329-080931.png](https://flexagon.atlassian.net/wiki/download/thumbnails/10926708845/image-20240329-080931.png?version=1&modificationDate=1724704132195&cacheVersion=1&api=v2&width=760&height=410)
To verify, clicked on the Artifacts tab and verified the ARM template and it shows up with just one selected pipeline.
![image-20240329-081014.png](https://flexagon.atlassian.net/wiki/download/thumbnails/10926708845/image-20240329-081014.png?version=1&modificationDate=1724704131700&cacheVersion=1&api=v2&width=760&height=379)
The ARM template is now uploaded to repository
![image-20240329-081607.png](https://flexagon.atlassian.net/wiki/download/thumbnails/10926708845/image-20240329-081607.png?version=1&modificationDate=1724704131309&cacheVersion=1&api=v2&width=760&height=279)
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:
SynapseBuild
steps:
- id: '1'
name: saveArtifacts
type: INVOKE_PLUGIN
data:
pluginName: FlexagonFilePlugin
pluginOperation: saveArtifacts
inputs:
- name: FDFILE_INP_SOURCE_SUBFOLDER
value:
isExpression: false
isEncrypted: false
- name: FDFILE_INP_FILE_FILTER
value:
isExpression: false
isEncrypted: false
- name: FDFILE_INP_FILE_FILTER_EXCLUDED
value:
isExpression: false
isEncrypted: false
- name: FDFILE_INP_TARGET_SUBFOLDER
value:
isExpression: false
isEncrypted: false
endpointInstanceOverride:
isExpression: false
consumesArtifacts: false
producesArtifacts: true
endpointSelection:
choice: All
endpointExecution:
choice: Any
stopOnError: false
outputs: []
userInputs: []
userOutputs: []
Deploy Workflow:
SynapseARMDeploy
variables:
- code: ENV_DETAILS
dataType: String
returnAsOutput: true
constant: false
encrypted: false
scope: LOCAL
- code: RELEASE_ID
dataType: String
returnAsOutput: true
constant: false
encrypted: false
scope: LOCAL
- code: ENVIRONMENT_ID
dataType: String
returnAsOutput: true
constant: false
encrypted: false
scope: LOCAL
- code: RELEASE_URL
dataType: String
returnAsOutput: true
constant: false
encrypted: false
scope: LOCAL
- code: FINALVERSION
dataType: String
returnAsOutput: true
constant: false
encrypted: false
scope: LOCAL
steps:
- id: '1'
name: execute
type: INVOKE_PLUGIN
data:
pluginName: FlexagonShellPlugin
pluginOperation: execute
inputs:
- name: FDSHELL_INP_CODE_SNIPPET
value:
value: "mkdir -p $FD_TEMP_DIR/ARMTEMPLATES\r\nfind $FD_ARTIFACTS_DIR -type f -name \"Template*.json\" -exec cp {} $FD_TEMP_DIR/ARMTEMPLATES \\;"
isExpression: false
isEncrypted: false
- name: FDSHELL_INP_STOP_ON_ERROR
value:
value: 'false'
isExpression: false
isEncrypted: false
- name: FDSHELL_INP_DISABLE_ECHO
value:
value: 'false'
isExpression: false
isEncrypted: false
- name: FDSHELL_INP_RESTRICT_ENVIRONMENT
value:
isExpression: false
isEncrypted: false
- name: FDSHELL_INP_NO_SECURE_VARIABLES
value:
value: 'false'
isExpression: false
isEncrypted: false
- name: FDSHELL_INP_LOCK
value:
isExpression: false
isEncrypted: false
endpointInstanceOverride:
isExpression: false
consumesArtifacts: true
producesArtifacts: false
endpointSelection:
choice: All
endpointExecution:
choice: Any
stopOnError: false
outputs: []
userInputs: []
userOutputs: []
- id: '2'
name: Assign
type: ASSIGN
data:
from: >-
PACKAGE_VERSION.substring(0,PACKAGE_VERSION.lastIndexOf(".") +1) +
FD_WORKFLOW_EXECUTION_ID
to: FINALVERSION
- id: '3'
name: publishArtifacts
type: INVOKE_PLUGIN
data:
pluginName: FlexagonAzurePlugin
pluginOperation: publishArtifacts
inputs:
- name: FDAZ_DEVOPS_INP_FEED
value:
value: FEED_NAME
isExpression: true
isEncrypted: false
- name: FDAZ_DEVOPS_INP_PACKAGE_NAME
value:
value: FD_PACKAGE_NAME + "-" + PACKAGE_NAME
isExpression: true
isEncrypted: false
- name: FDAZ_DEVOPS_INP_PACKAGE_VERSION
value:
value: FINALVERSION
isExpression: true
isEncrypted: false
- name: FDAZ_DEVOPS_INP_PACKAGE_DESCRIPTION
value:
isExpression: false
isEncrypted: false
- name: FDAZ_DEVOPS_INP_PROJECT_NAME
value:
value: PROJECT_NAME
isExpression: true
isEncrypted: false
- name: FDAZ_DEVOPS_INP_PACKAGE_PATH
value:
value: FD_TEMP_DIR + "/ARMTEMPLATES"
isExpression: true
isEncrypted: false
- name: FDAZ_DEVOPS_INP_ADDITIONAL_PARAMS
value:
isExpression: false
isEncrypted: false
endpointInstanceOverride:
isExpression: false
consumesArtifacts: false
producesArtifacts: false
endpointSelection:
choice: All
endpointExecution:
choice: Any
stopOnError: false
outputs:
- output: FDAZ_DEVOPS_OUT_ERR
- output: FDAZ_DEVOPS_OUT_RESP
userInputs: []
userOutputs: []
- id: '4'
name: createRelease
type: INVOKE_PLUGIN
data:
pluginName: FlexagonAzurePlugin
pluginOperation: createRelease
inputs:
- name: FDAZ_DEVOPS_INP_RELEASE_DEFINITION_ID
value:
value: RELEASE_DEFINITION_ID
isExpression: true
isEncrypted: false
- name: FDAZ_DEVOPS_INP_ARTIFACTS_PAYLOAD
value:
isExpression: false
isEncrypted: false
- name: FDAZ_DEVOPS_INP_PROJECT_NAME
value:
value: PROJECT_NAME
isExpression: true
isEncrypted: false
- name: FDAZ_DEVOPS_INP_VARIABLES_LIST
value:
value: >-
"feedName:" + PROJECT_NAME + "/" + FEED_NAME + "##packageName:" +
FD_PACKAGE_NAME + "-" + PACKAGE_NAME + "##packageVersion:" +
FINALVERSION
isExpression: true
isEncrypted: false
- name: FDAZ_DEVOPS_INP_PROPERTIES
value:
isExpression: false
isEncrypted: false
- name: FDAZ_DEVOPS_INP_MANUAL_ENVIRONMENTS
value:
isExpression: false
isEncrypted: false
- name: FDAZ_DEVOPS_INP_RELEASE_STATUS_CHECK
value:
value: 'false'
isExpression: false
isEncrypted: false
endpointInstanceOverride:
isExpression: false
consumesArtifacts: false
producesArtifacts: false
endpointSelection:
choice: All
endpointExecution:
choice: Any
stopOnError: false
outputs:
- output: FDAZ_DEVOPS_OUT_RESP
- output: FDAZ_DEVOPS_OUT_RELEASE_WEB_URL
- output: FDAZ_DEVOPS_OUT_REL_ENV_STAGE_DETAILS
variable: ENV_DETAILS
- output: FDAZ_DEVOPS_OUT_RELEASE_ID
variable: RELEASE_ID
userInputs: []
userOutputs: []
- id: '5'
name: parseJson
type: INVOKE_PLUGIN
data:
pluginName: FlexagonXPathPlugin
pluginOperation: parseJson
inputs:
- name: FDP_SOURCE
value:
value: ENV_DETAILS
isExpression: true
isEncrypted: false
- name: FDP_XPATH
value:
value: '''$..[?(@.name==\''''+FD_ENVIRONMENT_NAME+''\'')].id'''
isExpression: true
isEncrypted: false
endpointInstanceOverride:
isExpression: false
consumesArtifacts: false
producesArtifacts: false
endpointSelection:
choice: All
endpointExecution:
choice: Any
stopOnError: false
outputs:
- output: FDP_VALUE
variable: ENVIRONMENT_ID
userInputs: []
userOutputs: []
- id: '6'
name: updateReleaseEnvStatus
type: INVOKE_PLUGIN
data:
pluginName: FlexagonAzurePlugin
pluginOperation: updateReleaseEnvStatus
inputs:
- name: FDAZ_DEVOPS_INP_RELEASE_ID
value:
value: RELEASE_ID
isExpression: true
isEncrypted: false
- name: FDAZ_DEVOPS_INP_RELEASE_ENVIRONMENT_ID
value:
value: ENVIRONMENT_ID.substring(1,ENVIRONMENT_ID.length()-1)
isExpression: true
isEncrypted: false
- name: FDAZ_DEVOPS_INP_PROJECT_NAME
value:
value: PROJECT_NAME
isExpression: true
isEncrypted: false
- name: FDAZ_DEVOPS_INP_RELEASE_ENVIRONMENT_STATUS
value:
value: InProgress
isExpression: false
isEncrypted: false
- name: FDAZ_DEVOPS_INP_VARIABLES_LIST
value:
value: ENVIRONMENT_VARIABLES_LIST
isExpression: true
isEncrypted: false
- name: FDAZ_DEVOPS_INP_RELEASE_COMMENT
value:
isExpression: false
isEncrypted: false
- name: FDAZ_DEVOPS_INP_SCHEDULED_DEPLOYMENT_TIME
value:
isExpression: false
isEncrypted: false
- name: FDAZ_DEVOPS_INP_REL_ENV_STATUS_CHECK
value:
value: 'true'
isExpression: false
isEncrypted: false
endpointInstanceOverride:
isExpression: false
consumesArtifacts: false
producesArtifacts: false
endpointSelection:
choice: All
endpointExecution:
choice: Any
stopOnError: false
outputs:
- output: FDAZ_DEVOPS_OUT_RESP
- output: FDAZ_DEVOPS_OUT_REL_ENV_WEB_URL
variable: RELEASE_URL
userInputs: []
userOutputs: []
Project Configuration
Create a Project by choosing the Classification: Package-based and Project Types as Generic
![image-20240329-064826.png](https://flexagon.atlassian.net/wiki/download/thumbnails/10926708845/image-20240329-064826.png?version=1&modificationDate=1724704130929&cacheVersion=1&api=v2&width=760&height=270)
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.
![image-20240329-084510.png](https://flexagon.atlassian.net/wiki/download/thumbnails/10926708845/image-20240329-084510.png?version=1&modificationDate=1724704130419&cacheVersion=1&api=v2&width=760&height=373)
Discover the files using File Catalog tab
![image-20240329-084559.png](https://flexagon.atlassian.net/wiki/download/thumbnails/10926708845/image-20240329-084559.png?version=1&modificationDate=1724704129976&cacheVersion=1&api=v2&width=760&height=232)
Now we can create Package upon selecting specific ARM template that to be deployed to the Target Synapse Workspace.
![image-20240329-084706.png](https://flexagon.atlassian.net/wiki/download/thumbnails/10926708845/image-20240329-084706.png?version=1&modificationDate=1724704129448&cacheVersion=1&api=v2&width=760&height=172)
Click on the Configuration tab, select General and update the Build and Deploy workflows with respective Target groups.
![image-20240329-084832.png](https://flexagon.atlassian.net/wiki/download/thumbnails/10926708845/image-20240329-084832.png?version=1&modificationDate=1724704129028&cacheVersion=1&api=v2&width=760&height=339)
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:
![image-20240329-085232.png](https://flexagon.atlassian.net/wiki/download/thumbnails/10926708845/image-20240329-085232.png?version=1&modificationDate=1724704128639&cacheVersion=1&api=v2&width=610&height=186)
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:
![image-20240329-085423.png](https://flexagon.atlassian.net/wiki/download/thumbnails/10926708845/image-20240329-085423.png?version=1&modificationDate=1724704128188&cacheVersion=1&api=v2&width=760&height=534)
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:
![image-20240329-093725.png](https://flexagon.atlassian.net/wiki/download/thumbnails/10926708845/image-20240329-093725.png?version=1&modificationDate=1724704127697&cacheVersion=1&api=v2&width=465&height=546)
![image-20240329-094447.png](https://flexagon.atlassian.net/wiki/download/thumbnails/10926708845/image-20240329-094447.png?version=1&modificationDate=1724704127284&cacheVersion=1&api=v2&width=760&height=307)
The parameter file in ARM template folder looks like:
![image-20240329-094817.png](https://flexagon.atlassian.net/wiki/download/thumbnails/10926708845/image-20240329-094817.png?version=1&modificationDate=1724704126871&cacheVersion=1&api=v2&width=760&height=436)
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”.
![image-20240329-095111.png](https://flexagon.atlassian.net/wiki/download/thumbnails/10926708845/image-20240329-095111.png?version=1&modificationDate=1724704126462&cacheVersion=1&api=v2&width=760&height=224)
To verify, clicked on the Artifacts tab and verified the ARM template.
![image-20240329-095203.png](https://flexagon.atlassian.net/wiki/download/thumbnails/10926708845/image-20240329-095203.png?version=1&modificationDate=1724704125816&cacheVersion=1&api=v2&width=760&height=587)
Click on Deploy for the same
![image-20240329-095039.png](https://flexagon.atlassian.net/wiki/download/thumbnails/10926708845/image-20240329-095039.png?version=1&modificationDate=1724704125096&cacheVersion=1&api=v2&width=760&height=336)
Post deployment if we verify the Linked Service in UAT workspace, we see the updated values in there: