Azure Automationアカウントの証明書期限が切れる前にメール/Slack通知する

[Azure Automationアカウントの証明書を更新する](https://qiita.com/shingo_kawahara/items/cca948c7daa1ab515a87) で更新手順を書きましたが、たぶん期限切れを忘れるので事前に通知する方法を考えました。

# やり方
Azure PowerShellのGet-AzureRmAutomationCertificateコマンドで、期限切れする日付を取得できるので、現在日付と比較して期限切れ前にSlack通知します。
設定場所は自分自身のAutomation Runbookです。

# Slack通知する手順
* 以下のようにPowerShell Runbookを作ります。Slackの通知先チャンネル名やWebHook URLは置き換えてください。

```
Param(
    [parameter(Mandatory=$True)]
    [string]$resourceGroup,

    [parameter(Mandatory=$True)]
    [string]$accountName,

    [parameter(Mandatory=$True)]
    [int]$notificationDay
)

$Conn = Get-AutomationConnection -Name AzureRunAsConnection
Add-AzureRMAccount -ServicePrincipal -Tenant $Conn.TenantID -ApplicationID $Conn.ApplicationID -CertificateThumbprint $Conn.CertificateThumbprint

# Automationアカウントの証明書が期限切れする日付を取得
$expiryTime = (Get-AzureRmAutomationCertificate -ResourceGroupName $resourceGroup -AutomationAccountName $accountName | Where-Object {$_.Name -match "^AzureRunAsCertificate$"}).ExpiryTime.DateTime
# 現在の日付を取得
$today = Get-Date
# 現在日付と期限切れ日付の差を取得
$expiredDay = ($expiryTime - $today).Days

if( $expiredDay -lt $notificationDay ) {
    $msg = "Azure Automation Account [$accountName] の証明書が、あと $expiredDay 日で期限切れになります"
    $enc = [System.Text.Encoding]::GetEncoding('ISO-8859-1')
    $utf8Bytes = [System.Text.Encoding]::UTF8.GetBytes($msg)
    $payload = @{
            text = $enc.GetString($utf8Bytes);
            username = "Azure Automation";
            icon_emoji = ":azure:"
            channel = "[Your Slack Channel]"
    }
    Invoke-RestMethod -Uri "[Slack WebHook URL]" -Method Post -Body (ConvertTo-Json $payload)
} else {
    Write-Output $expiredDay
}
```

* あとはRunbookのスケジュール設定して完了です。
* Runbookのパラメータは以下のように与えます。
    * RESOURCEGROUP
        * チェックしたいAutomationアカウントの所属するリソースグループ名
    * ACCOUNTNAME
        * チェックしたいAutomationアカウント名
    * NOTIFICATIONDAY
        * 期限が何日を切ると通知するかの日数を指定。例えば30日前に通知したい場合は「30」と入力して実行します。

* Automationクラシックアカウントはあまり使わないと思うのでチェックしていません。
  チェックしたい場合は「AzureRunAsCertificate」の箇所を「AzureClassicRunAsCertificate」に変えるとうまくいくはずです。

# メール通知する手順
* メール送信にはSendGridを使うので、 [SendGridアカウントを作成](https://qiita.com/shingo_kawahara/items/608fd110f1203453e3c9#sendgrid%E3%82%A2%E3%82%AB%E3%82%A6%E3%83%B3%E3%83%88%E4%BD%9C%E6%88%90) してください
* 次にAutomationアカウントの [SendGrid資格情報を作成](https://qiita.com/shingo_kawahara/items/608fd110f1203453e3c9#sendgrid%E8%B3%87%E6%A0%BC%E6%83%85%E5%A0%B1%E3%82%92%E8%BF%BD%E5%8A%A0%E3%81%99%E3%82%8B) してください
* 以下のようにPowerShell Runbookを作ります。送信元メールアドレスは任意のものに置き換えてください。

```
Param(
    [parameter(Mandatory=$True)]
    [string]$resourceGroup,

    [parameter(Mandatory=$True)]
    [string]$accountName,

    [parameter(Mandatory=$True)]
    [int]$notificationDay,

    [parameter(Mandatory=$True)]
    [String] $SmtpCredName,

    [parameter(Mandatory=$True)]
    [string] $MailTo
)

$Conn = Get-AutomationConnection -Name AzureRunAsConnection
Add-AzureRMAccount -ServicePrincipal -Tenant $Conn.TenantID -ApplicationID $Conn.ApplicationID -CertificateThumbprint $Conn.CertificateThumbprint

# Automationアカウントの証明書が期限切れする日付を取得
$expiryTime = (Get-AzureRmAutomationCertificate -ResourceGroupName $resourceGroup -AutomationAccountName $accountName | Where-Object {$_.Name -match "^AzureRunAsCertificate$"}).ExpiryTime.DateTime
# 現在の日付を取得
$today = Get-Date
# 現在日付と期限切れ日付の差を取得
$expiredDay = ($expiryTime - $today).Days

if( $expiredDay -lt $notificationDay ) {

    $SmtpCredential = Get-AutomationPSCredential -Name $SmtpCredName
 
    function EncodeSubject($s) {
        $enc = [Text.Encoding]::GetEncoding("csISO2022JP")
        $s64 = [Convert]::ToBase64String($enc.GetBytes($s), [Base64FormattingOptions]::None)
        return [String]::Format("=?{0}?B?{1}?=", $enc.HeaderName, $s64)  
    }

    $msg = "Azure Automation Account [$accountName] の証明書が、あと $expiredDay 日で期限切れになります"
    $From = "[任意の送信元メールアドレス]"
    $Subject = EncodeSubject(EncodeSubject("Azure Automation Account期限切れ前通知"))

    Send-MailMessage `
        -To $MailTo  `
        -Subject $Subject  `
        -Body $msg `
        -UseSsl `
        -Port 587 `
        -SmtpServer 'smtp.sendgrid.net' `
        -From $From `
        -BodyAsHtml `
        -Encoding ([System.Text.Encoding]::UTF8) `
        -Credential $SmtpCredential
} else {
    Write-Output $expiredDay
}
```

* あとはRunbookのスケジュール設定して完了です。
* Runbookのパラメータは以下のように与えます。
    * RESOURCEGROUP
        * チェックしたいAutomationアカウントの所属するリソースグループ名
    * ACCOUNTNAME
        * チェックしたいAutomationアカウント名
    * NOTIFICATIONDAY
        * 期限が何日を切ると通知するかの日数を指定。例えば30日前に通知したい場合は「30」と入力して実行します。
    * SMTPCREDNAME
        * 作成したSendGrid資格情報名
    * MAILTO
        * メール送信先アドレス