Upgrade to Pro — share decks privately, control downloads, hide ads and more …

CloudFormation/SAMのススメ

 CloudFormation/SAMのススメ

CloudFormation と SAM を使って AWS の構築を自動化する方法とは?よくあるパターンは、テンプレート化して再利用性を高めましょう。

Eiji KOMINAMI / 小南英司

October 19, 2020
Tweet

More Decks by Eiji KOMINAMI / 小南英司

Other Decks in Technology

Transcript

  1. ⼩南 英司
    Eiji KOMINAMI
    JAWS KOBE & OSAKA
    CloudFormation & SAMのススメ
    - よくあるパターンは全部テンプレ化しちゃいましょう -

    View Slide

  2. 2
    ⾃⼰紹介
    ⼩南 英司(こみなみ えいじ)
    サーバサイドの構築 から アプリの実装 まで
    プリキュア応援アプリの開発/実装
    ⾼校野球速報アプリの開発/実装
    M-1グランプリ視聴者投票システムの構築
    ...など
    @eijikominami

    View Slide

  3. 3
    Agenda - CloudFormation & SAM の魅⼒を伝えたい
    利⽤するメリットと注意点
    既存のテンプレートの活⽤
    スタック構築Tips

    View Slide

  4. 利⽤するメリットと注意点
    4

    View Slide

  5. 5
    CloudFormationとは...
    AWSリソース群をテンプレート化し、
    迅速かつ適切な順序でプロビジョニング/管理できるサービス
    Resources:
    MyKinesis:
    Type: 'AWS::Kinesis::Stream'
    Properties:
    ShardCount: 1
    MyLambda:
    Type: 'AWS::Lambda::Function'
    Properties:
    Code:
    ZipFile: |
    import boto3
    def lambda_handler(event, context):
    records = decode_records(event)
    ……………………………………………
    Handler: index.lambda_handler
    Role: arn:aws:iam:0123456789:role/IAMRoleForLambda
    Runtime: python3.8
    MyLambdaEventSourceMapping:
    Type: 'AWS::Lambda::EventSourceMapping'
    Properties:
    EventSourceArn: !GetAtt MyKinesis.Arn
    FunctionName: !GetAtt MyLambda.Arn
    MyDynamoDBTable:
    Type: 'AWS::DynamoDB::Table'
    Properties:
    AttributeDefinitions:
    - AttributeName: user_id
    AttributeType: S
    KeySchema:
    - AttributeName: user_id
    KeyType: HASH
    ②ʼAWS CLI からデプロイ
    ①テンプレートファイルを作成
    ②マネージメントコンソールからデプロイ
    AWS Cloud
    Region
    Amazon Kinesis
    Lambda
    Amazon DynamoDB
    ③AWS上に⾃動で構築

    View Slide

  6. 6
    Serverless Application Modelとは...
    CloudFormationを拡張した
    サーバレスアプリケーション構築⽤フレームワーク
    Resources:
    MyKinesis:
    Type: 'AWS::Kinesis::Stream'
    Properties:
    ShardCount: 1
    MyLambda:
    Type: 'AWS::Serverless::Function'
    Properties:
    CodeUri: myLambda/
    Events:
    KinesisEvent:
    Properties:
    StartingPosition: TRIM_HORIZON
    Stream: !GetAtt MyKinesis.Arn
    Type: Kinesis
    MyDynamoDBTable:
    Type: 'AWS::DynamoDB::Table'
    Properties:
    AttributeDefinitions:
    - AttributeName: user_id
    AttributeType: S
    KeySchema:
    - AttributeName: user_id
    KeyType: HASH
    AWS Cloud
    Amazon Kinesis
    Lambda
    Amazon DynamoDB
    ③AWS上に⾃動で構築
    テンプレートファイル
    template.yaml
    aws-lambda-powertools
    ライブラリ設定ファイル
    requirements.txt
    import base64
    import json
    import boto3
    import os
    import copy
    from aws_lambda_powertools import Logger
    from aws_lambda_powertools import Tracer
    dynamodb = boto3.resource('dynamodb')
    table = dynamodb.Table('test')
    user_id_key_name = 'user_id'
    group_id_key_name = 'group_id'
    attributes_key_name = 'attributes'
    @logger.inject_lambda_context(log_event=True)
    @tracer.capture_lambda_handler
    def lambda_handler(event, context):
    records = decode_records(event)
    for record in records:
    user_id = record['data'][user_id_key_name]
    group_id = record['data'][group_id_key_name]
    attributes = copy.deepcopy(record['data'])
    del attributes[user_id_key_name]
    del attributes[group_id_key_name]
    update_data(user_id, group_id, attributes)
    Lambdaプログラム
    lambda_function.py
    Amazon S3
    ②SAM CLIを⽤いて
    ビルド/パッケージ化/デプロイ
    ①テンプレートファイルや
    Lambdaプログラム等を作成

    View Slide

  7. 7
    CloudFormation導⼊で何を変えたかったか
    マネージメントコンソールからの⾯倒な⼿動操作
    設定の抜け漏れや作業ミスの発⽣
    • 作業順序(サービスAを設定した後じゃないとサービスBが設定できない)
    • 正しく設定されているかを後から検証することが困難
    ⾼い作業コストと時間の浪費
    • 同じパターンのアーキテクチャを何度も⼿作業で構築(テスト環境/本番環境, 案件A/案件B...)
    複雑なリソース管理/運⽤
    ウィザード等で作成した過去のリソースの乱⽴
    ロールバックやスクラップ&ビルドが困難
    ⼿間が掛かる上に更新が滞る管理⽤のドキュメント
    システム構成の属⼈化
    作業者によって微妙に異なる設定

    View Slide

  8. 8
    CloudFormation/SAMのメリット①
    再利⽤可能なテンプレート
    複数環境への展開が容易
    • 変数のパラメータ化
    • 異なるリージョン, 異なるステージ, 複数のシステム/プロジェクトで利⽤できる
    バージョン管理可能
    安全で⾃動化されたデプロイ
    依存関係や実⾏順序を⾃動的に判断しデプロイ
    デプロイ失敗時にロールバックが可能
    スクラップ&ビルドが容易
    • CloudFormationスタックを削除すれば、関連するリソース全てが消える(⼀部例外あり)
    合理的かつ継続したデプロイプロセスを構築可能に

    View Slide

  9. 9
    CloudFormation/SAMのメリット②
    リソースのグループ化
    テンプレートの分割とネストされたスタック
    • 複数のCloudFormationスタックを組み合わせてデプロイが可能
    関連するリソースを同時に作成
    • リソースに権限を付与 : Service-Linked ロール, IAM ロール, S3バケットポリシー
    • ログの出⼒ : S3バケット, CloudWatch Logs
    • リソースの監視 : CloudWatch アラーム, EventBridge, SNS
    サーバレスアプリケーションを迅速に構築(SAM)
    テンプレートとLambdaプログラムを⼀括管理
    サーバレスサービスに特化した機能
    • 簡略化したテンプレート構⽂の提供
    • ローカル開発環境にLambdaの実⾏環境を構築可能

    View Slide

  10. 10
    CloudFormation/SAMの注意点①
    未対応のサービスあり、挙動が怪しい場合も。
    今後のロードマップや機能改善等の予定は以下を参照
    • CloudFormation Public Coverage Roadmap
    https://github.com/aws-cloudformation/aws-cloudformation-coverage-roadmap
    • AWS SAM - Issue
    https://github.com/aws/aws-sam-cli/issues
    未対応サービスの例
    • CloudFront の Origin Failover
    • DynamoDB の Global Tables
    • ローンチされたばかりのサービスや新機能 ...など
    Issueの例
    • EC2インスタンスに付けたタグが同時に作成したEBSには付与されない
    • EventBridgeのイベントパターン内でNumber値を指定すると勝⼿にStringに変換されてしまう
    • ネストされたスタック内では sam build が実⾏されない
    ...など

    View Slide

  11. 11
    CloudFormation/SAMの注意点②
    CloudFormationの制限
    1つのテンプレートに含むことのできるリソース数は200まで
    • 上限を超える場合は、テンプレートの分割を検討
    1つのテンプレートに含むことのできるパラメータ数は60まで
    • 変数を⽤いて複雑な処理を⾏う場合は、Mappingsセクションの活⽤も検討
    1つのテンプレートの本⽂サイズは51,200バイトまで
    • 上限を超える場合は、テンプレートをS3にアップロードした上でデプロイ
    1つのアカウントで作成できるスタック数は200まで
    • 上限を超える場合は、上限緩和申請も検討
    作成するAWSサービスの制限
    • オブジェクトを全て削除しないとS3バケットを削除できない
    – DeletionPolicy: Retain を指定してスタック削除時にバケットを保持
    • 同時に作成できるDynamoDBテーブル数の上限
    • Detective は GuardDuty 有効化から 48時間経過後に有効化可能 ...など

    View Slide

  12. 12
    CloudFormation/SAMの注意点③
    その他の注意点
    四則演算やforループなどは使⽤できない
    スタック内のリソースの⼿動による設定変更(ドリフト)
    • ドリフト検出機能を⽤いて設定変更を検知可能
    • 正しいテンプレートを⽤いて再デプロイしてもドリフトは解消されない
    • ⼿動であるべき姿に戻す or スタックから当該リソースの切り離しと再度インポート
    Parametersセクション
    • Default は初回作成時のみ有効
    • Description を⽇本語にすると⽂字化け
    ➡ CDK(AWS Cloud Development Kit)の利⽤を検討

    View Slide

  13. 既存のテンプレートの活⽤
    13

    View Slide

  14. 14
    ⾃分でテンプレートを作成しなくても⼤丈夫
    公開されている既存のテンプレートを活⽤しよう
    Webページからスタック起動URLをクリック
    Serverless Application Repository からアプリケーションを選択
    マネージメントコンソール
    (CloudFormation)が⾃動で起動
    デプロイ
    CloudFormation
    Stack
    Template
    マネージメントコンソール
    (Lambda)が⾃動で起動
    Template
    デプロイ
    CloudFormation
    Stack

    View Slide

  15. 15
    セキュリティサービスの⼀括有効化
    AWSアカウント作成時に有効化すべきサービス群
    Amazon Inspector
    Amazon GuardDuty
    AWS Config
    AWS CloudTrail
    AWS Security Hub
    Amazon Detective
    AWS Cloud
    Tokyo (ap-northeast-1)
    security stack
    S3
    Bucket
    AWS Security Hub
    AWS CloudTrail
    AWS Config
    Amazon GuardDuty
    Amazon Inspector
    Alarm
    Amazon SNS
    AWS Personal Health
    IAM Role
    ServiceLinkedRole
    Amazon EventBridge
    IAM Access Analyzer
    Amazon
    CloudWatch Events
    Amazon CloudWatch
    Logs
    S3
    Bucket
    Documents
    S3
    Bucket
    Lambda
    Amazon Detective
    https://git.io/JTWiB
    GitHub
    eijikominami/aws-cloudformation-templates

    View Slide

  16. 16
    静的ウェブサイトのホスティング
    CloudFront + S3 + CloudWatch Synthetics
    AWS WAF 設定可能
    OAIによるアクセス制限
    ログの有効化
    外形監視
    https://git.io/JTWPW
    GitHub
    eijikominami/aws-cloudformation-templates
    AWS Cloud
    Tokyo (ap-northeast-1)
    static-website-hosting-with-ssl stack
    Amazon S3
    Amazon CloudFront
    Amazon S3
    access log
    AWS WAF
    Origin Access
    Identity
    Amazon CloudWatch
    Synthetics
    AWS Lambda
    Amazon S3
    Amazon CloudWatch
    Logs
    log
    data
    synthetics monitoring
    Amazon CloudWatch
    Alarm

    View Slide

  17. 17
    CloudWatchアラームの設定
    頻繁に使⽤するサービスのアラーム設定をテンプレート化
    そのままデプロイ
    ⾃分のテンプレートに埋め込み
    マネージメントコンソール
    (Lambda)が⾃動で起動
    Template
    デプロイ
    CloudFormation
    Stack
    https://amzn.to/2Hk4CAf
    Serverless Application Repository
    https://serverlessrepo.aws.amazon.com/applications
    AWS Serverless
    Application Repository
    Resources:
    AlarmEC2:
    Type: 'AWS::Serverless::Application'
    Properties:
    Location:
    ApplicationId: arn:aws:serverlessrepo:us-east-
    1:172664222583:applications/cloudwatch-alarm-about-ec2
    SemanticVersion: 1.1.6
    Parameters:
    CPUUtilizationThreshold: 80
    CustomAlarmName: !Ref AWS::StackName
    SNSTopicArn: !Ref SNSForDeploymentArn
    EC2:
    Type: 'AWS::EC2::Instance'
    Properties:
    Template
    デプロイ
    リソースの⼀部として埋め込み
    CloudWatchアラーム
    ⾯倒なアラーム設定を簡単セットアップ

    View Slide

  18. スタック構築Tips
    18

    View Slide

  19. 19
    便利なコマンド/ツール群
    cfn-lint
    テンプレートのプロパティとその値をチェック(Linter)
    複数のIDE向けプラグインあり
    cfn-guard
    テンプレートのポリシーコンプライアンスをチェック
    事前に作成したルールに適合するかチェック
    2020/10/1 GA
    $ cfn-lint template.yaml
    W3005 Obsolete DependsOn on resource (IAMRoleForLambda), dependency already enforced by a "Fn:GetAtt" at Resources/LambdaPutData/Properties/Role/Fn::GetAtt
    template.yaml:405:11
    https://git.io/JU0pI
    https://git.io/JT8cf
    $ cfn-guard check -t template.yaml -r default.ruleset
    [LambdaGetData] failed because [Runtime] is [python3.7] and Lambda runtime requires Python 3.8
    Number of failures: 2
    AWS::Lambda::Function Runtime == Python3.8 << Lambda runtime requires Python 3.8
    事前に作成したルール

    View Slide

  20. 20
    CodePipelineを⽤いたビルド&デプロイ
    テンプレートの更新をトリガに⾃動でデプロイを実⾏
    マネージメントコンソールにログインすることなく⾃動で全てが完了
    テンプレート コミット ビルド/テスト デプロイ
    パイプライン
    git push
    Cloudformation テンプレートの場合
    1. cfn-lint の実⾏
    2. cfn-guard の実⾏
    SAM テンプレートの場合
    1. cfn-lint の実⾏
    2. cfn-guard の実⾏
    3. sam-validate の実⾏
    4. sam-build の実⾏
    5. sam-package の実⾏

    View Slide

  21. CodePipelineを⽤いたビルド&デプロイ
    テンプレートのプッシュをトリガにデプロイを⾃動で実⾏
    マネージメントコンソールにログインすることなく⾃動で全てが完了

    View Slide

  22. 22
    モジュラーアプローチ
    複数のテンプレートに分割し再利⽤性を⾼める
    AWS Cloud
    Tokyo (ap-northeast-1)
    security stack
    S3
    Bucket
    AWS Security Hub
    AWS CloudTrail
    AWS Config
    Amazon GuardDuty
    Amazon Inspector
    Alarm
    Amazon SNS
    AWS Personal Health
    IAM Role
    ServiceLinkedRole
    Amazon EventBridge
    IAM Access Analyzer
    Amazon
    CloudWatch Events
    Amazon CloudWatch
    Logs
    S3
    Bucket
    Documents
    S3
    Bucket
    Lambda
    Amazon Detective
    ネストされたスタックの利⽤
    AWS::Include の利⽤
    親テンプレート
    ネストされたテンプレート
    ネストされたテンプレート
    親テンプレート
    挿⼊されたテンプレート
    ネストされたテンプレートは
    変更セットを確認できない

    View Slide

  23. 複数のテンプレートに分割し再利⽤性を⾼める
    detective.yaml
    securityhub.yaml
    inspector.yaml
    iam.yaml
    guardduty.yaml
    config.yaml cloudtrail.yaml
    23
    モジュラーアプローチ
    AWS Cloud
    Tokyo (ap-northeast-1)
    Amazon SNS
    AWS Personal Health
    IAM Role
    ServiceLinkedRole
    Amazon EventBridge
    ネストされたスタックの利⽤
    AWS::Include の利⽤
    親テンプレート
    ネストされたテンプレート
    ネストされたテンプレート
    親テンプレート
    挿⼊されたテンプレート
    ネストされたテンプレートは
    変更セットを確認できない

    View Slide

  24. 24
    Enjoy CloudFormation and SAM!

    View Slide

  25. Appendix
    25

    View Slide

  26. 26
    テンプレートリファレンス(CloudFormation)
    https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/template-reference.html

    View Slide

  27. 27
    テンプレートリファレンス(SAM)
    https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/sam-specification-resources-and-properties.html

    View Slide

  28. 28
    CloudFormation Sample Templates
    https://github.com/awslabs/aws-cloudformation-templates

    View Slide

  29. 29
    AWS Quick Start
    https://github.com/aws-quickstart

    View Slide

  30. 30
    AWS CloudFormation Templates
    https://github.com/eijikominami/aws-cloudformation-templates/

    View Slide

  31. 31
    buildspec ファイル for SAM テンプレート
    version: 0.2
    phases:
    install:
    runtime-versions:
    python: 3.8
    commands:
    - pip install -U pip
    - pip install -U cfn-lint
    # Use the latest version
    - pip install -U awscli
    # for Lambda
    - pip install -U aws-sam-cli
    - pip install -U boto3
    # for Lambda Powertools
    - pip install -U aws-lambda-powertools
    # for cloudformation-guard
    - wget https://github.com/aws-cloudformation/cloudformation-guard/releases/download/1.0.0/cfn-guard-linux-1.0.0.tar.gz
    - tar -xvf cfn-guard-linux-1.0.0.tar.gz
    pre_build:
    commands:
    - find ./ -type f -name "*.yaml" | xargs --no-run-if-empty cfn-lint
    - find ./ -type f -name "*.yaml" | xargs -I {} ./cfn-guard-linux/cfn-guard check -r ./security-standards.ruleset -t {}
    build:
    commands:
    - sam validate --template ${TEMPLATE_FILE_PATH}template.yaml
    - sam build --template ${TEMPLATE_FILE_PATH}template.yaml
    - sam package --template-file .aws-sam/build/template.yaml --s3-bucket ${PACKAGE_BUCKET} --output-template-file packaged.yaml
    artifacts:
    files:
    - packaged.yaml
    https://git.io/JT8z1
    GitHub
    eijikominami/aws-cloudformation-templates

    View Slide

  32. 32
    cfn-guard ルールファイルの例
    AWS Security Hub Security Standards に⼀部準拠
    AWS::CloudTrail::Trail IsMultiRegionTrail == true << CloudTrail trails should cover all regions
    AWS::CloudTrail::Trail EnableLogFileValidation == true << CloudTrail file validation should be enabled
    AWS::CloudTrail::Trail CloudWatchLogsLogGroupArn == /.*/ << CloudTrail trails should be integrated with Amazon CloudWatch Logs
    AWS::CloudTrail::Trail KMSKeyId == /.*/ << CloudTrail trails should encrypt the logs delivered by it.
    AWS::DMS::ReplicationInstance PubliclyAccessible == false << DMS instance should not be publicly accessible
    AWS::EC2::Volume Encrypted == true << EC2 volumes should be encrypted
    AWS::EC2::Instance BlockDeviceMappings.*.Ebs.Encrypted == true << EC2 volumes should be encrypted
    AWS::EC2::SecurityGroup WHEN SecurityGroupIngress.*.ToPort == 22 CHECK SecurityGroupIngress.*.CidrIp != 0.0.0.0/0
    AWS::EC2::SecurityGroup WHEN SecurityGroupIngress.*.ToPort == 3389 CHECK SecurityGroupIngress.*.CidrIp != 0.0.0.0/0
    AWS::Elasticsearch::Domain EncryptionAtRestOptions.Enabled == true << Domain encryption should be enabled
    AWS::GuardDuty::Detector Enable == true << Detector should be enabled
    AWS::IAM::Role Policies.*.PolicyDocument.Statement.*.Action.* != ¥* << IAM Role should not allow full "*" administrative privileges
    AWS::KMS::Key EnableKeyRotation == true << Key rotation should be enabled
    AWS::RDS::DBInstance PubliclyAccessible == false << Databasae should not be publicly accessible
    AWS::RDS::DBInstance StorageEncrypted == true << Storage encryption should be enabled
    AWS::S3::Bucket BucketEncryption.ServerSideEncryptionConfiguration == /.*/ << S3 bucket encryption should be enabled
    AWS::SageMaker::NotebookInstance DirectInternetAccess == Disabled << Notebooks should not have direct internet access
    https://git.io/JT8g4
    GitHub
    eijikominami/aws-cloudformation-templates

    View Slide