Microdoft Azureが提供しているRDMSのマネージドサービスには、SQL Server, Oracle, PostgreSQL, MariaDBがありますが、このページではPostgreSQLの操作方法をまとめます。
データベースサーバの作成
リソースグループの作成
以下のコマンドでリソースグループを作成します。
az group create --name myResourceGroup --location japaneast
PostgreSQLデータベースの作成
AzureのPostgreSQLには「単一サーバー」と「フレキシブルサーバー」があります。両者の比較は「比較表 – Azure Database for PostgreSQL の単一サーバーとフレキシブル サーバー」を参照ください。このページでは「単一サーバー」の操作例を紹介します。
以下のコマンドで「単一サーバー」のPostgreSQLを作成します。nameはAzure内で一位な名前を指定します。mydemoserverのような他の誰かが使ってそうな名前は使用できません。
az postgres server create \ --resource-group myResourceGroup \ --name gokatei-db-01 \ --location japaneast \ --admin-user myadmin \ --admin-password P@ssw0rd \ --sku-name GP_Gen5_2
デフォルトのセキュリティ設定の確認
デフォルトのセキュリティ設定を確認して仕様理解を深めます。showコマンドを発行しJSONの定義体を眺めて良いですが、適度にGUIを併用した方が素早く状況を把握できるでしょう。
Azure Database for PostgreSQLの「接続のセキュリティ」を見ると、以下のようなデフォルト設定の挙動を理解する事ができます。
デフォルト設定は予告なしに変わる可能性もありますので、たまに確認するようにしましょう。
- パブリック ネットワークからのアクセスは許可
- しかし、接続を許可するパブリックIPアドレスが1つも定義されてないため、どこからもアクセスできない
- SSLの使用を強制する
ファイアウォールルールの定義
デフォルト設定では、接続を許可するパブリックIPアドレスが定義されていませんので、PostgreSQLへの接続を許可するパブリックIPアドレスを指定します。以下は、「103.5.140.188」からの接続を許可する設定例です。パブリックIPアドレスは環境に応じて適宜変更して下さい。
az postgres server firewall-rule create \ --resource-group myResourceGroup \ --server gokatei-db-01 \ --name AllowMyIP \ --start-ip-address 103.5.140.188 \ --end-ip-address 103.5.140.188
接続確認
psqlコマンド等を用いて接続可否を確認します。psqlコマンドに与える引数は、Azure Database for PostgreSQLの「接続文字列」を見ると、サンプル設定を見る事ができます。
クリップボードにコピーされたサンプルの接続文字列は以下の通りです。データベース名とパスワードのみ適宜変更すれば接続できます。
psql \ "host=gokatei-db-01.postgres.database.azure.com \ port=5432 \ dbname={your_database} \ user=myadmin@gokatei-db-01 \ password={your_password} \ sslmode=require"
デフォルトで作成される「postgres」データベースへ接続する操作例は以下の通りです。
admin@mac19 ~ % psql \ "host=gokatei-db-01.postgres.database.azure.com \ port=5432 \ dbname=postgres \ user=myadmin@gokatei-db-01 \ password=P@ssw0rd \ sslmode=require" psql (14.2, server 9.6.21) SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off) Type "help" for help. postgres=> \l List of databases Name | Owner | Encoding | Collate | Ctype | Access privileges -------------------+-----------------+----------+----------------------------+----------------------------+------------------------------------- azure_maintenance | azure_superuser | UTF8 | English_United States.1252 | English_United States.1252 | azure_superuser=CTc/azure_superuser azure_sys | azure_superuser | UTF8 | English_United States.1252 | English_United States.1252 | postgres | azure_superuser | UTF8 | English_United States.1252 | English_United States.1252 | template0 | azure_superuser | UTF8 | English_United States.1252 | English_United States.1252 | =c/azure_superuser + | | | | | azure_superuser=CTc/azure_superuser template1 | azure_superuser | UTF8 | English_United States.1252 | English_United States.1252 | =c/azure_superuser + | | | | | azure_superuser=CTc/azure_superuser (5 rows) postgres=>
データベースの操作
データベース一覧の取得
Azure Database for PostgreSQLはCREATE DATABASE等のDDLによるデータベース操作も可能ですが、Azure純正のazコマンドで操作する事もできます。
例えば以下のようにaz postgres db listコマンドを使用するとデータベース一覧を取得する事もできます。
az postgres db list \ --resource-group myResourceGroup \ --server-name gokatei-db-01
実行例は以下の通りです。azure_maintenance, azure_sysなど、オンプレミスでPostgreSQLを構築した場合には見られないAzure管理のデータベースが作成されている事が分かります。
admin@mac19 ~ % az postgres db list \ --resource-group myResourceGroup \ --server-name gokatei-db-01 [ { "charset": "UTF8", "collation": "English_United States.1252", "id": "/subscriptions/2e2f81a9-b030-410f-9784-c582580c932e/resourceGroups/myResourceGroup/providers/Microsoft.DBforPostgreSQL/servers/gokatei-db-01/databases/postgres", "name": "postgres", "resourceGroup": "myResourceGroup", "type": "Microsoft.DBforPostgreSQL/servers/databases" }, { "charset": "UTF8", "collation": "English_United States.1252", "id": "/subscriptions/2e2f81a9-b030-410f-9784-c582580c932e/resourceGroups/myResourceGroup/providers/Microsoft.DBforPostgreSQL/servers/gokatei-db-01/databases/azure_maintenance", "name": "azure_maintenance", "resourceGroup": "myResourceGroup", "type": "Microsoft.DBforPostgreSQL/servers/databases" }, { "charset": "UTF8", "collation": "English_United States.1252", "id": "/subscriptions/2e2f81a9-b030-410f-9784-c582580c932e/resourceGroups/myResourceGroup/providers/Microsoft.DBforPostgreSQL/servers/gokatei-db-01/databases/azure_sys", "name": "azure_sys", "resourceGroup": "myResourceGroup", "type": "Microsoft.DBforPostgreSQL/servers/databases" } ]
データベースの作成
以下のようなazコマンドでデータベースを作成する事もできます。
az postgres db create \ --resource-group myResourceGroup \ --server-name gokatei-db-01 \ --name sample-01
操作例は以下の通りです。
admin@mac19 ~ % az postgres db create \ --resource-group myResourceGroup \ --server-name gokatei-db-01 \ --name sample-01 { "charset": "UTF8", "collation": "English_United States.1252", "id": "/subscriptions/2e2f81a9-b030-410f-9784-c582580c932e/resourceGroups/myResourceGroup/providers/Microsoft.DBforPostgreSQL/servers/gokatei-db-01/databases/sample-01", "name": "sample-01", "resourceGroup": "myResourceGroup", "type": "Microsoft.DBforPostgreSQL/servers/databases" } admin@mac19 ~ %
想定通りのデータベースが作成されているかを確認します。azコマンドに頼らず、psqlでデータベースが作成されている事を確認します。
admin@mac19 ~ % psql \ "host=gokatei-db-01.postgres.database.azure.com \ port=5432 \ dbname=postgres \ user=myadmin@gokatei-db-01 \ password=P@ssw0rd \ sslmode=require" psql (14.2, server 9.6.21) SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off) Type "help" for help. postgres=> \l List of databases Name | Owner | Encoding | Collate | Ctype | Access privileges -------------------+-----------------+----------+----------------------------+----------------------------+------------------------------------- azure_maintenance | azure_superuser | UTF8 | English_United States.1252 | English_United States.1252 | azure_superuser=CTc/azure_superuser azure_sys | azure_superuser | UTF8 | English_United States.1252 | English_United States.1252 | postgres | azure_superuser | UTF8 | English_United States.1252 | English_United States.1252 | sample-01 | myadmin | UTF8 | English_United States.1252 | English_United States.1252 | template0 | azure_superuser | UTF8 | English_United States.1252 | English_United States.1252 | =c/azure_superuser + | | | | | azure_superuser=CTc/azure_superuser template1 | azure_superuser | UTF8 | English_United States.1252 | English_United States.1252 | =c/azure_superuser + | | | | | azure_superuser=CTc/azure_superuser (6 rows) postgres=>
プライベート エンドポイント
前述の操作例はパブリックIPアドレスを介して接続する方法です。Azure内の仮想マシンやAppServiceがパブリックIPアドレスを介して接続するのはセキュリティ観点でも性能観点でも望ましくありませんので、プライベートIPアドレス経由で接続できるようにします。
仮想ネットワークと仮想マシン
仮想マシンからプライベートIPアドレス経由で接続するには「プライベート エンドポイント」と呼ばれる設定が必要です。この設定の動作確認するために、動作確認用の仮想ネットワークと仮想マシンを作成します。
az network vnet create \ -g myResourceGroup \ -n vnet01 \ --address-prefix 172.16.0.0/16 \ --subnet-name Subnet01 \ --subnet-prefix 172.16.1.0/24 az vm create \ --resource-group myResourceGroup \ --name linux020 \ --image Oracle:Oracle-Linux:ol85-lvm:8.5.2 \ --public-ip-sku Standard \ --admin-username azureuser \ --authentication-type ssh \ --ssh-key-values ~/.ssh/authorized_keys \ --vnet-name vnet01 \ --subnet Subnet01 \ --private-ip-address 172.16.1.20
プライベート エンドポイント ネットワーク ポリシーの無効化
プライベート エンド ポイントをサブネットに接続するには、NSG(ネットワーク セキュリティ グループ)をプライベート エンド ポイントに適用しないように設定変更する必要があります。
この操作はポータル(GUI)を使用する場合は、プライベート エンド ポイントの接続操作をした場合は、自動的にプライベート エンドポイント ネットワーク ポリシーが無効化されます。ポータル(GUI)を使用する場合は明示的な操作は不要です。
操作例は以下の通りです。--disable-private-endpoint-network-policiesというオプションを使用して操作します。
az network vnet subnet update \ --name Subnet01 \ --resource-group myResourceGroup \ --vnet-name vnet01 \ --disable-private-endpoint-network-policies true
操作後、showコマンドを発行し、privateEndpointNetworkPoliciesがFalseに変わった事を確認します。
admin@mac19 ~ % az network vnet subnet show \ -g myResourceGroup \ --vnet-name vnet01 \ --name Subnet01 { "addressPrefix": "172.16.1.0/24", "addressPrefixes": null, "applicationGatewayIpConfigurations": null, "delegations": [], "etag": "W/\"5cd8063d-8830-42c9-b922-f99b7c0cc382\"", "id": "/subscriptions/2e2f81a9-b030-410f-9784-c582580c932e/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/vnet01/subnets/Subnet01", "ipAllocations": null, "ipConfigurationProfiles": null, "ipConfigurations": [ { "etag": null, "id": "/subscriptions/2e2f81a9-b030-410f-9784-c582580c932e/resourceGroups/myResourceGroup/providers/Microsoft.Network/networkInterfaces/linux020VMNic/ipConfigurations/ipconfiglinux020", "name": null, "privateIpAddress": null, "privateIpAllocationMethod": null, "provisioningState": null, "publicIpAddress": null, "resourceGroup": "myResourceGroup", "subnet": null } ], "name": "Subnet01", "natGateway": null, "networkSecurityGroup": null, "privateEndpointNetworkPolicies": "Disabled", "privateEndpoints": null, "privateLinkServiceNetworkPolicies": "Enabled", "provisioningState": "Succeeded", "purpose": null, "resourceGroup": "myResourceGroup", "resourceNavigationLinks": null, "routeTable": null, "serviceAssociationLinks": null, "serviceEndpointPolicies": null, "serviceEndpoints": null, "type": "Microsoft.Network/virtualNetworks/subnets" }
プライベート エンドポイントの作成
プライベート エンドポイントを作成する操作例は以下の通りです。作成するためには、PostgreSQLサーバの「名前」ではなく「ID」を指定する必要がありますので、まずはIDの調査が必要になります。
Azure Database for PostgreSQL 単一(シングル)サーバを使用する場合は、group-idにpostgresqlServerを指定します。
az network private-endpoint create \ --name myPrivateEndpoint \ --resource-group myresourcegroup \ --vnet-name vnet01 \ --subnet Subnet01 \ --private-connection-resource-id <PostgreSQLサーバのid> \ --group-id postgresqlServer \ --connection-name myConnection
まずは、引数に指定するPostgreSQLサーバの「ID」を調査します。
公式ドキュメント「CLI を使用して Azure Database for PostgreSQL 単一サーバー用の Private Link を作成および管理する」では、以下のようなaz resource showコマンドを使った調査方法が紹介されています。
admin@mac19 ~ % az resource show \ --resource-group myResourcegroup \ --name gokatei-db-01 \ --resource-type "Microsoft.DBforPostgreSQL/servers" { "extendedLocation": null, "id": "/subscriptions/2e2f81a9-b030-410f-9784-c582580c932e/resourceGroups/myResourceGroup/providers/Microsoft.DBforPostgreSQL/servers/gokatei-db-01", "identity": null, "kind": null, "location": "japaneast", "managedBy": null, "name": "gokatei-db-01", "plan": null, "properties": { "administratorLogin": "myadmin", "byokEnforcement": "Disabled", "earliestRestoreDate": "2022-02-25T12:30:56.357+00:00", "fullyQualifiedDomainName": "gokatei-db-01.postgres.database.azure.com", "infrastructureEncryption": "Disabled", "masterServerId": "", "minimalTlsVersion": "TLSEnforcementDisabled", "privateEndpointConnections": [], "publicNetworkAccess": "Enabled", "replicaCapacity": 5, "replicationRole": "None", "sslEnforcement": "Enabled", "storageProfile": { "backupRetentionDays": 7, "geoRedundantBackup": "Disabled", "storageAutogrow": "Enabled", "storageMB": 51200 }, "userVisibleState": "Ready", "version": "9.6" }, "resourceGroup": "myResourceGroup", "sku": { "capacity": 2, "family": "Gen5", "model": null, "name": "GP_Gen5_2", "size": null, "tier": "GeneralPurpose" }, "tags": null, "type": "Microsoft.DBforPostgreSQL/servers" }
公式手順とは異なりますが、PostgreSQLサーバに対するshowコマンドでも調査可能です。
admin@mac19 ~ % az postgres server show \ --resource-group myResourceGroup \ --name gokatei-db-01 { "administratorLogin": "myadmin", "byokEnforcement": "Disabled", "earliestRestoreDate": "2022-02-25T12:30:56.357000+00:00", "fullyQualifiedDomainName": "gokatei-db-01.postgres.database.azure.com", "id": "/subscriptions/2e2f81a9-b030-410f-9784-c582580c932e/resourceGroups/myResourceGroup/providers/Microsoft.DBforPostgreSQL/servers/gokatei-db-01", "identity": null, "infrastructureEncryption": "Disabled", "location": "japaneast", "masterServerId": "", "minimalTlsVersion": "TLSEnforcementDisabled", "name": "gokatei-db-01", "privateEndpointConnections": [], "publicNetworkAccess": "Enabled", "replicaCapacity": 5, "replicationRole": "None", "resourceGroup": "myResourceGroup", "sku": { "capacity": 2, "family": "Gen5", "name": "GP_Gen5_2", "size": null, "tier": "GeneralPurpose" }, "sslEnforcement": "Enabled", "storageProfile": { "backupRetentionDays": 7, "geoRedundantBackup": "Disabled", "storageAutogrow": "Enabled", "storageMb": 51200 }, "tags": null, "type": "Microsoft.DBforPostgreSQL/servers", "userVisibleState": "Ready", "version": "9.6" }
以上の調査結果を踏まえたと操作例を示します。
postgresql_id=$(az postgres server show \ --resource-group myResourceGroup \ --name gokatei-db-01 \ --query "id" \ --output tsv) az network private-endpoint create \ --name myPrivateEndpoint \ --resource-group myResourceGroup \ --vnet-name vnet01 \ --subnet Subnet01 \ --private-connection-resource-id ${postgresql_id} \ --group-id postgresqlServer \ --connection-name myConnection
疎通確認(1)
プライベート エンドポイントに対してshowコマンドを発行し、PostgreSQLのエンドポイントにどのプライベートIPアドレスが割り当てられたかを確認します。
admin@mac19 ~ % az network private-endpoint show \ --name myPrivateEndpoint \ --resource-group myResourceGroup { "applicationSecurityGroups": null, "customDnsConfigs": [ { "fqdn": "gokatei-db-01.postgres.database.azure.com", "ipAddresses": [ "172.16.1.4" ] } ], "customNetworkInterfaceName": "", "etag": "W/\"0c553977-986d-471d-b63b-64efacbfb104\"", "extendedLocation": null, "id": "/subscriptions/2e2f81a9-b030-410f-9784-c582580c932e/resourceGroups/myresourcegroup/providers/Microsoft.Network/privateEndpoints/myPrivateEndpoint", "ipConfigurations": [], "location": "japaneast", "manualPrivateLinkServiceConnections": [], "name": "myPrivateEndpoint", <omitted>
Azure上に作成された仮想マシンから、psqlコマンドを使ってPostgreSQLへ接続可能である事を確認します。まずは仮想マシンにpsqlコマンドをインストールします。
sudo su - dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-8-x86_64/pgdg-redhat-repo-latest.noarch.rpm dnf -qy module disable postgresql dnf install -y postgresql13
プライベートIPアドレスを用いた接続ができる事を確認します。
[root@linux020 ~]# psql \ > "host=172.16.1.4 \ > port=5432 \ > dbname=postgres \ > user=myadmin@gokatei-db-01 \ > password=P@ssw0rd \ > sslmode=require" psql (13.6, server 9.6.21) SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off) Type "help" for help. postgres=>
プライベートDNSゾーンの作成
IPアドレスによる接続は不便ですので、PostgreSQLサーバ名に対するCNAMEを定義しましょう。
ポータル(GUI)で操作した場合は、自動的にCNAMEが作成され明示的な操作は不要になります。
「privatelink.postgres.database.azure.com」という名前のゾーンファイルを作成します。このゾーンファイル名は任意の名前ではなく、「privatelink.postgres.database.azure.com」を使用して下さい。az network private-link-resource listコマンドの実行結果をよく観察すると、任意の名前が許容されていない事が分かります。
az network private-dns zone create \ --resource-group myResourceGroup \ --name "privatelink.postgres.database.azure.com" az network private-dns link vnet create \ --resource-group myResourceGroup \ --zone-name "privatelink.postgres.database.azure.com" \ --name MyDNSLink \ --virtual-network vnet01 \ --registration-enabled false
以下のようなコマンドでCNAMEを定義します。
az network private-dns record-set a create \ --name <PostgreSQLサーバの短縮ホスト名> \ --zone-name privatelink.postgres.database.azure.com \ --resource-group myresourcegroup az network private-dns record-set a add-record \ --record-set-name <PostgreSQLサーバの短縮ホスト名> \ --zone-name privatelink.postgres.database.azure.com \ --resource-group myresourcegroup \ --ipv4-address <プライベート エンドポイントのIPアドレス>
「PostgreSQLサーバの短縮ホスト名」「プライベート エンドポイントのIPアドレス」を調査します。
公式ドキュメント「CLI を使用して Azure Database for PostgreSQL 単一サーバー用の Private Link を作成および管理する」では、以下のようなaz resource showコマンドを使った調査方法が紹介されています。
networkInterfaceId=$(az network private-endpoint show \ --name myPrivateEndpoint \ --resource-group myResourceGroup \ --query 'networkInterfaces[0].id' \ --output tsv) az resource show \ --ids ${networkInterfaceId} \ --api-version 2019-04-01 \ --output json
公式手順とは異なりますが、プライベート エンドポイントに対してshowコマンドでも調査可能です。
admin@mac19 ~ % az network private-endpoint show \ --name myPrivateEndpoint \ --resource-group myResourceGroup { "applicationSecurityGroups": null, "customDnsConfigs": [ { "fqdn": "gokatei-db-01.postgres.database.azure.com", "ipAddresses": [ "172.16.1.4" ] } ], "customNetworkInterfaceName": "", "etag": "W/\"0c553977-986d-471d-b63b-64efacbfb104\"", "extendedLocation": null, "id": "/subscriptions/2e2f81a9-b030-410f-9784-c582580c932e/resourceGroups/myresourcegroup/providers/Microsoft.Network/privateEndpoints/myPrivateEndpoint", "ipConfigurations": [], "location": "japaneast", "manualPrivateLinkServiceConnections": [], "name": "myPrivateEndpoint", <omitted>
CNAMEを定義する操作例は以下の通りです。
az network private-dns record-set a create \ --name gokatei-db-01 \ --zone-name privatelink.postgres.database.azure.com \ --resource-group myResourceGroup az network private-dns record-set a add-record \ --record-set-name gokatei-db-01 \ --zone-name privatelink.postgres.database.azure.com \ --resource-group myResourceGroup \ --ipv4-address 172.16.1.4
疎通確認(2)
Azure上に作成された仮想マシンから、プライベート エンドポイントに対する名前解決ができる事を確認します。
[root@linux020 ~]# nslookup gokatei-db-01.postgres.database.azure.com Server: 168.63.129.16 Address: 168.63.129.16#53 Non-authoritative answer: gokatei-db-01.postgres.database.azure.com canonical name = gokatei-db-01.privatelink.postgres.database.azure.com. Name: gokatei-db-01.privatelink.postgres.database.azure.com Address: 172.16.1.4
psqlコマンドで、名前による接続が可能である事を確認します。
p[root@linux020 ~]# psql \ > "host=gokatei-db-01.postgres.database.azure.com \ > port=5432 \ > dbname=postgres \ > user=myadmin@gokatei-db-01 \ > password=P@ssw0rd \ > sslmode=require" psql (13.6, server 9.6.21) SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off) Type "help" for help. postgres=>
補足
パブリック ネットワーク アクセスの拒否
プライベート エンドポイントを定義している場合は、パブリックIPアドレス経由の接続は不要です。ファイアウォールルールに関わらず、パブリックIPアドレスからの接続を禁止するには事もできます。操作例は以下の通りです。
az postgres server update \ --resource-group myResourceGroup \ --name gokatei-db-01 \ --public-network-access Disabled
SSLの無効化
状況によってはSSLを無効化したい場合もあるかもしれません。PostgreSQLに接続する時のSSLを強制しないように設定変更するには、以下のように操作します。
az postgres server update \ --resource-group myresourcegroup \ --name gokatei-db-01 \ --ssl-enforcement Disabled