#eventpattern
Explore tagged Tumblr posts
Video
So proud of my Event System on Unity. So much work, a combination of ScriptableObjects and CustomInspector programming but now many things can be done using only the editor. Worth it! Congrats to _Kiusep3D_ for the 3D models as always! . . Fiero del mio sistema ad eventi in Unity. Così tanto lavoro, una combinazione di ScriptableObjects e Inspector personalizzato ma ora moltissime cose possono essere fatte usando solo l'editor. Ne è valsa la pena! Congratulazioni come sempre a _Kiusep3D_ per i modelli 3D! #cwsgaming #gamedevelopment #softwaredeveloper #mobiledeveloper #developer #csharp #visualstudio #unity #scriptableobjects #eventpattern #android #indiegaming #indieitalia #indie #tutorial (presso Piazza Patrioti) https://www.instagram.com/p/B3eWRudlwa5/?igshid=1dp0evkevaisj
#cwsgaming#gamedevelopment#softwaredeveloper#mobiledeveloper#developer#csharp#visualstudio#unity#scriptableobjects#eventpattern#android#indiegaming#indieitalia#indie#tutorial
0 notes
Photo
Amazon CloudWatch EventsのイベントルールでターゲットをAmazon SQSにしてAWS Lambdaでイベントソースにして処理するAWS CloudFormationのテンプレートをつくってみた https://ift.tt/2VCgm4X
Amazon CloudWatch EventsのイベントルールでターゲットをAmazon SQSにしてAWS Lambdaでイベントソースにして処理するAWS CloudFormationのテンプレートをつくってみた
AWSマネジメントコンソールからだと簡単に設定できましたが、AWS CloudFormationのテンプレート化するのにいろいろとハマったのでメモ。
リソース
必要最低限となる構成はこんな感じになりました。
��用するサービスは以下になります。
Amazon S3
AWS CloudTrail
Amazon CloudWatch Events
Amazon SQS
AWS Lambda
AWS CloudFormation(リソース管理用)
ポイント
先にポイントをいくつかあげてみます。 完成形のテンプレートはこのあとにおいてます。
Amazon S3のバケットを複数用意する
Amazon CloudWatch EventsでAmazon S3のイベントを扱うのにAWS CloudTrailも必要になります。
Amazon S3 ソースの CloudWatch イベント ルールを作成する (コンソール) – CodePipeline https://docs.aws.amazon.com/ja_jp/codepipeline/latest/userguide/create-cloudtrail-S3-source-console.html
AWS CloudTrail 証跡を作成にはログファイルを出力するAmazon S3のバケットがいりますが、これをイベントを扱いたいバケットにしてしまうと。。。あとはわかりますね。無限ループに陥ります。
また、AWS CloudTrailでログを出力しない設定にすると、イベントが発火しませんでした。
AWS CloudTrailのログファイルを保存するキー名は固定
ログファイルを保存する先はバケット名/AWSLogs/AWSアカウントID/*と指定する必要があります。
テンプレート抜粋
CloudTrailBucketPolicy: Type: AWS::S3::BucketPolicy Properties: Bucket: !Ref OutputBucket PolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Principal: Service: cloudtrail.amazonaws.com Action: s3:GetBucketAcl Resource: !GetAtt OutputBucket.Arn - Effect: Allow Principal: Service: cloudtrail.amazonaws.com Action: s3:PutObject Resource: !Join - "" - - !GetAtt OutputBucket.Arn - "/AWSLogs/" - !Ref "AWS::AccountId" - "/*" Condition: StringEquals: s3:x-amz-acl: bucket-owner-full-control
AWSLogsを別名にしてみたらAWS CloudFormationのスタック作成でエラーになりました。
Incorrect S3 bucket policy is detected for bucket: <ProjectName>-output (Service: AWSCloudTrail; Status Code: 400; Error Code: InsufficientS3BucketPolicyException; Request ID: 3a9a7575-5226-4f19-b62a-737e87acc9b8)
AWSアカウントIDを指定せずにバケット名/AWSLogs/* とするとイベントが発火しませんでした。
AWS Lambda関数でメッセージの削除はしなくて良い
AWS Lambda関数でAmazon SQSを自前でポーリングして処理する場合、正常に処理が完了したらメッセージを削除する必要があったのですが、イベントソースにするとそれも必要なくなるみたいです。
AWS LambdaがSQSをイベントソースとしてサポートしました! | Developers.IO https://dev.classmethod.jp/articles/aws-lambda-support-sqs-event-source/
次に関数コードを入力します。サンプルの関数はチュートリアル通り以下の内容として保存します。ここでSQSメッセージの削除処理を入れていないことが分かります。
最初はチュートリアルのサンプルだからかな?と思ってましたが実際に動作させると正常終了時にメッセージが勝手に削除されました。こりゃ便利。
なので実装はキューの情報からS3バケットに保存された���ブジェクトのキーを取得して出力しているだけです。
テンプレート抜粋
ReceiveQueFunction: Type: AWS::Lambda::Function Properties: FunctionName: !Sub "${ProjectName}-ReceiveQueFunction" Handler: "index.lambda_handler" Role: !GetAtt LambdaExecutionRole.Arn Code: ZipFile: | from __future__ import print_function import json import os import boto3 def lambda_handler(event, context): for record in event["Records"]: requestParameters = json.loads(record["body"])["detail"]["requestParameters"] print(str(requestParameters)) Runtime: "python3.7" Timeout: "60" ReservedConcurrentExecutions: 3
AWS Lambda関数の同時実行数を調整する
上記テンプレートでReservedConcurrentExecutions: 3と同時実行数を指定していますが、こちらはケース・バイ・ケースで指定する必要があります。
AWS::Lambda::Function – AWS CloudFormation https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html#cfn-lambda-function-reservedconcurrentexecutions
大量のキューをさばく必要がある場合、同時実行数の制限まで全力でポーリングしてくれます。 なので同時実行数を指定していないと、標準設定の1,000まで同時実行してくれます。アカウントの同時実行数は最大1,000となりますので、もし他にも関数がある場合、影響する可能性があるのでご注意ください。
イベントルールのターゲット指定でバケット名やキーがプレフィックス指定できる
こちらは下記記事をご参考ください。地味に便利です。
Amazon CloudWatch EventsのルールでAmazon S3のキーをプレフィックス指定できた – Qiita https://cloudpack.media/52397
今回はキーをprefix: hoge/とすることでs3://バケット名/hoge/ 配下にオブジェクトがPUTされた場合にイベントが発火する設定にしました。
テンプレート抜粋
CloudWatchEventRule: Type: AWS::Events::Rule Properties: Name: !Sub "${ProjectName}-EventRule" EventPattern: source: - aws.s3 detail-type: - "AWS API Call via CloudTrail" detail: eventSource: - s3.amazonaws.com eventName: - CopyObject - PutObject - CompleteMultipartUpload requestParameters: bucketName: - !Ref InputBucket key: - prefix: hoge/ Targets: - Arn: !GetAtt S3EventQueue.Arn Id: !Sub "${ProjectName}-TarfgetQueue"
SQSのキューポリシーを設定する
今回、一番ドハマリしました。 キューポリシーがなくてもリソースは作成できるのですが、それだとバケットにオブジェクトをPUTしてもイベントが発火しませんでした。AWSのドキュメントを漁ってみてもそれらしき記述が見当たらずでしたが、下記のフォーラムに情報があり知ることができました。
AWS Developer Forums: CloudWatch event rule not sending to … https://forums.aws.amazon.com/message.jspa?messageID=742808
AWSマネジメントコンソールでぽちぽちと設定する場合にはポリシーを勝手に作成してくれるので、テンプレート化する際にハマりやすいポイントだったみたいです。
テンプレート抜粋
SQSQueuePolicy: Type: AWS::SQS::QueuePolicy Properties: PolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Principal: AWS: "*" Action: - "sqs:SendMessage" Resource: - !GetAtt S3EventQueue.Arn Condition: ArnEquals: "aws:SourceArn": !GetAtt CloudWatchEventRule.Arn Queues: - Ref: S3EventQueue
テンプレート
ちょっと長いですがテンプレートになります。
AWSTemplateFormatVersion: "2010-09-09" Parameters: ProjectName: Type: String Default: "<お好みで>" Resources: InputBucket: Type: AWS::S3::Bucket Properties: BucketName: !Sub "${ProjectName}-input" AccessControl: Private PublicAccessBlockConfiguration: BlockPublicAcls: True BlockPublicPolicy: True IgnorePublicAcls: True RestrictPublicBuckets: True OutputBucket: Type: AWS::S3::Bucket Properties: BucketName: !Sub "${ProjectName}-output" AccessControl: Private PublicAccessBlockConfiguration: BlockPublicAcls: True BlockPublicPolicy: True IgnorePublicAcls: True RestrictPublicBuckets: True S3EventQueue: Type: AWS::SQS::Queue Properties: DelaySeconds: 0 VisibilityTimeout: 360 LambdaExecutionRole: Type: AWS::IAM::Role Properties: RoleName: !Sub "${ProjectName}-LambdaRolePolicy" AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Principal: Service: lambda.amazonaws.com Action: "sts:AssumeRole" Path: "/" ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole Policies: - PolicyName: !Sub "${ProjectName}-LambdaRolePolices" PolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Action: - s3:* Resource: "*" - PolicyName: !Sub "${ProjectName}-LambdaRoleSQSPolices" PolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Action: - sqs:ReceiveMessage - sqs:DeleteMessage - sqs:GetQueueAttributes - sqs:ChangeMessageVisibility Resource: !GetAtt S3EventQueue.Arn ReceiveQueFunction: Type: AWS::Lambda::Function Properties: FunctionName: !Sub "${ProjectName}-ReceiveQueFunction" Handler: "index.lambda_handler" Role: !GetAtt LambdaExecutionRole.Arn Code: ZipFile: | from __future__ import print_function import json import os import boto3 def lambda_handler(event, context): for record in event["Records"]: requestParameters = json.loads(record["body"])["detail"]["requestParameters"] print(str(requestParameters)) Runtime: "python3.7" Timeout: "60" ReservedConcurrentExecutions: 3 CloudTrailBucketPolicy: Type: AWS::S3::BucketPolicy Properties: Bucket: !Ref OutputBucket PolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Principal: Service: cloudtrail.amazonaws.com Action: s3:GetBucketAcl Resource: !GetAtt OutputBucket.Arn - Effect: Allow Principal: Service: cloudtrail.amazonaws.com Action: s3:PutObject Resource: !Join - "" - - !GetAtt OutputBucket.Arn - "/AWSLogs/" - !Ref "AWS::AccountId" - "/*" Condition: StringEquals: s3:x-amz-acl: bucket-owner-full-control CloudTrail: Type: AWS::CloudTrail::Trail DependsOn: - CloudTrailBucketPolicy Properties: TrailName: !Sub "${ProjectName}-Trail" S3BucketName: !Ref OutputBucket EventSelectors: - DataResources: - Type: AWS::S3::Object Values: - Fn::Sub: - "${InputBucketArn}/" - InputBucketArn: !GetAtt InputBucket.Arn ReadWriteType: WriteOnly IncludeManagementEvents: false IncludeGlobalServiceEvents: true IsLogging: true IsMultiRegionTrail: false CloudWatchEventRule: Type: AWS::Events::Rule Properties: Name: !Sub "${ProjectName}-EventRule" EventPattern: source: - aws.s3 detail-type: - "AWS API Call via CloudTrail" detail: eventSource: - s3.amazonaws.com eventName: - CopyObject - PutObject - CompleteMultipartUpload requestParameters: bucketName: - !Ref InputBucket key: - prefix: hoge/ Targets: - Arn: !GetAtt S3EventQueue.Arn Id: !Sub "${ProjectName}-TarfgetQueue" SQSQueuePolicy: Type: AWS::SQS::QueuePolicy Properties: PolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Principal: AWS: "*" Action: - "sqs:SendMessage" Resource: - !GetAtt S3EventQueue.Arn Condition: ArnEquals: "aws:SourceArn": !GetAtt CloudWatchEventRule.Arn Queues: - Ref: S3EventQueue LambdaFunctionEventSourceMapping: Type: AWS::Lambda::EventSourceMapping DependsOn: - S3EventQueue - ReceiveQueFunction Properties: BatchSize: 10 Enabled: true EventSourceArn: !GetAtt S3EventQueue.Arn FunctionName: !GetAtt ReceiveQueFunction.Arn
スタック作成して動かしてみる
最後にざくっと検証してみます。
# リソースを作成 > cd テンプレートファイルがある場所 > aws cloudformation create-stack \ --stack-name <お好みで> \ --template-body file://<テンプレートファイル名> \ --capabilities CAPABILITY_NAMED_IAM \ --region <お好みの> \ --parameters '[ { "ParameterKey": "ProjectName", "ParameterValue": "<お好み��>" } ]' { "StackId": "arn:aws:cloudformation:<お好みのリージョン>:xxxxxxxxxxxx:stack/<お好みのスタック名>/18686480-6f21-11ea-bcf3-020de04cec9a" } # ファイルをアップロード > touch hoge.txt # hogeキー配下にアップロードしない > aws s3 cp hoge.txt s3://<ProjectName>-input/ upload: ./hoge.txt to s3://<ProjectName>-input/hoge/hoge.txt > aws s3 cp hoge.txt s3://<ProjectName>-input/hoge/ upload: ./hoge.txt to s3://<ProjectName>-input/hoge/hoge.txt > aws s3 ls --recursive s3://<ProjectName>-input 2020-03-26 06:28:03 0 hoge.txt 2020-03-26 06:26:12 0 hoge/hoge.txt # Lambda関数のログを確認 > aws logs get-log-events \ --region <お好みのリージョン> \ --log-group-name '/aws/lambda/<ProjectName>-ReceiveQueFunction' \ --log-stream-name '2020/03/26/[$LATEST]ae8735ef9a1c46c38ab241f23a26b384' \ --query "events[].[message]" \ --output text START RequestId: 10f98cf9-c39b-531b-9514-da0f8ea72a42 Version: $LATEST {'bucketName': '<ProjectName>-input', 'Host': '<ProjectName>-input.s3.<お好みのリージョン>.amazonaws.com', 'key': 'hoge/hoge.txt'} END RequestId: 10f98cf9-c39b-531b-9514-da0f8ea72a42 REPORT RequestId: 10f98cf9-c39b-531b-9514-da0f8ea72a42 Duration: 1.85 ms Billed Duration: 100 ms Memory Size: 128 MB Max Memory Used: 69 MB Init Duration: 275.58 ms
やったぜ。
まとめ
AWSマネジメントコンソールで設定すると比較的かんたんに設定できるのですが、CFnのテンプレート化する際にはそこそこ大変でしたが、良い知見を得ることができました。
参考
Amazon S3 ソースの CloudWatch イベント ルールを作成する (コンソール) – CodePipeline https://docs.aws.amazon.com/ja_jp/codepipeline/latest/userguide/create-cloudtrail-S3-source-console.html
AWS LambdaがSQSをイベントソースとしてサポートしました! | Developers.IO https://dev.classmethod.jp/articles/aws-lambda-support-sqs-event-source/
AWS::Lambda::Function – AWS CloudFormation https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html#cfn-lambda-function-reservedconcurrentexecutions
Amazon CloudWatch EventsのルールでAmazon S3のキーをプレフィックス指定できた – Qiita https://cloudpack.media/52397
AWS Developer Forums: CloudWatch event rule not sending to … https://forums.aws.amazon.com/message.jspa?messageID=742808
Amazon CloudWatch LogsのログをAWS CLIでいい感じに取得する – Qiita https://cloudpack.media/50416
AWS CLIを使ってAWS Lambdaのログ取得時に注意したいこと | Developers.IO https://dev.classmethod.jp/articles/note-log-of-lambda-using-awscli/
元記事はこちら
「Amazon CloudWatch EventsのイベントルールでターゲットをAmazon SQSにしてAWS Lambdaでイベントソースにして処理するAWS CloudFormationのテンプレートをつくってみた」
April 13, 2020 at 04:00PM
0 notes
Video
So proud of my Event Pattern on Unity. So much work, a combination of ScriptableObjects and CustomInspector programming but now many things can be done using only the editor. Worth it! Congrats to _Kiusep3D_ for the 3D models as always! . . . Fiero del mio sistema ad eventi in Unity. Così tanto lavoro, una combinazione di ScriptableObjects e InspectorPersonalizato ma ora moltissime cose possono essere fatte usando solo l'editor. Ne è valsa la pena! Congratulazioni come sempre a _Kiusep3D_ per i modelli 3D! #cwsgaming #gamedevelopment #softwaredeveloper #mobiledeveloper #developer #csharp #visualstudio #unity #scriptableobjects #eventpattern #android #indiegaming #indieitalia #indie #tutorial https://www.instagram.com/p/B3eVzPwogAr/?igshid=kt59cuvkc2od
#cwsgaming#gamedevelopment#softwaredeveloper#mobiledeveloper#developer#csharp#visualstudio#unity#scriptableobjects#eventpattern#android#indiegaming#indieitalia#indie#tutorial
0 notes
Photo

AWSでGCEぽく、Lambdaでインスタンス起動時にDNS自動登録する http://bit.ly/2CZdsic
GCEでインスタンスを起動するときに、先にホスト名を決める必要があります。AutoScaling等の場合は、勝手にプリフィックスがついて名前被りを避けます。これによりAWSのようなIPアドレスベースの使いにくいFQDN(Internal)ではなく、直感的な名前で名前解決ができます。 AWSでもUserData,cloud-initによる機構などで実現することは可能ですが、私の直感として「そんなことはインフラだけで完結しろよ!」と思うので、GCEぽい動きをするLambdaを約2年前に作成していたので、今更蔵出し公開します。
aws lambdaで ec2の local ipを r53へ自動登録. Contribute to h-imaoka/aws-lambda-internaldns development by creating an account on GitHub. h-imaoka/aws-lambda-internaldns - GitHub
github.com
使いたいだけの人は使い方はすべてGitHub上に書いていますので、そちらを見てください。

このエントリでは、今回蔵出ししたこのツールを通して serverlessフレームワークの歴史と使い方について振り返り書きます。書きたいのはこっちですが、タイトル詐欺ではないので許して。
その前にこのツールの意義
前述の通り、このツールは2年前に作成してい��した。現在と状況が違う点としては、Route53 auto naming (service discovery) が今は存在しますが、一応このツールとは競合していないです。
R53 auto naming との違い
結論から言うと、やっぱり ecs (eksも?) service discoveryとして使うべきものであり、名前解決が面倒だから楽したいという意図で使うべきではないと、一度使った人なら思うはず。
service discovery = サービス(web とか smtp とか)の生死を名前解決に反映させる
本ツール = ただ、内部ホスト間の名前解決を楽したい
のように目的が根本的に違います。そのためservice discovery は見た目こそroute53でHostedZoneも見えるのですが、そのHostedZoneがAWS管轄となり、ユーザーが自力でレコードを一切いじれない となります。
例として、ただ単に名前解決したいと思い、Private Hostedzone .hoge. を作りました。 そこにはすでにいくつかFQDNを登録しています。 その .hoge. に service discovery で追加される分も混ぜることはできないです。
言葉で書いてもピンとこないと思いますが、一発作ればよくわかります、ただ単に名前解決を楽にしたいだけという低い意識に対して service discovery (auto naming) を使うは完全にオーバースペックで悪手です。
UserDataなどを使う方法との違い
本ツールはEC2イベントとLambdaを使いますので、EC2インスタンス側への組み込みは一切不要です。UserData等の場合は、Powershellなのか、Shellなのか、AWSCLIなのか、Powershellのモジュールなのかいろいろ考える必要があります。もしくはGo lang win/linux 共通のバイナリを作るとか。でもそんなのめんどくさくてやってられない。
terraform/Cfnとかでインスタンスと同じタイミングにレコード追加するなどとの違い
上と一緒でめんどくさい。それよりなにより、名前解決ごときでterraformの実行反映がとろいのが嫌。IAMとRoute53のレコードは特に反映までの待ちが長いので、こんなしょうもないこと(ホスト間の名前解決)のためにいちいち待たされんのがいや。それと、AutoScaling等を導入する場合を考慮すると、結局UserDataなどを使わないといけないのでこちらのほうが守備範囲が狭い。
serverless framework(sls)
本エントリの本題に入ります。ダラダラ書きますが、基本は分かっている人向けで、入門的な話は書きません。
概要・存在意義
serverless version 1.x 系のリリースのころから私は始めました。当時の私の認識が間違っていたので、ここでも改めて書きますが
あくまでもLambdaが中心 (API Gatewayが中心じゃない)
プラグイン型にしたことに先見の明あり
nodejs製なので、serverless framework自体のバージョン固定必須
Lambdaを中心として、そのLambdaが必要とするIAMロールと、そのLambdaの導火線(着火剤)となるイベントを定義できます。Webに特化したものではないです、Webにも使えますが。AWSの場合はこの点が非常に重要で、特にインフラ屋が使うツールはたくさんのサービスに対してアクセスすることが多いです。これらを1元管理できるのは便利。 serverlessフレームワークは前身があったはずで、その頃はプラグイン型ではなかったはず。特にAWSのように目まぐるしき新しいサービス・サービス関連系が増えるものは明らかにこのモデルが優秀で、プラグインから本体へ取り込まれたものもいくつかあるはず。 最後に悪い点としてnodejsでできていること。ともかくアップデートのプレッシャーがきつく、nodejs本体のバージョンにも注意が必要。なので、ここはコンテナ(docker)化する。
EC2イベントから slsの本質を知る
2年前の実装をリファインするにあたり、まず最初にいじったのがここ。EC2イベントは当時はsls本体のイベントとしては存在しなかった。じゃあ、どうやって表現していたのか?slsの実装を忖度して、実行時=deploy に生成される Cfnテンプレートをイメージしながら追加リソースを書く となります。なんのとこやらわからないと思うので
# you can add CloudFormation resource templates here resources: Resources: RegisterRule: Type: AWS::Events::Rule Properties: EventPattern: { "source": [ "aws.ec2" ], "detail-type": [ "EC2 Instance State-change Notification" ], "detail": { "state": [ "running" ] } } Name: register-rule Targets: - Arn: Fn::GetAtt: - "RegisterLambdaFunction" - "Arn" Id: "TargetFunc1" RegisterPermissionForEventsToInvokeLambda: Type: "AWS::Lambda::Permission" Properties: FunctionName: Ref: "RegisterLambdaFunction" Action: "lambda:InvokeFunction" Principal: "events.amazonaws.com" SourceArn: Fn::GetAtt: - "RegisterRule" - "Arn" UnRegisterRule: Type: AWS::Events::Rule Properties: EventPattern: { "source": [ "aws.ec2" ], "detail-type": [ "EC2 Instance State-change Notification" ], "detail": { "state": [ "terminated" ] } } Name: unregister-rule Targets: - Arn: Fn::GetAtt: - "UnregisterLambdaFunction" - "Arn" Id: "TargetFunc1" PermissionForEventsToInvokeLambda: Type: "AWS::Lambda::Permission" Properties: FunctionName: Ref: "UnregisterLambdaFunction" Action: "lambda:InvokeFunction" Principal: "events.amazonaws.com" SourceArn: Fn::GetAtt: - "UnRegisterRule" - "Arn"
というふうに書きました。slsはコード以外のデプロイつまりAWSリソースはすべてCfnで行われます。slsの優れているところは、このCfnに対してほぼべた書きでserverless.yml に追記できる点です。これより2年前の私はEC2イベントを実現していました。これは言葉を変えれば、今本体がサポートしていないイベントでも、Cfnがわかる人ならば自分で追加できるということになります。この点は本体slsのマージが遅いならばとっととプラグインとして公開し、みんな早くハッピーになれるので、先見の明と先に書いたのはこの点です。
解説します。
RegisterRule: Type: AWS::Events::Rule
はCloudWatch Events を定義しています、注目ポイントは
Arn: Fn::GetAtt: - "UnregisterLambdaFunction" - "Arn" Id: "TargetFunc1"
で、イベント時に着火するLambdaを指定していますが、この名前は deploy 時に反映されるCfnのテンプレートやリソース名を確認して忖度し適合させています。みなさんがやる場合も生成されるCfnを読んでslsに忖度してあげましょう。
次に
PermissionForEventsToInvokeLambda: Type: "AWS::Lambda::Permission"
の部分です。これはManagementConsoleでしかLambdaをいじったことがないと一生理解できないかもしれないLambda側のパーミッションです。Lambda関数の中で必要となる = APIコールするAWSリソースに対して、Lambdaが権限を持っている必要があるは直感でわかるはfずですが、これは逆に S3やCloudWatch Events のようなものから対象Lambdaが呼ばれてもいいよ という許可設定です。この点は重要なので詳しく書いておきます。 例えばAWSリソース(A)から別のAWSリソース(B)へAPIコールする場合に、AにCredentialなどが持てるのであれば、A -> B の権限を、Aが持っていれば良いとなります。しかし CloudWatch EventsにはCredentialは仕込めません。私はこの手のものを俺用語で公共物と言ってます、具体的にはS3やCloudWatch Events,SQS 。対して、Credentialを仕込ませられるものは占有物と勝手にいい、代表はEC2やLambdaです。 つまり、占有物 -> 公共物ならば 占有物にCredential+権限があればOK。しかし公共物 -> 占有物には Credentialが使えない、「どうしよう、公共物ってことなので、だれでも名前さえ知ってたら呼べちゃう」を解決するのがこのLambda Permission。簡単にいうと、受ける側で送信元を限定する、A -> B の呼び出しをB側で許可するということになります。最近は公共物でもロールを当てることができたりします e.g. Cfnロール
EC2のイベントが本体に取り組まれたため、今回はこんなにスッキリしています。たったこれだけでCloudWatch Eventsの登録 & Lambdaパーミッションの設定ができます。
functions: register: handler: register.handle memorySize: 128 timeout: 30 events: - cloudwatchEvent: event: source: - "aws.ec2" detail-type: - "EC2 Instance State-change Notification" detail: state: - running
nodejs(sls)を固定化させる方法
最近のnpm は lockが可能なので少し立ち位置が微妙ですが yarn(hadoop関係ない方)で固定化させていました。とりあえず今回は npmでlockするので、yarnは無しにしました。 次にnodejs本体のバージョン固定と、ネイティブバイナリのビルドについての考慮です。
nodejs本体のバージョン固定
slsが入ったDockerイメージも誰かが作っているので、これに乗っかるのもありです。が、訳あってこれは使いません。
lambda向けネイティブバイナリビルド
じつは今回公開したLambdaは、ネイティブバイナリのビルドはありません。のでこの機能は必要ないのですが。ネイティブバイナリとは、まあ一般的にはC/C++ で書かれるそのOS/CPUでしか動かないコンパイル済みのバイナリを指します。これはmacでもWindowsでも引っかかる問題です。仮にローカルPCとしてmacでビルドした場合、mac用のバイナリができます。当然これをLinuxに持ち込んでも動かない。 Python使いなら requirements.txt というのを書くと思いますが、これをDocker でビルドして、バイナリをクライアントPCに持ってくるプラグインがあります serverless-python-requirements。 これはrequirements.txtを扱えるだけではなく、Dockerを使ってのクロスコンパイル(というかDockerコンテナがLinuxなのでそこで普通にビルドするだけ)が可能です。 どうせやるならこの点も解消しようと思いました。
slsコマンド本体はDockerでやるのは決めていたので、そのまま何も考えないならば slsのDockerから、更にbuild用Dockerを作りそこでビルドです。ちなみにこれはDinDを使わなくとも一応実現可能ですが、macでしか使えないはずです。今回は採用しませんでしたが、一応残しておくと
slsコンテナに -v で docker.socket(UNIXドメインソケット)を渡す
slsコンテナに dockerコマンドを突っ込む
上記で完璧と思ったが、slsコンテナからビルド用コンテナに行くとき、さらに -v でソース=requirements.ext がある場所をバインドしている。よって -v する mac上のパスと、slsコンテナのパスを完全に一致させる必要がある。
となります。が、この方法ははっきり言ってアホです。そもそもslsコンテナの時点でLinuxなので、だったらそこで普通にビルドしたら良いだけです。serverless-python-requirementsはDockerを使わないビルドも可能ですので、今回はこちらでやりました。方針としてはslsのblogと同じように、serverless-python-requirementsはグローバルインストールしない、dockerizePip: falseで使うことにします。こちらもpython37/36 だけですが Dockerfile & image を公開しています。
Containers for Serverless framework. Contribute to h-imaoka/sls-builder development by creating an account on GitHub. h-imaoka/sls-builder - GitHub
github.com
https://hub.docker.com/r/himaoka/sls-builder
まとめ・感想
2年たった今でもslsは優秀だなと改めて感じた。プラグイン型や、Cfnによるデプロイは本当に先見の明があり。
ド素人は本体にあるイベントで我慢して
ちょっと分かる人は、Cfnのリソースを直接書き足して(2年前の私)
もっと分かる人は、プラグインにして公開して
プラグインでももうこれは本体に取り込んで良いんじゃないかと思うものは、PRして
こうすることで、素人に優しい環境を提供しつつ、玄人の尊厳も忘れないというOSSの理想の形が体現できているように思う。ま、samは使ったことないんだけどね。
元記事はこちら
「AWSでGCEぽく、Lambdaでインスタンス起動時にDNS自動登録する」
January 09, 2019 at 12:00PM
0 notes