1. やりたいこと
AzureのSQL serverに外部から接続するためには、ファイヤウォールで許可するipを設定しなければならない。クライアント側がglobal ipだったらいいのだが、今回はそうではない。ルーターの電源を切らなければ、ipは変わってないので大丈夫なのだけど、停電とかその他理由で突然ipが変更になった場合に、SQL Serverに接続できなくなる。
なので、global ipが変わったときに、ファイヤウォールの設定を自動的に行いたいというのが、やりたいこと。
そのためには、Azure認証を自動的に行う必要がある。AzureのServicePrincipalを使って、Azure認証を行い、PowershellでSQL Serverのファイヤウォールの設定を変更する。
参考:
2. Service Principalの作成
サービスプリンシパルについてはここを参照。
・Azure Active Directory > アプリの登録 > 新規登録
アプリケーションの名前を決める。ここでは、ServicePrincipalTestとする。
・アプリケーションIDとテナントIDを後から使うので控えておく。
・"証明書とシークレット"を追加。
新しいクライアント シークレットを選択。有効期限を決めて、追加。
・"値"というのが認証用のパスワードになるので、覚えておく。
3. カスタムロールの作成
ServicePrincipalにどのような権限を持たせるかを定義する。ロールに紐づいたActionがあって、ServicePrincipalにロールを割り当てるのだが、今回やりたいのはファイヤウォール規則の変更なので、それだけをもつロールを定義して、そのロールをServicePrincipalに割り当てる。
・サブスクリプション>アクセス制御(IAM)>カスタムロールを作成する
カスタムロール名を決める。ここでは、"SQL firewallRules”とする。
・今回ファイヤウォールのルール作成なので、firewallと検索窓に入れて、アクションを選択。
Microsoft.Sql/servers/firewallRulesのCreateなどにチェック。
4. ServicePrincipalにロールを割り当てる
・サブスクリプション>アクセス制御(IAM) > 追加 >ロールの割当の追加
・検索窓にfirewallと打って、先ほど追加したロールを探す。
・"選択"で、さきほど作成したServicePrincipalの名前を入れると、下にでてくるので、選択して"選択"ボタンを押す。
5. Azure PowerShellをインストール
ログインを行うPCにAzure PowerShellを入れる。
# PowerShellGetの更新
# PowerShellを管理者として起動する。アイコンを右クリックして管理者として実行するを行う。
Install-Module PowerShellGet -Force
# ポリシーの変更
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned
# Azure PowerShellのインストール
Install-Module -Name Az -AllowClobber -Scope CurrentUser
#Import-Module Az.Resources
$tenantId = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
$applicationId = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
$passwd = ConvertTo-SecureString "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" -AsPlainText -Force
$pscredential = New-Object System.Management.Automation.PSCredential($applicationId, $passwd)
Connect-AzAccount -ServicePrincipal -Credential $pscredential -Tenant $tenantId
Read-Host "続けるには Enter キーを押してください..."
tenantIdはテナントID、applicationIdはアプリケーションID、passwdは、ServicePrincipalを作ったときに出てきた"値"を入れる。このスクリプトを走らせれば、Azureにログインができる。それから、ログインしたあとにファイヤーウォールの設定をする。
6. ファイヤウォールの設定
$ipaddress = (Invoke-WebRequest inet-ip.info/ip -UseBasicParsing).Content
Write-Host "Global IP: " $ipaddress
New-AzSqlServerFirewallRule -ResourceGroupName "xxxxxxxxxx" -ServerName "xxxxxxxxx"
-FirewallRuleName xxxxxxxxxx -StartIpAddress $ipaddress -EndIpAddress $ipaddress
Read-Host "続けるには Enter キーを押してください..."
ResourceGroupName はリソースグループ、ServerNameは接続するサーバー名を入れる。
FirewallRuleNameはファイヤウォール規則の名前を適当に入れる。
実際には、このスクリプトをC#でつくったサービスで実行させている。一連のスクリプト全体を一応エンコードしている。
あと、Invoke-WebRequestで-UseBasicParsingを使わないと、サービスで実行したときにIEが設定されてないと言われてエラーになる。これで結構はまった。