AWS CDKでCloudFormationのJSONを取得するAPIをServerless Frameworkで作る

CloudFormationのテンプレートを作るAPIを、AWS CDKで実装してServerless Frameworkでデプロイしてみました。 ちょっと何言っているかわからない。 モチベーション よく使うCloudF […]

広告ここから
広告ここまで

目次

    CloudFormationのテンプレートを作るAPIを、AWS CDKで実装してServerless Frameworkでデプロイしてみました。

    ちょっと何言っているかわからない。

    モチベーション

    • よく使うCloudFormationのテンプレートを一発で作りたかった
    • 可能なら、動的に値を変えれるといいよね
    • ボイラープレートを秘伝のタレ実装なしで作りたい

    思考の流れ

    • AWS CDKがJavaScriptなのでなんとかなりそう
    • CLIのsynthコマンドをJSで動かせばいけるのでは
    • JSON取れたらあとはYAMLに変えるだけだから、とりあえずJSONとろう
    • 実験APIだからsls createでさっさと作ってためそう

    できたもの

    serverless.ymlはただGETのAPIはやしてるだけなので省略。CDKはcdk initせずにそのままnpm install -Sしました。

    'use strict';
    const cdk = require('@aws-cdk/cdk')
    const sam = require('@aws-cdk/aws-sam')
    
    class CdkTestStack extends cdk.Stack {
      constructor(scope, id, props) {
        super(scope, id, props);
        new sam.CfnFunction(
          this,
          'function',
          {
            handler: 'index.handler',
            runtime: 'nodejs8.10',
            codeUri: 'src'
          }
        )
    
      }
    }
    
    module.exports.hello = async (event) => {
      const app = new cdk.App();
      new CdkTestStack(app, 'CdkTestStack');
      const { template } = app.synthesizeStack('CdkTestStack')
      return {
        statusCode: 200,
        body: JSON.stringify(template),
      };
    };
    

    動かしてみる

    $ curl  https://xxxxx.execute-api.us-east-1.amazonaws.com/dev/stack | jq .
    
    {
      "Transform": "AWS::Serverless-2016-10-31",
      "Resources": {
        "function": {
          "Type": "AWS::Serverless::Function",
          "Properties": {
            "CodeUri": "src",
            "Handler": "index.handler",
            "Runtime": "nodejs8.10"
          }
        }
      }
    }

    CloudFormationのJSONがとれました。

    YAMLがとれるようにもしてみる

    js-yamlを使うことで、レスポンスをJSON / YAML切り替えれるようにできます。

    'use strict';
    const cdk = require('@aws-cdk/cdk')
    const sam = require('@aws-cdk/aws-sam')
    const yaml = require('js-yaml')
    
    class CdkTestStack extends cdk.Stack {
      constructor(scope, id, props) {
        super(scope, id, props);
        new sam.CfnFunction(
          this,
          'function',
          {
            handler: 'index.handler',
            runtime: 'nodejs8.10',
            codeUri: 'src'
          }
        )
    
      }
    }
    
    const makeStack = (template, format = 'json') => {
      const type = format === 'yaml' ? 'yaml': 'json'
      if (type === 'json') return JSON.stringify(template)
      return yaml.safeDump(template)
    }
    
    module.exports.hello = async (event) => {
      const { queryStringParameters } = event
      const format = queryStringParameters.format || 'json'
    
      const app = new cdk.App();
      new CdkTestStack(app, 'CdkTestStack');
      const { template } = app.synthesizeStack('CdkTestStack')
    
      return {
        statusCode: 200,
        body: makeStack(template, format),
      };
    };
    

    こんな感じです。

    $ curl  https://xxxxx.execute-api.us-east-1.amazonaws.com/dev/stack?format=yaml | jq .
    
    Transform: 'AWS::Serverless-2016-10-31'
    Resources:
      function:
        Type: 'AWS::Serverless::Function'
        Properties:
          CodeUri: src
          Handler: index.handler
          Runtime: nodejs8.10
    

    使いどころとか

    これだけなら「で?」で終わるのですが、引数を受け取るようにするといろいろ使い所は出てきそうです。

    • ボイラープレートCLI
    • 一部だけ設定を変えたスタックをダウンロードできるAPI
    • スタックをカスタマイズしてDLするAPI
    • 動的にカスタムしてスタック立ち上げまで実行できるようにする
    • etc…

    オフィシャルのテンプレートビルダーで、Lambdaでもローカル環境でも動かせるのはかなりメリットかなと思いますので、いろいろ試してみようかなと思います。

    広告ここから
    広告ここまで
    Home
    Search
    Bookmark