ARM Template の書き方 その7 SQL Database①

  • Audit
  • SQLServer
  • AzureDataBase
  • StorageAccount
  • AzureResourceManager
  • 以前にやったこと

    過去に Terraform を使って Azure SQL Database を構築するという記事「Terraform で Azure SQL Server」を書きました。その際は、Vritualnetwork のサブネットにサービスエンドポイント "Microsoft.Sql" を設定して接続する方法を紹介しました。

    やりたいこと

    構成

    今回は Firewall の設定により VirtualMachine から直接アクセス許可するシンプルな構成で、ARM Template を作成します。また、監査ログをストレージアカウントに保存するように設定します。

    arm-template-sqldatabase-1-01

    参考にしたもの

    私は普段、最初にやりたいことと近いクイックテンプレートを探して、その内容を自分なりにカスタマイズして使うようにしています。今回は、以下のクイックテンプレートを参考としました。

    やってみた

    実際に書いたテンプレートを掲載します。解説はその後に書きたいと思います。

    "Microsoft.Sql/servers"

    {
      "name": "[variables('sqlServers').sqlServer01.name]",
      "type": "Microsoft.Sql/servers",
      "apiVersion": "2019-06-01-preview",
      "location": "[variables('location')]",
      "tags": "[variables('tags')]",
      "properties": {
        "administratorLogin": "[variables('sqlServers').sqlServer01.administratorLogin]",
        "administratorLoginPassword": "[parameters('adminPassword')]",
        "version": "12.0",
        "minimalTlsVersion": "1.2",
        "publicNetworkAccess": "Enabled"
      },
      "resources": [
        {
          // https://docs.microsoft.com/ja-jp/azure/templates/microsoft.sql/servers/auditingsettings
          "name": "[concat(variables('sqlServers').sqlServer01.name,'/auditingSettings')]",
          "type": "Microsoft.Sql/servers/auditingSettings",
          "apiVersion": "2017-03-01-preview",
          "properties": {
            "state": "Enabled",
            "storageEndpoint": "[reference(variables('resourceID').storage01, '2019-06-01').primaryEndpoints['blob']]",
            "storageAccountAccessKey": "[listKeys(variables('resourceID').storage01,'2019-06-01').keys[0].value]",
            "retentionDays": 30,
            "auditActionsAndGroups": [
              "BATCH_COMPLETED_GROUP",
              "SUCCESSFUL_DATABASE_AUTHENTICATION_GROUP",
              "FAILED_DATABASE_AUTHENTICATION_GROUP",
              "APPLICATION_ROLE_CHANGE_PASSWORD_GROUP",
              "BACKUP_RESTORE_GROUP",
              "DATABASE_LOGOUT_GROUP",
              "DATABASE_OBJECT_CHANGE_GROUP",
              "DATABASE_OBJECT_OWNERSHIP_CHANGE_GROUP",
              "DATABASE_OBJECT_PERMISSION_CHANGE_GROUP",
              "DATABASE_OPERATION_GROUP",
              "DATABASE_PERMISSION_CHANGE_GROUP",
              "DATABASE_PRINCIPAL_CHANGE_GROUP",
              "DATABASE_PRINCIPAL_IMPERSONATION_GROUP",
              "DATABASE_ROLE_MEMBER_CHANGE_GROUP",
              "FAILED_DATABASE_AUTHENTICATION_GROUP",
              "SCHEMA_OBJECT_ACCESS_GROUP",
              "SCHEMA_OBJECT_CHANGE_GROUP",
              "SCHEMA_OBJECT_OWNERSHIP_CHANGE_GROUP",
              "SCHEMA_OBJECT_PERMISSION_CHANGE_GROUP",
              "SUCCESSFUL_DATABASE_AUTHENTICATION_GROUP",
              "USER_CHANGE_PASSWORD_GROUP",
              "BATCH_STARTED_GROUP",
              "BATCH_COMPLETED_GROUP"
            ],
            "isStorageSecondaryKeyInUse": false,
            "isAzureMonitorTargetEnabled": false
          },
          "dependsOn": [
            "[variables('resourceID').sqlsv01]"
          ]
        },
        {
          // Allow pubip01
          "name": "[concat(variables('sqlServers').sqlServer01.name,'/rule01')]",
          "type": "Microsoft.Sql/servers/firewallRules",
          "apiVersion": "2015-05-01-preview",
          "properties": {
            "startIpAddress": "[reference(variables('resourceID').pubip01,'2020-05-01').ipAddress]",
            "endIpAddress": "[reference(variables('resourceID').pubip01,'2020-05-01').ipAddress]"
          },
          "dependsOn": [
            "[variables('resourceID').sqlsv01]"
          ]
        },
        {
          "name": "[concat(variables('sqlServers').sqlServer01.name,'/',variables('sqlDatabases').sqlDatabase01.name)]",
          "type": "Microsoft.Sql/servers/databases",
          "apiVersion": "2020-08-01-preview",
          "location": "[variables('location')]",
          "tags": "[variables('tags')]",
          "sku": {
            // Get-AzSqlServerServiceObjective -Location eastus | Out-File sku.txt
            "name": "Standard",
            "tier": "Standard",
            "capacity": 20
          },
          "properties": {
            "collation": "SQL_Latin1_General_CP1_CI_AS",
            "sampleName": "AdventureWorksLT",
            "requestedServiceObjectiveName": "S1"
          },
          "dependsOn": [
            "[variables('resourceID').sqlsv01]"
          ]
        }
      ]
    }

    "version": "12.0"

    とりあえず、クイックテンプレートにそう書いてあったので、そのまま継承しています。公式ドキュメントを探してみたのですが、 SQL Database のバージョン情報についてはよく分かりませんでした。

    "publicNetworkAccess": "Enabled"

    プライベートエンドポイントでの接続を行う場合以外は "Enabled" です。

    "Microsoft.Sql/servers/auditingSettings"

    監査設定を行う部分です。ストレージアカウントのエンドポイントとプライマリキーを指定するのは必須です。

    監査アクションは自由に設定できます。上記のテンプレートでは全操作を監査するための設定です。ログ量が多すぎる場合は、不要な監査アクションは減らした方が良いでしょう。

    設定がうまくいくとコンソールでは以下のように表示されます。

    arm-template-sqldatabase-1-03

    全ての子リソースで共通ですが、"dependsOn" でサーバーを指定するのを忘れると依存関係のエラーが発生しますので注意してください。

    "Microsoft.Sql/servers/firewallRules"

    SQL Server に接続可能な IP Address を指定します。ここで指定した IP Address 以外からはアクセスできません。上記のテンプレートでは、Virtual Machine に付与されているパブリック IP Address を参照しています。

    Azure 内のサービスからのアクセスを全て許可する設定も可能です。その場合は、以下のように指定してください。

    {
      // Allow Azure services and resources to access this server
      "name": "[concat(variables('sqlServers').sqlServer01.name,'/rule00')]",
      "type": "Microsoft.Sql/servers/firewallRules",
      "apiVersion": "2015-05-01-preview",
      "properties": {
        "startIpAddress": "0.0.0.0",
        "endIpAddress": "0.0.0.0"
      },
      "dependsOn": [
        "[variables('resourceID').sqlsv01]"
      ]
    }

    このように "0.0.0.0" を指定すると良いです。

    "Microsoft.Sql/servers/databases"

    インスタンスタイプを確認する場合は以下のコマンドを実行してください。

    PS /Users/atsushi/github> Get-AzSqlServerServiceObjective -Location eastus

    インスタンスタイプの選択に迷う場合は過去に SQL Database の概要についての解説記事「Azure SQL Database のサービス概要」を書いておりますので、よかったらご参考にしてください。

    "sampleName": "AdventureWorksLT"

    用意されたテストデータを投入することができます。SQL の確認をする場合などには便利ですね。テストデータとして投入されたテーブルのER図を以下に掲載します。

    arm-template-sqldatabase-1-02

    用意されているテストデータは以下の3種類あります。

    • AdventureWorksLT
    • WideWorldImportersStd
    • WideWorldImportersFull(Premium限定)

    ここについての説明は少ないですが、詳細はこちらをご確認ください。

    最後に

    私の専門領域はデータベースなのですが、データベースを触るためにはデータベースが使える環境を自分で用意できなければ話になりません。Azure では ARM Template を使って自由に検証用の環境を作れるようにしておきたいですね。再利用や社内への情報共有もやりやすいですし。

    ただ、全種類のデータベースに対して ARM template を用意するにはまだまだ時間が掛かりそうです。

    ぼちぼち、マイペースでやっていきたいと思います。

  • Audit
  • SQLServer
  • AzureDataBase
  • StorageAccount
  • AzureResourceManager