LoginSignup
8
4

More than 3 years have passed since last update.

EC2 Image Builderで作ったAMI IDを動的に取得して、AutoScalingグループの起動設定を更新する

Last updated at Posted at 2019-12-14

この記事はZOZOテクノロジーズ #2 Advent Calendar 2019 14日目の記事になります。
昨日は、@_sa_chi_03さんの「ZOZOTOWNのメールマガジンの仕組みについて」でした。

まえがき

ZOZOテクノロジーズ SREチームのテックリード光野と申します。普段はAWSを使って、より安全でより手がかからず、お金もかからない。でも速い。そんないい感じのネットワーク構築に邁進しています。

さて、この記事ではAWS re:Invent 2019で発表されたEC2 Image Builderを扱います。EC2 Image Builderは、指定したレシピを元にEC2のカスタムイメージを作成することができるサービスです。任意もしくは定期的なタイミングでAMIを更新することができます。

AutoScalingグループと合わせれば、毎日最新のセキュリティパッチのあたったAMIを作っておいて、インスタンス入れ替え、なんて事が簡単にできます。幸せです。

この投稿では、EC2 Image Builderで作成したAMI IDを機械的に参照できるよう工夫してみたいと思います。

本文

目標:CloudFormationテンプレートで動的参照

弊社ではインフラの管理にCloudFormationを多用しています。
例えば、CloudFormationでAutoScalingの起動設定を作成する場合、次のように記述します。

AWSTemplateFormatVersion: 2010-09-09
Resources:
  AutoScalingLaunchConfiguration:
    Type: 'AWS::AutoScaling::LaunchConfiguration'
    Properties:
      ImageId: 'ami-0ab292e52c1d6ac8c' # Ubuntu 18.04 LTS
      InstanceType: 'm5.large'

  # 最低限の記述です。実際にはセキュリティグループなどが必要でしょう。。

ここでは、ImageIdを可変にし、CloudFormation実行のタイミングで、常にImage Builderが作成する最新のAMI IDを参照するようにします。

組み合わせ

CloudFormationではSSMのParameter Storeに登録した値を動的に参照することができます。

AWSTemplateFormatVersion: 2010-09-09
Resources:
  AutoScalingLaunchConfiguration:
    Type: 'AWS::AutoScaling::LaunchConfiguration'
    Properties:
      ImageId: "{{resolve:ssm:oreore-image-with-eib:1}}"
      InstanceType: 'm5.large'

or

AWSTemplateFormatVersion: 2010-09-09
Parameters:
  AMI:
    Type: 'AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>'
    Default: 'oreore-image-with-eib'
Resources:
  AutoScalingLaunchConfiguration:
    Type: 'AWS::AutoScaling::LaunchConfiguration'
    Properties:
      ImageId: !Ref AMI
      InstanceType: 'm5.large'

パラメータからの指定であれば、バージョン番号の入力を省略できるため、常に最新〜という指定が叶えられそうです。他方、EC2 Image BuilderはSNSに対応しているため、SNS経由でなんとかParameter Storeまで値を届けられそうな気がします。

作ったもの

image.png

ここではUserが手動でCloudFormationを更新します。

Lambdaに設定したスクリプトは以下のとおりです。Rubyが好きなので.rbです。

# coding: utf-8
require 'json'
require 'aws-sdk-ssm'

def lambda_handler(event:, context:)
    message = JSON.parse(event['Records'][0]['Sns']['Message'])
    puts message # debug用
    client = Aws::SSM::Client.new
    resp = client.put_parameter({
                                  name: 'oreore-image-with-eib',
                                  value: message['outputResources']['amis'][0]['image'],
                                  type: 'String',
                                  overwrite: true
                                })

    { statusCode: 200, body: JSON.generate('OK') }
end

CloudFormartionのテンプレートは上で掲載したものを使います。

AWSTemplateFormatVersion: 2010-09-09
Parameters:
  AMI:
    Type: 'AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>'
    Default: 'oreore-image-with-eib'
Resources:
  AutoScalingLaunchConfiguration:
    Type: 'AWS::AutoScaling::LaunchConfiguration'
    Properties:
      ImageId: !Ref AMI
      InstanceType: 'm5.large'

結果

EC2 Image Builder
image.png

SSM Parameter Store
image.png

CloudFormation
image.png

AutoScaling
image.png

しっかり反映されました!

あとがき

EC2 Image BuilderからParameter Storeを通じて、動的に最新のAMIを得ることができました。
AWSのサービスは一つ新しいものが増えると、組み合わせの楽しみがどんどん広がるので目が離せません。

CloudFormationテンプレートになってさえいればCodePipelineなどで自動化もできますし、これまで抱えていた「カスタムAMIがあればもっと効率的に色々できるけど、運用するのが面倒くさいんだよな・・・」という悩みが解決できそうでとてもワクワクしています。

明日は@murs313さんの記事になります。お楽しみに!

8
4
1

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
8
4