AWS各サービスの価格情報をスクレイピングするワンライナー

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

昔のURLは非推奨になってしまった

AWSの価格一覧を取得したいときに以前まで使っていたURLが非推奨になってしまっていました。そこで、新しいURLを使って同じようなことをしてみたいと思います。

以前の方法。

https://aws.amazon.com/jp/ec2/pricing/json/linux-od.json

301転送される

https://a0.awsstatic.com/pricing/1/deprecated/ec2/linux-od.json

新しいURLはAWSの各サービスのHTMLソースを見れば分かります。新しいURLはJSONではなくJSONPのコールバックになっています。これはブラウザアプリから呼び出し易くなりましたが、スクレイピングするには面倒です。そこで、JSONに変換するワンライナーを入れます。

新しいURL

http://a0.awsstatic.com/pricing/1/ec2/linux-od.min.js

callback部分を外す

$ curl http://a0.awsstatic.com/pricing/1/ec2/linux-od.min.js \
  | sed -n 's/.*callback(//p' \
  | sed -e 's/);$//g'

JSONとして認識させるために名前を"でくくる

$ curl http://a0.awsstatic.com/pricing/1/ec2/linux-od.min.js \
  | sed -n 's/.*callback(//p' \
  | sed -e 's/);$//g' \
  | sed 's/\([0-9a-zA-Z]*\):/\"\1\":/g'

jqで形を整える

$ curl http://a0.awsstatic.com/pricing/1/ec2/linux-od.min.js \
  | sed -n 's/.*callback(//p' \
  | sed -e 's/);$//g' \
  | sed 's/\([0-9a-zA-Z]*\):/\"\1\":/g' \
  | jq .

結果

・・・
    "regions": [
      {
        "region": "us-east-1",
        "instanceTypes": [
          {
            "type": "generalCurrentGen",
            "sizes": [
              {
                "size": "t2.micro",
                "vCPU": "1",
                "ECU": "variable",
                "memoryGiB": "1",
                "storageGB": "ebsonly",
                "valueColumns": [
                  {
                    "name": "linux",
                    "prices": {
                      "USD": "0.013"
                    }
                  }
                ]
・・・

jqを使ってもっとピンポイントに情報を収集する

基本的な方法が分かりましたので必要な情報だけを取り出してみましょう

対応しているリージョン一覧

$ curl http://a0.awsstatic.com/pricing/1/ec2/linux-od.min.js \
  | sed -n 's/.*callback(//p' \
  | sed -e 's/);$//g' \
  | sed 's/\([0-9a-zA-Z]*\):/\"\1\":/g' \
  | jq .config.regions[].region

結果

"us-east-1"
"us-west-2"
"us-west-1"
"eu-west-1"
"eu-central-1"
"ap-southeast-1"
"ap-northeast-1"
"ap-southeast-2"
"sa-east-1"
"us-gov-west-1

東京リージョンの情報だけ取得

$ curl http://a0.awsstatic.com/pricing/1/ec2/linux-od.min.js \
  | sed -n 's/.*callback(//p' \
  | sed -e 's/);$//g' \
  | sed 's/\([0-9a-zA-Z]*\):/\"\1\":/g' \
  | jq .config.regions[] \
  | jq 'select(.region=="ap-northeast-1")'

結果

{
  "region": "ap-northeast-1",
  "instanceTypes": [
    {
      "type": "generalCurrentGen",
      "sizes": [
        {
          "size": "t2.micro",
          "vCPU": "1",
          "ECU": "variable",
          "memoryGiB": "1",
          "storageGB": "ebsonly",
          "valueColumns": [
            {
              "name": "linux",
              "prices": {
                "USD": "0.020"
              }
            }
          ]
        },
・・・

Spotインスタンスの情報

Spotインスタンスの情報が入っているjsは、静的テキストではなく動的生成しているようで、他とフォーマットが異なるのでコマンドも少々違います。

$ curl http://spot-price.s3.amazonaws.com/spot.js \
  | sed -e 's/.*callback(//g' \
  | sed -e 's/)$//g' \
  | jq .config.regions[] \
  | jq 'select(.region=="apac-tokyo")'

結果

{
  "region": "apac-tokyo",
  "footnotes": {
    "*": "clusterOnlyInUSEast"
  },
  "instanceTypes": [
    {
      "type": "generalCurrentGen",
      "sizes": [
        {
          "size": "m3.medium",
          "valueColumns": [
            {
              "name": "linux",
              "prices": {
                "USD": "0.0122"
              }
            },
            {
              "name": "mswin",
              "prices": {
                "USD": "0.0731"
              }
            }
          ]
        },
・・・

他サービスの価格情報

EC2

RDS

S3

Redshift

ElastiCache

まとめ

ある程度メジャーなサービスは価格表をjs経由で取得出来る事が分かりました。jqで加工できますので煮るなり焼くなりしてDBなどに入れておいても良いかもしれませんね。