[レポート]上級者への道: Advanced Infrastructure as Code Programming on AWS #reinvent #DEV327

2018.11.27

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

本記事はre:Invent 2018のセッション「DEV327 Beyond the Basics: Advanced Infrastructure as Code Programming on AWS」のレポートです。

概要

In addition to the basic infrastructure as code capabilities provided by AWS CloudFormation, AWS now offers various programmability constructs to power complex provisioning use cases. In this talk, we present several advanced use cases of declarative, imperative, and mixed coding scenarios that cloud infrastructure developers can leverage. Examples include demonstrating how to create custom resources and leveraging transforms, like the AWS Serverless Application Model (AWS SAM), to create both simple and complex macros with AWS CloudFormation.

スピーカー

  • Chuck Meyer - Sr. Dev Advocate - AWS CloudFormation
  • Luis Colon - Senior Developer Advocate, AWS CloudFormation

レポート

アジェンダ

  • 宣言型と命令形のコーディング
  • Deep Dive: AWS CloudFormationマクロ
  • Deep Dive: AWS CloudFormationの中での命令形プログラミング

宣言型と命令形のコーディング

宣言型プログラミングと命令形プログラミングとは何か、またそれらの違いが何なのかを解説。 参入障壁が高いか低いか。また制約が何か。

Cfn: 宣言型プログラミング

CloudFormationはYAML, JSONにより期待する状態が宣言される。

Resources:
    AutoScalingGroup:
        CreationPolicy:
            ResourceSignal:
                Count: !Ref DesiredCapacity
                Timeout: "PT5M"
        UpdatePolicy:
            AUtoScalingReplicationUpdate
            WillReplace: true
        ...

以下により命令形プログラミングも多少は可能

  • EC2 UserData
  • Fn:Condition, Fn:FindInMapなどのようなファンクション

CloudFormationプログラミングの選択肢

宣言型
  • YAML/JSON
  • 変換
    • Include
    • SAM
    • マクロ
    • Jinja/Mustachのようなテンプレートエンジン
命令形

Deep Dive: AWS CloudFormationマクロ

Lambda関数を使ってCloudFormationテンプレートの記法を拡張できる機能

マクロの例と各コードのサンプル

  • 繰り返し
  • Pythonコード実行
  • Stringファンクション(Upper, Lower, ...)
  • グローバル変数

マクロを使うことで、以下のようなコードで

Transform:
    - Count
Resources:
    Bucket:
        Type: AWS::S3::Bucket
        Count: 3

このようにResourcesが展開される

Resources:
    Bucket1:
        Type: AWS::S3::Bucket
    Bucket2:
        Type: AWS::S3::Bucket
    Bucket3:
        Type: AWS::S3::Bucket

Pythonの実行

以下のようにTagsにPythonコードを埋め込むことができ、output変数の内容で置き換えられる。

AWSTemplateFormatVersion: "2010-09-09"
Description: tests String macro functions
Parameters:
  Tags:
    Default: "Env=Prod,Application=MyApp,BU=ModernisationTeam"
    Type: "CommaDelimitedList"
Resources:
  S3Bucket:
    Type: "AWS::S3::Bucket"
    Properties:
      Tags: |
        #!PyPlate
        output = []
        for tag in params['Tags']:
           key, value = tag.split('=')
           output.append({"Key": key, "Value": value})
Transform: [PyPlate]

Stringファンクション

以下のように Fn::Transform を定義することで、InputString の内容が Upper により大文字に変換され Value に置き換えられる。

Parameters:
  InputString:
    Default: "This is a test input string"
    Type: String
Resources:
  S3Bucket:
    Type: "AWS::S3::Bucket"
    Properties:
      Tags:
        - Key: Upper
          Value:
            'Fn::Transform':
             - Name: 'String'
               Parameters:
                 InputString: !Ref InputString
                 Operation: Upper

つまり以下のように変換される。

Parameters:
  InputString:
    Default: "This is a test input string"
    Type: String
Resources:
  S3Bucket:
    Type: "AWS::S3::Bucket"
    Properties:
      Tags:
        - Key: Upper
          Value: "THIS IS A TEST INPUT STRING"

Stringファンクションは他にも以下のようなものが定義されている。

  • Upper
  • Lower
  • Capitalize
  • Title
  • SwapCase
  • Strip
  • Replace
  • MaxLength

AWS CloudFormationの中での命令形プログラミング

命令形プログラミングの選択肢

以下のそれぞれをサンプルコードでデモンストレーション。

さいごに

CloudFormationはYAML, JSONによる宣言型なコードで複雑なプロビジョニングユースケースに対処できないかと思いきや、マクロを使うことで柔軟にテンプレートを定義することができます。

本セッションでは。同じようなリソースを複数定義するためにテンプレートが冗長になってしまっているとき、文字列の大文字小文字の変換や分割の処理を挟んだりとテンプレートをシンプルにするためにマクロがとても有効なことを、大量のサンプルコードで示してくれました。