LoginSignup
2
0

Azure SynapseのCI/CD化をやってみた

Last updated at Posted at 2024-01-09

システム構成

image.png

概要

開発用と本番用のSynapse、DevOpsServerをインストールするためのLinuxVM、Azure DevOpsのRepoとパイプラインを準備します。

まず開発環境で変更が生じて修正した後、Synapseの発行機能でリソース全てをjson形式でRepoに出力します。そしてパイプラインを実行し、内部でテストを行い本番環境に自動的に反映させます。

構築

Azure DevOps設定 リポジトリ設定①

事前にReposにリポジトリの作成を行います。
リポジトリを作成すると自動的にmainブランチも作成されます。

スクリーンショット 2023-03-04 164004.jpg

image.png

スクリーンショット 2023-03-04 164237.jpg

Azure DevOps サービスプリンシパル設定②

Azure DevOpsから本番環境のSynapseにアクセス出来るように権限設定を行います。
後々リリースパイプラインの実行権限、本番環境のSynapseのアクセス権限設定時に使用します。

一番左下の「Project settings」から「Service connections」、「Create service connection」を選択します。

スクリーンショット 2023-03-04 173216.jpg

「Azure Resource Manager」を選択。

スクリーンショット 2023-03-04 173242.jpg

「Service principal(automatic)」を選択。

スクリーンショット 2023-03-04 173259.jpg

自身のサブスクリプションを選択。
スクリーンショット 2023-03-04 173332.jpg

これで作成完了です。

スクリーンショット 2023-03-04 173416.jpg

スクリーンショット 2023-03-04 173429.jpg

Synapseのデプロイ

今回画面操作で構築すると時間が掛かるのでBicepでデプロイを行います。
以下に解説の記事を書いています。

synapseのARMはMicrosoftが公開しているものがあるので、Bicepにデコンパイルします。

以下デコンパイルして修正したものになります。
必要に応じてリソース名を変更します。
ローカル環境でbicepファイルを作成し内容をコピーします。

Synapse.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のファイルパス

を実行します。

リソースの展開を確認。
image.png

Synapse リポジトリ設定

作成したAzure DevOpsのReposとSynapseを紐づける設定を行います。
まず開発環境Synapseのファイアウォールに自身のIPを追加。

image.png

開発環境のSynapseにログインし一番左の「工具箱アイコン」から「Git configuration」「構成」を選択。

スクリーンショット 2023-03-04 164416.jpg

スクリーンショット 2023-03-04 164523.jpg

image.png

スクリーンショット 2023-03-04 164754.jpg

以下の図を参考に値を入力していきます。
コラボレーションブランチはSynapseの各jsonリソースが格納されている場所。
発行ブランチは「workspace_publish」固定になります。

image.png

スクリーンショット 2023-03-04 172450.jpg

こちらで設定完了です。

image.png

リポジトリのブランチと紐づけることで、現在のSynapseのリソースがそれぞれjson形式で保存されるようになります。

image.png

試しにtestを出力するNotebookを新規に作成します。
そして「すべてコミット」を選択します。

スクリーンショット 2023-03-04 172637.jpg

スクリーンショット 2023-03-04 172705.jpg

スクリーンショット 2023-03-04 172722.jpg

スクリーンショット 2023-03-04 172802.jpg

これで新規に作成したNotebookが開発環境に紐づくリポジトリ内に保存されていることが分かります。

image.png

次にSynapseの各リソースを二つのjsonファイルに出力を行います。
「発行」を選択します。
スクリーンショット 2023-03-04 172637.jpg

発行完了後は「workspace_publish」というブランチが自動的に作成され、Synapseのリソースとパラメータが記載されたjsonファイルが保存されます。

スクリーンショット 2023-03-04 172833.jpg

Azure DevOps Artifacts設定

左欄から「Pipeline」「Release」を選択してリリースパイプラインの新規作成を行います。
「Add」を選択。

image.png

開発環境のSynapseから発行されたブランチを指定。

スクリーンショット 2023-03-04 172935.jpg

これでArtifactsの設定は完了です。

image.png

Azure DevOps Stage内のタスク設定

「1job, 0 task」の部分を選択。

image.png

「+」を選択し、検索欄に「Synapse」を入力。
「Synapse workspace deployment」の「Add」を選択。

スクリーンショット 2023-03-04 173023.jpg

下記のようにタスクが追加されるので下記のパラメータを入力していきます。

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本番環境のワークスペース名を入力。

スクリーンショット 2023-03-04 173057.jpg

スクリーンショット 2023-03-04 173124.jpg

image.png

image.png

AzureDevOpsサーバー インストール

DevOpsの実行環境になる仮想VMを構築します。
またVMのパブリックIPアドレスが固定になるため、本番環境Synapseのファイアウォールも設定できるようになります。

ホームから「Virtual Machines」を選択。
image.png

「作成」、「Azure 仮想マシン」を選択。

image.png

image.png

リソースグループと仮想マシン名を入力し、他はデフォルトの値で作成。

image.png

image.png

「作成」を選択し、「秘密キーのダウンロードとリソースの作成」をクリック。

image.png

image.png

image.png

デプロイ完了後、最左欄にある「接続」をクリック。
ネイティブSSHの「選択」をクリックし「構成」を選択。

image.png

下図のコマンドをPowerShellで実行。
ssh -i 暗号鍵ファイルのパス azureuser@パブリックIP

image.png

実行するとLinuxにアクセス出来ます。

image.png

ここからAzureDevOpsに戻り「Project Settings」から「Agent pools」、「Add pool」を選択。

image.png

上のタブをLinuxにし、Download the agent の下にあるURLをコピーするボタンをクリック。

image.png

下記コマンドをLinuxで実行し、設定ファイルのダウンロードを行います。
wget コピーしたURL

image.png

次に
tar zxvf ダウンロードしたファイル名
を実行して圧縮ファイルを解凍します。

image.png

解凍後は以下のファイルが配置されます。

image.png

コマンド./config.shを実行し、以下のURLを参考にAzureDevOps側のPATを設定して値を入力していきます。

image.png

コマンド./run.shを実行しAzure DevOpsサーバーを起動します。

image.png

起動できるとAzure DevOpsの画面でエージェントが実行されていることを確認出来ます。

image.png

本番環境Synapse 権限設定

Linuxの仮想VMのパブリックIPを確認します。

image.png

確認後、自身のIPとパブリックIPをファイアウォールに設定を行います。

image.png

本番環境のSynapseにログインし一番左の「工具箱アイコン」から「Acess control」を選択。

スクリーンショット 2023-03-04 173911.jpg

ここで先程作成したサービスプリンシパルの表示名を確認します。
「Manage Service Principal」を選択。
スクリーンショット 2023-03-04 173429.jpg

下記のように表示名が出るので、コピーしてSynapse権限追加時の検索欄に貼り付けて追加します。

スクリーンショット 2023-03-04 173452.jpg

スクリーンショット 2023-03-04 174048.jpg

スクリーンショット 2023-03-04 174104.jpg

スクリーンショット 2023-03-04 174120.jpg

AzureDevOps リリースパイプライン実行

本番環境でNotebookが何も作成されていないことを確認します。

image.png

Azure DevOpsの右上の「Create release」を選択します。

image.png

「Create」を選択します。

image.png

実行ログ内でNotebookがデプロイされていることが確認出来ます。
この部分でリソースに不正がないか自動でチェックされ、不整合など発見されるとエラーが発生します。

image.png

実行が完了しました。

image.png

本番環境Synapseを確認すると開発環境と同じNotebookが自動的に反映されてることが確認出来ます。

image.png

こちらで内容は以上となります。
見て下さりありがとうございました。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0