PowerShellでAWS Price List API (AKA the Bulk API) からオファーファイルのURL一覧を取得する

この記事を書いたメンバー:

SAITO Keita

PowerShellでAWS Price List API (AKA the Bulk API) からオファーファイルのURL一覧を取得する

目次

はじめに

PowerQueryでAWS Price List API (AKA the Bulk API) からオファーファイルの一覧を取得する #AWS - Qiita


以前、QiitaブログにPowerQueryでAWS Price List APIを取得する方法を投稿しました。

AWSで利用料を確認する際には、各サービスページの料金ページを参照する事が多いのですが。

直接オファーファイルを確認したくなることも、たまにあります。


そのような場合にExcelでURIの一覧を取得できるようにPowerQueryで取得する方法のブログ記事を書きましたが、今回はこの一覧をPowerShellで作成するスクリプトを書いたので紹介します。


なおそもそもAWS Price List API (AKA the Bulk API) が何かについては、上述のQiitaブログに記載しているため本記事では割愛します。

動作確認している環境

  • Windows PowerShell  5.1.26100.2161
  • PowerShell 7.4.6


今回作成しているスクリプトについて

  • 最新のリージョン別のオファーファイルのURLのみ取得するGet-CurrentAWSOfferFileURLByRegion.ps1
  • 過去バージョンのリジョン別のオファーファイルのURLを取得するGet-HistoryAWSOfferFileURLByRegion.ps1

の2種類のスクリプトを作成しています。


最新のリージョン別オファーファイルのURLを取得(Get-CurrentAWSOfferFileURLByRegion.ps1)

#!/usr/bin/env pwsh
<#
.SYNOPSIS
    AWSサービスでインデックスファイルから最新のオファーファイル(リージョン別)のURL一覧を取得
.DESCRIPTION
    AWS Price List API (AKA the Bulk API)から最新のオファーファイルURLを取得する
.EXAMPLE
    # 最新のオファーファイルURLを全取得
    PS > ./Get-CurrentAWSOfferFileURLByRegion.ps1
    # AmazonEC2 かつ ap-northeast-1 となるオファーファイルURLを取得
    PS > ./Get-CurrentAWSOfferFileURLByRegion.ps1 -offerCode AmazonEC2 -regionCode ap-northeast-1
    結果をtxtファイルに出力する場合(省略されないようにWidth 1000 指定)
    PS > ./Get-CurrentAWSOfferFileURLByRegion.ps1 | Format-Table * | Out-File ./CurrentAWSOfferFileURLByRegion.txt -Width 1000
    結果をcsvファイルに出力する場合
    PS > ./Get-CurrentAWSOfferFileURLByRegion.ps1 | Export-Csv ./CurrentAWSOfferFileURLByRegion.csv
.INPUTS
    None
.OUTPUTS
    pscustomobject serviceName, regionCode, offerFileUrl
#>
[CmdletBinding()]
param (
    [Parameter(Mandatory = $false)]
    [string]$offerCode = "*",
    [Parameter(Mandatory = $false)]
    [string]$regionCode = "*"
)


PROCESS {


    Set-StrictMode -Version Latest
    $ErrorActionPreference = "stop"


    # AmazonPriceListAPIのベースUri
    $baseUri = "https://pricing.us-east-1.amazonaws.com"


    # AWSのサービス一覧を取得
    $serviceList = ((Invoke-RestMethod "$baseUri/offers/v1.0/aws/index.json").offers.psobject.Properties.value)


    # 引数のofferCodeでフィルタ
    $targetServiceList = $serviceList | Where-Object offerCode -Like $offerCode


    foreach ($serviceRow in $targetServiceList) {
        # 最新のリージョン別のインデックスファイルURL生成
        $currentRegionIndexUrl = ($baseUri + $serviceRow.currentRegionIndexUrl)
        # 最新のリージョン別のサービスインデックスファイル取得
        $currentRegionIndex = (Invoke-RestMethod -Uri $currentRegionIndexUrl).regions.psobject.Properties.value
        # 引数のregionCodeでフィルタ
        $targetCurrentRegionIndex = $currentRegionIndex | Where-Object regionCode -Like $regionCode


        # リージョンごとのインデックスファイルからオファーファイルのURLを生成
        foreach ($regionRow in $targetCurrentRegionIndex) {
            $outputLine = [pscustomobject]@{
                serviceName  = $serviceRow.offerCode
                regionCode   = $regionRow.regionCode
                offerFileUrl = ($baseUri + $regionRow.currentVersionUrl)
            }
            Write-Output $outputLine
        }
    }
}


上記、PowerShellスクリプトを引数を付けずに実行すると最新のサービス別リージョン別のオファーファイルのURLが表示されます。

EXSAMPLEに記載していますが、ファイルに保存する場合はOut-FileやExport-CSVにするなど適宜調整してください。

やってる事は単純で、

  • https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/index.json からサービス別のインデックスファイルを取得
  • インデックスファイルにはサービスごとにcurrentRegionIndexUrlにリージョンごとのインデックスファイルの識別子があるので、URLにしてリージョンごとのインデックスファイルを取得
  • リージョンごとのインデックスファイルの中にはオファーファイルの識別子があるので、これをURLにして出力


バージョン別にリージョン別オファーファイルのURLを取得(Get-HistoryAWSOfferFileURLByRegion.ps1)

#!/usr/bin/env pwsh
<#
.SYNOPSIS
    AWSサービスでインデックスファイルから取得できるすべてのオファーファイル(リージョン別)のURL一覧を取得
.DESCRIPTION
    AWS Price List API (AKA the Bulk API)から最新のオファーファイルURLを取得する
.EXAMPLE
    # リージョン別オファーファイルURLをHistoryを含めて全取得
    PS > ./Get-HistoryAWSOfferFileURLByRegion.ps1
    # AmazonEC2 かつ ap-northeast-1 となるオファーファイルURLをHistoryを含めて全取得
    PS > ./Get-HistoryAWSOfferFileURLByRegion.ps1 -offerCode AmazonEC2 -regionCode ap-northeast-1
    結果をtxtファイルに出力する場合(省略されないようにWidth 1000 指定)
    PS > ./Get-HistoryAWSOfferFileURLByRegion.ps1 | Format-Table * | Out-File ./HistoryAWSOfferFileURLByRegion.txt -Width 1000
    結果をcsvファイルに出力する場合
    PS > ./Get-HistoryAWSOfferFileURLByRegion.ps1 | Export-Csv ./HistoryAWSOfferFileURLByRegion.csv
.INPUTS
    None
.OUTPUTS
    pscustomobject serviceName, versionEffectiveBeginDate, versionEffectiveEndDate, regionCode, offerFileUrl
#>
[CmdletBinding()]
param (
    [Parameter(Mandatory = $false)]
    [string]$offerCode = "*",
    [Parameter(Mandatory = $false)]
    [string]$regionCode = "*"
)


PROCESS {


    Set-StrictMode -Version Latest
    $ErrorActionPreference = "stop"


    # AmazonPriceListAPIのベースUri
    $baseUri = "https://pricing.us-east-1.amazonaws.com"


    # AWSのサービス一覧を取得
    $serviceList = ((Invoke-RestMethod "$baseUri/offers/v1.0/aws/index.json").offers.psobject.Properties.value)


    # 引数のofferCodeでフィルタ
    $targetServiceList = $serviceList | Where-Object offerCode -Like $offerCode


    foreach ($serviceRow in $targetServiceList) {
        # versionIndexUrl URL生成
        $versionIndexUrl = ($baseUri + $serviceRow.versionIndexUrl)
        # リージョン別のサービスインデックスデータ取得
        $versionIndex = (Invoke-RestMethod -Uri $versionIndexUrl).versions.psobject.Properties.value | Sort-Object versionEffectiveBeginDate


        # 該当サービスの提供リージョン一覧を表示
        foreach ($versionRow in $VersionIndex) {
            # offerVersionUrlのindex.jsonをregion_index.jsonに書き換えてリージョンごとのインデックスファイルURLを生成
            $regionIndexUrl = ($baseUri + $versionRow.offerVersionUrl -replace "index.json", "region_index.json")
            # リージョンごとのインデックスファイル取得
            $regionIndex = (Invoke-RestMethod -Uri $regionIndexUrl).regions.psobject.Properties.value
            # 引数のregionCodeでフィルタ
            $targetRegionIndex = $regionIndex | Where-Object regionCode -Like $regionCode | Sort-Object regionCode


            # リージョンごとのインデックスファイルからオファーファイルのURLを生成
            foreach ($regionRow in $targetRegionIndex ) {
                $outputLine = [pscustomobject]@{
                    serviceName               = $serviceRow.offerCode
                    versionEffectiveBeginDate = $versionRow.versionEffectiveBeginDate
                    versionEffectiveEndDate   = $versionRow.versionEffectiveEndDate
                    regionCode                = $regionRow.regionCode
                    offerFileUrl              = ($baseUri + $regionRow.currentVersionUrl)
                }
                Write-Output $outputLine
            }


        }
    }
}


こちらもやっている事は単純ですが、サービス別のインデックスファイルには最新のファイル用のリージョン事のインデックスファイルの識別子としてcurrentRegionIndexUrlが用意されていますが。

バージョンごとの方についてはリージョン事のインデックスファイルの識別子は用意されていません。





versionRegionIndexUrlといた項目があれば、それを使えばよいのですがないのでindex.jsonをregin_index.jsonに読み替えてリージョン毎のインデックスファイルを取得します。

あとは最新の情報を取得するときと一緒でリージョン毎のインデックスファイルを取得して、その中にオファーファイルの識別子があるのでこれをURLにして出力。

総評

以前、PowerQueryでオファーファイルのURLを取得する仕組みを作成してみましたが、今回はちょっとPowerShellのコマンドベースでオファーファイルのURLを取得する仕組みが欲しくなったので作成してみました。


方式としてサービス別のインデックスファイルを取得 ー> サービスごとにリージョン別のインデックスファイルを取得 といった流れとなるため、インデックスファイル分の1回+対象とするサービスの個数回のInvoke-RestMethodが発生するので、引数で条件指定せずに全サービス取得しようとするとだいぶ時間はかかります。


カテゴリー
タグ

この記事を書いたメンバー

SAPシステムや基幹システムのクラウド移行・構築・保守、
DXに関して
お気軽にご相談ください

03-6260-6240 (受付時間 平日9:30〜18:00)