0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

AWS CloudFormationのデプロイ済みスタックのテンプレートを取得

Posted at

CloudFormationのデプロイ済みスタックのテンプレートをawscliでYAMLやJSONのフォーマットで取得する方法です。

aws cloudformation get-templateコマンドでテンプレートを取得できるのですが、デプロイ時YAMLとJSONのどちらを使ったかによって返ってくるフォーマットが違い、毎回試行錯誤してしまうので、メモしておきます。

テンプレートを取得するワンライナー

YAMLでデプロイしたスタックをYAMLで取得

$ aws cloudformation get-template --stack-name $STACKNAME | jq .TemplateBody -r

JSONでデプロイしたスタックをJSONで取得

$ aws cloudformation get-template --stack-name $STACKNAME | jq .TemplateBody

YAMLでデプロイしたスタックをJSONで取得

$ aws cloudformation get-template --stack-name $STACKNAME | jq .TemplateBody -r | yq

$ aws cloudformation get-template --stack-name $STACKNAME | ruby -rjson -ryaml -e 'puts JSON.pretty_generate(YAML.load(JSON.load(ARGF)["TemplateBody"]))'

$ aws cloudformation get-template --stack-name $STACKNAME | jq .TemplateBody -r | python -c 'import sys; import json; from awscli.customizations.cloudformation.yamlhelper import yaml_parse; print(json.dumps(yaml_parse(sys.stdin.read()), indent=4))'

1つ目と2つ目は !GetAtt みたいなのには非対応です。Pythonのboto3がある環境では、3つ目のようにがんばれば !GetAtt みたいなのに対応できます。

JSONでデプロイしたスタックをYAMLで取得

$ aws cloudformation get-template --stack-name $STACKNAME | yq .TemplateBody -y

$ aws cloudformation get-template --stack-name $STACKNAME | ruby -ryaml -e 'puts YAML.dump(YAML.load(ARGF)["TemplateBody"])'

試してみる

テンプレートファイル

RDSのインスタンスを作るシンプルなテンプレートで試します。

AWSTemplateFormatVersion: '2010-09-09'

Resources:
  SampleRDS:
    Type: AWS::RDS::DBInstance
    Properties:
      Engine: postgres
      EngineVersion: 12.5
      DBInstanceIdentifier: samplerdsinstance1
      DBInstanceClass: db.t3.micro
      StorageType: gp2
      AllocatedStorage: 20 # GiB
      DBName: mydb
      MasterUsername: myuser
      MasterUserPassword: mypassword

Outputs:
  SampleRDSEndpoint:
      Value: !GetAtt SampleRDS.Endpoint.Address
{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Resources": {
    "SampleRDS": {
      "Type": "AWS::RDS::DBInstance",
      "Properties": {
        "Engine": "postgres",
        "EngineVersion": 12.5,
        "DBInstanceIdentifier": "samplerdsinstance2",
        "DBInstanceClass": "db.t3.micro",
        "StorageType": "gp2",
        "AllocatedStorage": 20,
        "DBName": "mydb",
        "MasterUsername": "myuser",
        "MasterUserPassword": "mypassword"
      }
    }
  },
  "Outputs": {
    "SampleRDSEndpoint": {
      "Value": {
        "Fn::GetAtt": ["SampleRDS", "Endpoint.Address"]
      }
    }
  }
}

デプロイ

$ aws cloudformation deploy --template-file template.yaml --stack-name sample-yaml
$ aws cloudformation deploy --template-file template.json --stack-name sample-json

aws cloudformation get-templateコマンド

デプロイ時のYAML/JSONでコマンドの出力がだいぶ違うんですよね。。。

YAMLの場合は、YAMLのコードがそのまま文字列になってJSONに埋め込まれている。JSONの場合は、そのままJSON。

$ aws cloudformation get-template --stack-name sample-yaml
{
    "TemplateBody": "AWSTemplateFormatVersion: '2010-09-09'\n\nResources:\n  SampleRDS:\n    Type: AWS::RDS::DBInstance\n    Properties:\n      Engine: postgres\n      EngineVersion: 12.5\n      DBInstanceIdentifier: samplerdsinstance1\n      DBInstanceClass: db.t3.micro\n      StorageType: gp2\n      AllocatedStorage: 20 # GiB\n      DBName: mydb\n      MasterUsername: myuser\n      MasterUserPassword: mypassword\n\nOutputs:\n  SampleRDSEndpoint:\n      Value: !GetAtt SampleRDS.Endpoint.Address\n",
    "StagesAvailable": [
        "Original",
        "Processed"
    ]
}
$ aws cloudformation get-template --stack-name sample-json
{
    "TemplateBody": {
        "AWSTemplateFormatVersion": "2010-09-09",
        "Resources": {
            "SampleRDS": {
                "Type": "AWS::RDS::DBInstance",
                "Properties": {
                    "Engine": "postgres",
                    "EngineVersion": 12.5,
                    "DBInstanceIdentifier": "samplerdsinstance2",
                    "DBInstanceClass": "db.t3.micro",
                    "StorageType": "gp2",
                    "AllocatedStorage": 20,
                    "DBName": "mydb",
                    "MasterUsername": "myuser",
                    "MasterUserPassword": "mypassword"
                }
            }
        },
        "Outputs": {
            "SampleRDSEndpoint": {
                "Value": {
                    "Fn::GetAtt": [
                        "SampleRDS",
                        "Endpoint.Address"
                    ]
                }
            }
        }
    },
    "StagesAvailable": [
        "Original",
        "Processed"
    ]
}

テンプレート取得

YAMLデプロイのスタックをYAMLで取得。YAML自体がJSONの文字列になっているのでjqコマンドに -r オプションを付ける。

$ aws cloudformation get-template --stack-name sample-yaml | jq .TemplateBody -r
AWSTemplateFormatVersion: '2010-09-09'

Resources:
  SampleRDS:
    Type: AWS::RDS::DBInstance
    Properties:
      Engine: postgres
      EngineVersion: 12.5
      DBInstanceIdentifier: samplerdsinstance1
      DBInstanceClass: db.t3.micro
      StorageType: gp2
      AllocatedStorage: 20 # GiB
      DBName: mydb
      MasterUsername: myuser
      MasterUserPassword: mypassword

Outputs:
  SampleRDSEndpoint:
      Value: !GetAtt SampleRDS.Endpoint.Address

JSONデプロイのスタックをJSONで取得。

$ aws cloudformation get-template --stack-name sample-json | jq .TemplateBody
{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Resources": {
    "SampleRDS": {
      "Type": "AWS::RDS::DBInstance",
      "Properties": {
        "Engine": "postgres",
        "EngineVersion": 12.5,
        "DBInstanceIdentifier": "samplerdsinstance2",
        "DBInstanceClass": "db.t3.micro",
        "StorageType": "gp2",
        "AllocatedStorage": 20,
        "DBName": "mydb",
        "MasterUsername": "myuser",
        "MasterUserPassword": "mypassword"
      }
    }
  },
  "Outputs": {
    "SampleRDSEndpoint": {
      "Value": {
        "Fn::GetAtt": [
          "SampleRDS",
          "Endpoint.Address"
        ]
      }
    }
  }
}

YAMLとJSONを変換したければ、冒頭に書いた通りyqコマンドやワンライナーで変換できます。

コマンドのインストール

jqコマンド

jq のインストールはUbuntuならば

$ sudo apt install -y jq

CentOS 8ならば

$ sudo yum install -y jq

yqコマンド

yqはPythonで書かれており、pipでインストールできます。

$ pip install yq

内部でjqを呼び出しているようで、jqがないと次のようなエラーになります。

yq: Error starting jq: FileNotFoundError: [Errno 2] No such file or directory: 'jq'. Is jq installed and available on PATH?
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?