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

Published Apr 06 2020 10:49 AM 2,535 Views
Microsoft

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:

 

KeyVault_1.png

 

 

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.

 

KeyVault_2.png

 

 

KeyVault_3.png

 

KeyVault_4.png

 

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

 

2 Comments
%3CLINGO-SUB%20id%3D%22lingo-sub-1279971%22%20slang%3D%22en-US%22%3EHow%20to%20securely%20manage%20load%20credentials%20with%20SSDT%2C%20Azure%20Key%20Vault%2C%20and%20Azure%20DevOps%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1279971%22%20slang%3D%22en-US%22%3E%3CP%3EWe%20released%20the%20simple%20and%20flexible%20%3CA%20href%3D%22https%3A%2F%2Fdocs.microsoft.com%2Fsql%2Ft-sql%2Fstatements%2Fcopy-into-transact-sql%3Fview%3Dazure-sqldw-latest%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%22%3ECOPY%20statement%3C%2FA%3E%20in%20preview%20to%20help%20data%20engineers%20onboard%20and%20build%20their%20data%20pipelines.%20The%20COPY%20statement%20requires%20users%20to%20specify%20credentials%20for%20authentication%20against%20external%20storage%20accounts%20where%20these%20credentials%20typically%20differ%20across%20database%20environments%20such%20as%20development%2C%20testing%2C%20and%20production.%20Building%20and%20deploying%20data%20pipelines%20securely%20with%20COPY%20credentials%20using%20a%20stable%20continuous%20integration%20and%20deployment%20(CI%2FCD)%20process%20has%20never%20been%20easier%20with%20the%20integration%20of%20Visual%20Studio%20SQL%20Server%20Data%20Tools%20(SSDT)%2C%20Azure%20DevOps%20and%20Azure%20Key%20Vault.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EThis%20blog%20outlines%20how%20to%20build%20a%20basic%20stored%20procedure%20with%20the%20COPY%20statement%20in%20SSDT%20and%20deploy%20the%20stored%20procedure%20in%20a%20CI%2FCD%20pipeline%20without%20storing%20any%20credentials%20within%20your%20database%20project.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E1.%20Set%20up%20your%20%3CA%20href%3D%22https%3A%2F%2Fdocs.microsoft.com%2Fazure%2Fsynapse-analytics%2Fsql-data-warehouse%2Fsql-data-warehouse-continuous-integration-and-deployment%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%22%3ECI%2FCD%20pipeline%20with%20SSDT%3C%2FA%3E%20and%20add%20a%20Stored%20Procedure%20containing%20your%20COPY%20statement%3A%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-center%22%20image-alt%3D%22KeyVault_1.png%22%20style%3D%22width%3A%20999px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Fgxcuf89792.i.lithium.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F182032i9F3885CC9B2E2BA8%2Fimage-size%2Flarge%3Fv%3D1.0%26amp%3Bpx%3D999%22%20title%3D%22KeyVault_1.png%22%20alt%3D%22KeyVault_1.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EIn%20this%20example%2C%20the%20stored%20procedure%20uses%20dynamic%20SQL%20to%20retrieve%20and%20load%20the%20time%20of%20ingestion%20in%20a%20table%20column.%20%26nbsp%3BThe%20current%20session%20user%20is%20also%20specified%20in%20the%20COPY%20LABEL%20hint%20for%20monitoring%20purposes.%20Sqlcmd%20variables%20are%20used%20to%20avoid%20storing%20credentials%20in%20plain%20text%20in%20the%20stored%20procedure%20definition%20within%20SSDT.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E2.%20Add%20a%20task%20in%20your%20Azure%20DevOps%20pipeline%20to%20%3CA%20href%3D%22https%3A%2F%2Fdocs.microsoft.com%2Fazure%2Fdevops%2Fpipelines%2Ftasks%2Fdeploy%2Fazure-key-vault%3Fview%3Dazure-devops%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%22%3Eextract%20secrets%20from%20Azure%20Key%20Vault%3C%2FA%3E%20as%20pipeline%20variables.%20These%20pipeline%20variables%20can%20be%20used%20as%20sqlcmd%20variables%20in%20the%20deployment%20task.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22KeyVault_2.png%22%20style%3D%22width%3A%20999px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Fgxcuf89792.i.lithium.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F182033iE29372D3D36267B4%2Fimage-size%2Flarge%3Fv%3D1.0%26amp%3Bpx%3D999%22%20title%3D%22KeyVault_2.png%22%20alt%3D%22KeyVault_2.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-center%22%20image-alt%3D%22KeyVault_3.png%22%20style%3D%22width%3A%20931px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Fgxcuf89792.i.lithium.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F182034i538807203676A9E2%2Fimage-size%2Flarge%3Fv%3D1.0%26amp%3Bpx%3D999%22%20title%3D%22KeyVault_3.png%22%20alt%3D%22KeyVault_3.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-center%22%20image-alt%3D%22KeyVault_4.png%22%20style%3D%22width%3A%20896px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Fgxcuf89792.i.lithium.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F182035i7C481AEBE0EF8645%2Fimage-size%2Flarge%3Fv%3D1.0%26amp%3Bpx%3D999%22%20title%3D%22KeyVault_4.png%22%20alt%3D%22KeyVault_4.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EIn%20this%20example%2C%20the%20pipeline%20pulls%20the%20%24(DataLakeSecret)%20secret%20from%20Azure%20Key%20Vault%20and%20passes%20the%20secret%20to%20the%20DataLakeSecret%20sqlcmd%20variable%20for%20the%20deployment%20%E2%80%93%20this%20is%20the%20SAS%20token%20within%20your%20COPY%20statement.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EFor%20each%20successful%20check-in%2C%20COPY%20credentials%20in%20your%20stored%20procedure%20will%20now%20be%20dynamically%20applied%20and%20updated%20securely%20from%20Azure%20Key%20Vault%20based%20on%20the%20target%20environment%20within%20your%20CI%2FCD%20pipeline.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EThe%20flexibility%20of%20using%20SSDT%2C%20Azure%20DevOps%2C%20and%20Azure%20Key%20vault%20enables%20you%20to%20extend%20this%20process%20to%3A%3C%2FP%3E%0A%3CUL%3E%0A%3CLI%3EStorage%20locations%20paths%20if%20you%20load%20from%20different%20accounts%20in%20each%20of%20your%20environments%3C%2FLI%3E%0A%3CLI%3EExternal%20table%20details%20such%20as%20your%20Master%20key%2C%20Database%20scoped%20credential%2C%20and%20External%20data%20source%3C%2FLI%3E%0A%3CLI%3EDatabase%20connection%20string%20details%20(usename%2C%20password%2C%20etc)%20and%20avoid%20having%20them%20in%20plain%20text%20within%20your%20Azure%20DevOps%20pipeline%3C%2FLI%3E%0A%3CLI%3EDatabase%20users%20and%20logins%20set%20up%20via%20SSDT%20pre-deployment%20scripts%20where%20passwords%20are%20stored%20in%20Azure%20Key%20vault%20for%20different%20database%20environments%3C%2FLI%3E%0A%3C%2FUL%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-LABS%20id%3D%22lingo-labs-1279971%22%20slang%3D%22en-US%22%3E%3CLINGO-LABEL%3ESynapse%20Data%20pipelines%3C%2FLINGO-LABEL%3E%3CLINGO-LABEL%3ESynapse%20DevOps%3C%2FLINGO-LABEL%3E%3CLINGO-LABEL%3ESynapse%20SQL%3C%2FLINGO-LABEL%3E%3C%2FLINGO-LABS%3E
Version history
Last update:
‎Apr 21 2020 08:05 AM
Updated by: