フォーム読み込み中
こんにちは、ソフトバンクの四役です。
突然ですが、皆さんはクラウドの課金額をどのように管理していますか?
クラウドは従量課金での利用が可能なため、この場合、普段から課金金額を意識して利用しないと、想定以上の費用がかかることがあります。一般的には、クラウドの課金額を直接アカウントにログインしてコンソールで確認することが多いと思いますが、複数のアカウントを管理する際にはこの方法は手間がかかります。スプレッドシートで一覧化できれば、もっと便利です。
そこで今回は、Alibaba Cloudを利用して複数のアカウントの課金額をスプレッドシートで一元管理するGoogle Apps Script(GAS)のサンプルコードを紹介します。
前回の記事「Alibaba Cloudの課金額をスプレッドシートで管理したい! 前編 ~GASでAPIを実行~」では、クラウドの課金額をスプレッドシートで管理するために、クラウド課金額を取得可能なQueryAccountBill APIの紹介と、Google Apps Script(GAS)からQueryAccountBill APIを呼び出し、クラウド課金額の管理に使用する値を返却するGAS関数(callBillingAPI)の実装について紹介しました。
今回は、callBillingAPI関数を使用して、実際にスプレッドシートでクラウド課金額を管理するためのGASのサンプルコードを紹介します。
クラウド課金額を管理するために作成したスプレッドシートの外観は以下の図の通りです。
クラウド課金額の管理を効率化するため、スプレッドシートで以下の機能を実装します。
クラウド課金額を取得した各アカウントのAccountIDを青枠の部分に、4月(年度始まり)から3月(年度終わり)までの月ごとのクラウド課金額を赤枠の部分に出力します。複数のアカウントがある場合は、出力行を矢印の方向に1行ずつオフセットさせて出力します。
各アカウントごとの4月から翌年3月までのクラウド課金額を合算し、設定した予算を超過した場合にGASのコンソールにログを出力します。今回はサンプルコードのため、ログ出力のみとしていますが、実際の管理の場合は、ご利用されるGメールやSlackなどに通知するようカスタマイズするとより効率的に管理できるでしょう。GASからメールやSlack通知を出す方法については、多くの方がブログで紹介していますので、そちらを参照してください。
サンプルコードは、前編で紹介したcallBillingAPI関数が実装済みであれば、そのまま利用することが可能です。今回紹介するサンプルコードはシンプルな機能のみを実装しているため、必要に応じてカスタマイズしてください。
今回のメインとなるGAS関数(getBillingAllMonth)は以下のコードの通りです。
本章では、getBillingAllMonth関数のコードをベースに説明しますが、すべてを説明すると冗長になるため、ポイントとなる箇所に絞ってお伝えします。
const getBillingAllMonth = ()=>{
// 処理を実行する日時とBillingAPIで指定する対象月の定義を取得
const today = new Date();
const billingTargetMonthArray = getBillingTargetMonthArray(today);
//結果を出力するシートを定義
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName('ツール');
// アカウント(キーとシークレット)毎にすべての月のクラウド課金額をループで取得
keySecret.forEach(({keyName, secretName},index)=>{
// gasに登録したプロパティ情報を取得
const key = PropertiesService.getScriptProperties().getProperty(keyName);
const secret = PropertiesService.getScriptProperties().getProperty(secretName);
//4月~翌3月のクラウドの課金データを配列としてAPIで取得
const billingArray = billingTargetMonthArray.map((targetMonth)=>{
Utilities.sleep(200);
return callBillingAPI(targetMonth ,key, secret);
});
// accountIdとaccountNameを代入
const accountId = billingArray[0].accountId;
// 取得したpretaxAmountを別の配列に格納
let pretaxArray = billingArray.map(o=>o.pretaxAmount);
// pretaxArrayの合算が設定した予算を超過した場合、ログを出力
const badget = 10000;
const total = pretaxArray.reduce((total,pretax) => total + pretax, 0);
if(total>=badget){Logger.log(`ログ: 設定予算(${badget}ドル)を超過しました。現在の現在までのクラウド利用料は${total}です。`);}
// 複数セルにpretaxAmountを出力するので配列に格納
pretaxArray = [pretaxArray];
// C7:N7を基準にpretaxAmountを出力、ループ毎に基準から1行下げて出力してく
const pretaxAmountRange = sheet.getRange('C7:N7').offset(index,0);
pretaxAmountRange.setValues(pretaxArray);
// B7を基準にaccountIdを出力、ループ毎に基準から1行下げて出力してく
const accountIdRange = sheet.getRange('B7').offset(index,0);
accountIdRange.setValue(accountId);
});
//D3を基準に最終更新日時を出力
const lastUpdateTimeRange = sheet.getRange('D3');
lastUpdateTimeRange.setValue(Utilities.formatDate(today, 'JST', 'yyyy-MM-dd HH:mm:ss'));
}
以下の処理について解説します。
// 処理を実行する日時とBillingAPIで指定する対象月の定義を取得
const today = new Date();
const billingTargetMonthArray = getBillingTargetMonthArray(today);
この処理は、関数の実行日の情報を基に、QueryAccountBill APIで取得したいクラウド課金額の年度と月をgetBillingTargetMonthArray関数を経由して配列として取得しています。ポイントは、年度の単位でクラウド課金額を管理したい場合、1〜3月とその他の月で設定する西暦が異なる点です。このポイントを加味すると、例えば以下のgetBillingTargetMonthArray関数のサンプルコードのような形になります。
// BillingAPIで取得する月の定義
const getBillingTargetMonthArray = (today) =>{
// 年度の予算管理のため1~3月の場合、year-1する
let year = today.getFullYear();
year = today.getMonth()+1 >= 4 ? year : year - 1;
const billingTargetMonthArray = [
`${year}-04`,
`${year}-05`,
`${year}-06`,
`${year}-07`,
`${year}-08`,
`${year}-09`,
`${year}-10`,
`${year}-11`,
`${year}-12`,
`${year+1}-01`,
`${year+1}-02`,
`${year+1}-03`,
];
return billingTargetMonthArray;
}
次に以下の処理について解説します。
// アカウント(キーとシークレット)毎にすべての月のクラウド課金額をループで取得
keySecret.forEach(({keyName, secretName},index) => {
// gasに登録したプロパティ情報を取得
const key = PropertiesService.getScriptProperties().getProperty(keyName);
const secret = PropertiesService.getScriptProperties().getProperty(secretName);
ポイントは、AccessKeyとAccessKey Secretなどの機微情報についてはPropertiesServiceクラスを利用して取り扱う方が良いという点と、keySecret配列でクラウド課金額を取得したいアカウントを管理したという点です。
keySecretのサンプルコードは以下の通りです。
const keySecret = [
{
//AlibabaCloud Account(1)
keyName: 'key-1',
secretName: 'secret-1',
},
{
//AlibabaCloud Account(2)
keyName: 'key-2',
secretName: 'secret-2',
},
]
GASにはPropertiesServiceクラスがあります。Key-Value形式のデータに対して参照できるユーザーを限定できるこのクラスは、Alibaba Cloudに限らず、キー情報などの機微情報を不特定多数に参照されないようにするのに有効です。機微情報はPropertiesServiceクラスを用いて参照者を限定しましょう。
また、keySecretでは各アカウントごとにPropertiesServiceクラスで機微情報を取得する際に指定する文字列を保持しています。これにより、クラウド課金額を取得する対象のアカウント情報を配列として管理しています。クラウド課金額を取得したいアカウントの増減については、keySecretを編集するだけで対応可能です。
次に以下の処理について解説します。
//4月~翌3月のクラウドの課金データを配列としてAPIで取得
const billingArray = billingTargetMonthArray.map((targetMonth)=>{
Utilities.sleep(200);
return callBillingAPI(targetMonth ,key, secret);
});
ポイントは、QueryAccountBill APIの実行レートを遵守する必要があるため、実行レートを600/60(s)以下に抑える必要があるということです。QueryAccountBill APIの実行レートについては、公式ドキュメントを参照ください。このコードではsleep関数を利用して実行レートを調整しています。
次に以下の処理についてですが、こちらは処理の実行時点までの年度のクラウド課金額を保持するpretaxArrayの値を合算し、badgetで指定した予算を超過したらログを出力しています。
// pretaxArrayの合算が設定した予算を超過した場合、ログを出力
const badget = 10000;
const total = pretaxArray.reduce((total,pretax) => total + pretax, 0);
if(total>=badget){Logger.log(`ログ: 設定予算(${badget}ドル)を超過しました。現在の現在までのクラウド利用料は${total}です。`);}
getBillingAllMonth関数を実行すると、スプレッドシートは以下のように更新されます。
AccountIDは、機微情報のためマスクをしていますが、keySecretに設定した2つのアカウント分、年度の月ごとの予算が一覧表示されていることが確認できました。
続いて、コンソールで予算を超過した際のログが出力されていることを確認してみます。
今回は予算を10000ドルに設定し、2つのアカウントとも処理の実行時点までにクラウド課金額が10000ドルを超過しているため、設定した予算を超過したことを伝えるログが出力されています。期待通りの挙動が確認できました。
ここまで記事をご覧いただき、ありがとうございます。
前編の「Alibaba Cloudの課金額をスプレッドシートで管理したい! 前編 ~GASでAPIを実行~」と併せて、Alibaba Cloudでクラウド課金額を取得できるQueryAccountBill APIの紹介、およびGASを用いて複数アカウントのクラウド課金額を管理するためのサンプルコードを紹介しました。
皆様の、効率的なクラウド利用の助けになりますと幸いです。
Alibaba Cloudは中国国内でのクラウド利用はもちろん、日本-中国間のネットワークの不安定さの解消、中国サイバーセキュリティ法への対策など、中国進出に際する課題を解消できるパブリッククラウドサービスです。
MSP(Managed Service Provider)サービスは、お客さまのパブリッククラウドの導入から運用までをトータルでご提供するマネージドサービスです。
条件に該当するページがございません