システム構成
概要
開発用と本番用のSynapse、DevOpsServerをインストールするためのLinuxVM、Azure DevOpsのRepoとパイプラインを準備します。
まず開発環境で変更が生じて修正した後、Synapseの発行機能でリソース全てをjson形式でRepoに出力します。そしてパイプラインを実行し、内部でテストを行い本番環境に自動的に反映させます。
構築
Azure DevOps設定 リポジトリ設定①
事前にReposにリポジトリの作成を行います。
リポジトリを作成すると自動的にmainブランチも作成されます。
Azure DevOps サービスプリンシパル設定②
Azure DevOpsから本番環境のSynapseにアクセス出来るように権限設定を行います。
後々リリースパイプラインの実行権限、本番環境のSynapseのアクセス権限設定時に使用します。
一番左下の「Project settings」から「Service connections」、「Create service connection」を選択します。
「Azure Resource Manager」を選択。
「Service principal(automatic)」を選択。
これで作成完了です。
Synapseのデプロイ
今回画面操作で構築すると時間が掛かるのでBicepでデプロイを行います。
以下に解説の記事を書いています。
synapseのARMはMicrosoftが公開しているものがあるので、Bicepにデコンパイルします。
以下デコンパイルして修正したものになります。
必要に応じてリソース名を変更します。
ローカル環境でbicepファイルを作成し内容をコピーします。
//開発環境ストレージ名
var storageAccounts_dev = 'developtesta1'
//開発環境Synapse名
var workspaces_dev = 'developtestb1'
//本番環境ストレージ名
var storageAccounts_pro = 'productiontesta1'
//本番環境Synapse名
var workspaces_pro = 'productiontestb1'
var location = 'japaneast'
//開発用環境
resource storageAccounts_name_resource_dev 'Microsoft.Storage/storageAccounts@2021-09-01' = {
name: storageAccounts_dev
location: location
sku: {
name: 'Standard_RAGRS'
}
kind: 'StorageV2'
properties: {
minimumTlsVersion: 'TLS1_2'
allowBlobPublicAccess: true
isHnsEnabled: true
networkAcls: {
bypass: 'AzureServices'
virtualNetworkRules: []
ipRules: []
defaultAction: 'Allow'
}
supportsHttpsTrafficOnly: true
encryption: {
services: {
file: {
keyType: 'Account'
enabled: true
}
blob: {
keyType: 'Account'
enabled: true
}
}
keySource: 'Microsoft.Storage'
}
accessTier: 'Hot'
}
}
resource storageAccounts_name_default_dev 'Microsoft.Storage/storageAccounts/blobServices@2021-09-01' = {
parent: storageAccounts_name_resource_dev
name: 'default'
properties: {
deleteRetentionPolicy: {
allowPermanentDelete: false
enabled: false
}
}
}
resource storageAccounts_zealls_name_default_zealfs_dev 'Microsoft.Storage/storageAccounts/blobServices/containers@2021-09-01' = {
parent: storageAccounts_name_default_dev
name: 'datafs'
}
resource workspaces_name_resource_dev 'Microsoft.Synapse/workspaces@2021-06-01' = {
name: workspaces_dev
location: location
identity: {
type: 'SystemAssigned'
}
properties: {
defaultDataLakeStorage: {
resourceId: storageAccounts_name_resource_dev.id
createManagedPrivateEndpoint: true
accountUrl: 'https://${workspaces_dev}ls.dfs.core.windows.net'
filesystem: '${workspaces_dev}fs'
}
encryption: {
}
managedVirtualNetwork: 'default'
privateEndpointConnections: []
managedVirtualNetworkSettings: {
preventDataExfiltration: false
allowedAadTenantIdsForLinking: []
}
publicNetworkAccess: 'Enabled'
azureADOnlyAuthentication: false
trustedServiceBypassEnabled: true
}
}
resource workspaces_zeal_name_Default_dev 'Microsoft.Synapse/workspaces/auditingSettings@2021-06-01' = {
parent: workspaces_name_resource_dev
name: 'Default'
properties: {
retentionDays: 0
auditActionsAndGroups: []
isStorageSecondaryKeyInUse: false
isAzureMonitorTargetEnabled: false
state: 'Disabled'
storageAccountSubscriptionId: '00000000-0000-0000-0000-000000000000'
}
}
resource Microsoft_Synapse_workspaces_azureADOnlyAuthentications_workspaces_name_default_dev 'Microsoft.Synapse/workspaces/azureADOnlyAuthentications@2021-06-01' = {
parent: workspaces_name_resource_dev
name: 'default'
properties: {
azureADOnlyAuthentication: false
}
}
resource Microsoft_Synapse_workspaces_dedicatedSQLminimalTlsSettings_workspaces_name_default_dev 'Microsoft.Synapse/workspaces/dedicatedSQLminimalTlsSettings@2021-06-01' = {
parent: workspaces_name_resource_dev
name: 'default'
properties: {
minimalTlsVersion: '1.2'
}
}
resource Microsoft_Synapse_workspaces_extendedAuditingSettings_workspaces_name_Default_dev 'Microsoft.Synapse/workspaces/extendedAuditingSettings@2021-06-01' = {
parent: workspaces_name_resource_dev
name: 'Default'
properties: {
retentionDays: 0
auditActionsAndGroups: []
isStorageSecondaryKeyInUse: false
isAzureMonitorTargetEnabled: false
state: 'Disabled'
storageAccountSubscriptionId: '00000000-0000-0000-0000-000000000000'
}
}
resource workspaces_zeal_name_AutoResolveIntegrationRuntime_dev 'Microsoft.Synapse/workspaces/integrationruntimes@2021-06-01' = {
parent: workspaces_name_resource_dev
name: 'AutoResolveIntegrationRuntime'
properties: {
type: 'Managed'
typeProperties: {
computeProperties: {
location: 'AutoResolve'
}
}
}
}
resource Microsoft_Synapse_workspaces_securityAlertPolicies_workspaces_name_Default_dev 'Microsoft.Synapse/workspaces/securityAlertPolicies@2021-06-01' = {
parent: workspaces_name_resource_dev
name: 'Default'
properties: {
state: 'Disabled'
disabledAlerts: [
''
]
emailAddresses: [
''
]
emailAccountAdmins: false
retentionDays: 0
}
}
//本番用環境
resource storageAccounts_name_resource_pro 'Microsoft.Storage/storageAccounts@2021-09-01' = {
name: storageAccounts_pro
location: location
sku: {
name: 'Standard_RAGRS'
}
kind: 'StorageV2'
properties: {
minimumTlsVersion: 'TLS1_2'
allowBlobPublicAccess: true
isHnsEnabled: true
networkAcls: {
bypass: 'AzureServices'
virtualNetworkRules: []
ipRules: []
defaultAction: 'Allow'
}
supportsHttpsTrafficOnly: true
encryption: {
services: {
file: {
keyType: 'Account'
enabled: true
}
blob: {
keyType: 'Account'
enabled: true
}
}
keySource: 'Microsoft.Storage'
}
accessTier: 'Hot'
}
}
resource storageAccounts_name_default_pro 'Microsoft.Storage/storageAccounts/blobServices@2021-09-01' = {
parent: storageAccounts_name_resource_pro
name: 'default'
properties: {
deleteRetentionPolicy: {
allowPermanentDelete: false
enabled: false
}
}
}
resource storageAccounts_name_default_zealfs_pro 'Microsoft.Storage/storageAccounts/blobServices/containers@2021-09-01' = {
parent: storageAccounts_name_default_pro
name: 'datafs'
}
resource workspaces_name_resource_pro 'Microsoft.Synapse/workspaces@2021-06-01' = {
name: workspaces_pro
location: location
identity: {
type: 'SystemAssigned'
}
properties: {
defaultDataLakeStorage: {
resourceId: storageAccounts_name_resource_pro.id
createManagedPrivateEndpoint: true
accountUrl: 'https://${workspaces_pro}ls.dfs.core.windows.net'
filesystem: '${workspaces_pro}fs'
}
encryption: {
}
managedVirtualNetwork: 'default'
privateEndpointConnections: []
managedVirtualNetworkSettings: {
preventDataExfiltration: false
allowedAadTenantIdsForLinking: []
}
publicNetworkAccess: 'Enabled'
azureADOnlyAuthentication: false
trustedServiceBypassEnabled: true
}
}
resource workspaces_zeal_name_Default_pro 'Microsoft.Synapse/workspaces/auditingSettings@2021-06-01' = {
parent: workspaces_name_resource_pro
name: 'Default'
properties: {
retentionDays: 0
auditActionsAndGroups: []
isStorageSecondaryKeyInUse: false
isAzureMonitorTargetEnabled: false
state: 'Disabled'
storageAccountSubscriptionId: '00000000-0000-0000-0000-000000000000'
}
}
resource Microsoft_Synapse_workspaces_azureADOnlyAuthentications_workspaces_name_default_pro 'Microsoft.Synapse/workspaces/azureADOnlyAuthentications@2021-06-01' = {
parent: workspaces_name_resource_pro
name: 'default'
properties: {
azureADOnlyAuthentication: false
}
}
resource Microsoft_Synapse_workspaces_dedicatedSQLminimalTlsSettings_workspaces_name_default_pro 'Microsoft.Synapse/workspaces/dedicatedSQLminimalTlsSettings@2021-06-01' = {
parent: workspaces_name_resource_pro
name: 'default'
properties: {
minimalTlsVersion: '1.2'
}
}
resource Microsoft_Synapse_workspaces_extendedAuditingSettings_workspaces_name_Default_pro 'Microsoft.Synapse/workspaces/extendedAuditingSettings@2021-06-01' = {
parent: workspaces_name_resource_pro
name: 'Default'
properties: {
retentionDays: 0
auditActionsAndGroups: []
isStorageSecondaryKeyInUse: false
isAzureMonitorTargetEnabled: false
state: 'Disabled'
storageAccountSubscriptionId: '00000000-0000-0000-0000-000000000000'
}
}
resource workspaces_zeal_name_AutoResolveIntegrationRuntime_pro 'Microsoft.Synapse/workspaces/integrationruntimes@2021-06-01' = {
parent: workspaces_name_resource_pro
name: 'AutoResolveIntegrationRuntime'
properties: {
type: 'Managed'
typeProperties: {
computeProperties: {
location: 'AutoResolve'
}
}
}
}
resource Microsoft_Synapse_workspaces_securityAlertPolicies_workspaces_name_Default_pro 'Microsoft.Synapse/workspaces/securityAlertPolicies@2021-06-01' = {
parent: workspaces_name_resource_pro
name: 'Default'
properties: {
state: 'Disabled'
disabledAlerts: [
''
]
emailAddresses: [
''
]
emailAccountAdmins: false
retentionDays: 0
}
}
az login
した後に
az deployment group create --resource-group デプロイリソースグループ --template-file Synapse.bicepのファイルパス
を実行します。
Synapse リポジトリ設定
作成したAzure DevOpsのReposとSynapseを紐づける設定を行います。
まず開発環境Synapseのファイアウォールに自身のIPを追加。
開発環境のSynapseにログインし一番左の「工具箱アイコン」から「Git configuration」「構成」を選択。
以下の図を参考に値を入力していきます。
コラボレーションブランチはSynapseの各jsonリソースが格納されている場所。
発行ブランチは「workspace_publish」固定になります。
こちらで設定完了です。
リポジトリのブランチと紐づけることで、現在のSynapseのリソースがそれぞれjson形式で保存されるようになります。
試しにtestを出力するNotebookを新規に作成します。
そして「すべてコミット」を選択します。
これで新規に作成したNotebookが開発環境に紐づくリポジトリ内に保存されていることが分かります。
次にSynapseの各リソースを二つのjsonファイルに出力を行います。
「発行」を選択します。
発行完了後は「workspace_publish」というブランチが自動的に作成され、Synapseのリソースとパラメータが記載されたjsonファイルが保存されます。
Azure DevOps Artifacts設定
左欄から「Pipeline」「Release」を選択してリリースパイプラインの新規作成を行います。
「Add」を選択。
開発環境のSynapseから発行されたブランチを指定。
これでArtifactsの設定は完了です。
Azure DevOps Stage内のタスク設定
「1job, 0 task」の部分を選択。
「+」を選択し、検索欄に「Synapse」を入力。
「Synapse workspace deployment」の「Add」を選択。
下記のようにタスクが追加されるので下記のパラメータを入力していきます。
Template
synリポジトリのworkspace_bulishブランチ内のTemplateForWorkspace.jsonを選択。
Template paramaters
synリポジトリのworkspace_bulishブランチ内のTemplateParametersForWorkspace.jsonを選択。
Synapse workspace connection type
先程作成したサービスコネクションを選択。
Synapse workspace resource group
Synapse本番環境が配置されているリソースグループを選択。
Synapse workspace name
Synapse本番環境のワークスペース名を入力。
AzureDevOpsサーバー インストール
DevOpsの実行環境になる仮想VMを構築します。
またVMのパブリックIPアドレスが固定になるため、本番環境Synapseのファイアウォールも設定できるようになります。
「作成」、「Azure 仮想マシン」を選択。
リソースグループと仮想マシン名を入力し、他はデフォルトの値で作成。
「作成」を選択し、「秘密キーのダウンロードとリソースの作成」をクリック。
デプロイ完了後、最左欄にある「接続」をクリック。
ネイティブSSHの「選択」をクリックし「構成」を選択。
下図のコマンドをPowerShellで実行。
ssh -i 暗号鍵ファイルのパス azureuser@パブリックIP
実行するとLinuxにアクセス出来ます。
ここからAzureDevOpsに戻り「Project Settings」から「Agent pools」、「Add pool」を選択。
上のタブをLinuxにし、Download the agent の下にあるURLをコピーするボタンをクリック。
下記コマンドをLinuxで実行し、設定ファイルのダウンロードを行います。
wget コピーしたURL
次に
tar zxvf ダウンロードしたファイル名
を実行して圧縮ファイルを解凍します。
解凍後は以下のファイルが配置されます。
コマンド./config.sh
を実行し、以下のURLを参考にAzureDevOps側のPATを設定して値を入力していきます。
コマンド./run.sh
を実行しAzure DevOpsサーバーを起動します。
起動できるとAzure DevOpsの画面でエージェントが実行されていることを確認出来ます。
本番環境Synapse 権限設定
Linuxの仮想VMのパブリックIPを確認します。
確認後、自身のIPとパブリックIPをファイアウォールに設定を行います。
本番環境のSynapseにログインし一番左の「工具箱アイコン」から「Acess control」を選択。
ここで先程作成したサービスプリンシパルの表示名を確認します。
「Manage Service Principal」を選択。
下記のように表示名が出るので、コピーしてSynapse権限追加時の検索欄に貼り付けて追加します。
AzureDevOps リリースパイプライン実行
本番環境でNotebookが何も作成されていないことを確認します。
Azure DevOpsの右上の「Create release」を選択します。
「Create」を選択します。
実行ログ内でNotebookがデプロイされていることが確認出来ます。
この部分でリソースに不正がないか自動でチェックされ、不整合など発見されるとエラーが発生します。
実行が完了しました。
本番環境Synapseを確認すると開発環境と同じNotebookが自動的に反映されてることが確認出来ます。
こちらで内容は以上となります。
見て下さりありがとうございました。