Blog Post

Azure Synapse Analytics Blog
2 MIN READ

How to securely manage load credentials with SSDT, Azure Key Vault, and Azure DevOps

kevin_ngo's avatar
kevin_ngo
Former Employee
Apr 06, 2020

We released the simple and flexible COPY statement in preview to help data engineers onboard and build their data pipelines. The COPY statement requires users to specify credentials for authentication against external storage accounts where these credentials typically differ across database environments such as development, testing, and production. Building and deploying data pipelines securely with COPY credentials using a stable continuous integration and deployment (CI/CD) process has never been easier with the integration of Visual Studio SQL Server Data Tools (SSDT), Azure DevOps and Azure Key Vault.

 

This blog outlines how to build a basic stored procedure with the COPY statement in SSDT and deploy the stored procedure in a CI/CD pipeline without storing any credentials within your database project.

 

1. Set up your CI/CD pipeline with SSDT and add a Stored Procedure containing your COPY statement:

 

 

 

In this example, the stored procedure uses dynamic SQL to retrieve and load the time of ingestion in a table column.  The current session user is also specified in the COPY LABEL hint for monitoring purposes. Sqlcmd variables are used to avoid storing credentials in plain text in the stored procedure definition within SSDT.

 

2. Add a task in your Azure DevOps pipeline to extract secrets from Azure Key Vault as pipeline variables. These pipeline variables can be used as sqlcmd variables in the deployment task.

 

 

 

 

 

In this example, the pipeline pulls the $(DataLakeSecret) secret from Azure Key Vault and passes the secret to the DataLakeSecret sqlcmd variable for the deployment – this is the SAS token within your COPY statement.

 

For each successful check-in, COPY credentials in your stored procedure will now be dynamically applied and updated securely from Azure Key Vault based on the target environment within your CI/CD pipeline.

 

The flexibility of using SSDT, Azure DevOps, and Azure Key vault enables you to extend this process to:

  • Storage locations paths if you load from different accounts in each of your environments
  • External table details such as your Master key, Database scoped credential, and External data source
  • Database connection string details (usename, password, etc) and avoid having them in plain text within your Azure DevOps pipeline
  • Database users and logins set up via SSDT pre-deployment scripts where passwords are stored in Azure Key vault for different database environments

 

Updated Apr 21, 2020
Version 7.0

2 Comments

  • First of all, Thank you for your article.
    Second of all, I did almost as same as you have mentioned in above. My pipeline creates my 'DATABASE SCOPED CREDENTIAL' for the first time but for second times, when my pipeline runs, I have this error : 

     

    ##[error]*** Could not deploy package.
    ##[error]Warning SQL72013: The following SqlCmd variables are not defined in the target scripts: DatabaseScopeCredentialSecret DatabaseScopeCredentialIdentity ExternalDataSourceMarineTrafficLocation.
     
    I have these files in my SSDT.
     
    ADLSCredential.sql : 
     

    CREATE MASTER KEY;
    GO

    CREATE DATABASE SCOPED CREDENTIAL ADLSCredential
    WITH
    IDENTITY = '$(DatabaseScopeCredentialIdentity)',
    SECRET = '$(DatabaseScopeCredentialSecret)'
    ;

     

    AzureDataLakeStoreMarineTraffic.sql : 

     

    CREATE EXTERNAL DATA SOURCE AzureDataLakeStoreMarineTraffic
    WITH (
    TYPE = HADOOP,
    LOCATION='$(ExternalDataSourceMarineTrafficLocation)',
    CREDENTIAL = ADLSCredential
    );

     

    As you can see i am using three variables. I have created these variables in my Azure key Vault and I have configured every things related to my Azure Key Vault. When I don't have these objects in my DW, My pipeline creates them perfectly but for next run, I have this error : 

     

    This is part of my YAML file:

     

     

    taskSqlAzureDataWarehouseDacpacDeployment@1
      inputs:
        azureSubscription'<My Subscription>'
        AuthenticationType'server'
        ServerName'<MyServer Name>.database.windows.net'
        DataWarehouse'$(SynapseName)'
        SqlUsername'$(SynapseSQLUsername)'
        SqlPassword'$(SynapseSQLPassword)'
        deployType'DacpacTask'
        DeploymentAction'Publish'
        DacpacFile'SQL_ASynapse\bin\Release\SQL_ASynapse.dacpac'
        AdditionalArguments'/p:IgnoreAnsiNulls=True /p:IgnoreComments=True /v:DatabaseScopeCredentialSecret=$(DatabaseScopeCredentialSecret) /v:DatabaseScopeCredentialIdentity=$(DatabaseScopeCredentialIdentity) /v:ExternalDataSourceMarineTrafficLocation=$(ExternalDataSourceMarineTrafficLocation)'
        IpDetectionMethod'AutoDetect'

     

    Could you please tell me What should I have done?