20211008のAWSに関する記事は13件です。

AWS Step Functions のステート定義におけるリトライの書き方

指数バックオフアルゴリズム   SFN(Step Functions) は指数バックオフによるリトライが行われます。 (エクスポネンシャルバックオフ) SFNにおける式はこんな感じ リトライ時間 = IntervalSeconds * BackoffRate ^ (Attempts-1) 簡単に言うと、ランダム時間でリトライ間隔を決めるアルゴリズムです。 いきなりこんな式を見てもピンと来ないので、エラー時に成功するまでn回リトライするようなケースを考えてみます。 よくあるリトライ リトライ間隔 = 2秒 (固定) リトライ回数 = n回 リトライ間隔は常に一定で、10回リトライを行います。 指数バックオフによるリトライ リトライ間隔 = 2秒 (初回のみ) リトライ回数 = n回 バックオフレート = 3秒 こちらは通常のリトライとは異なり、リトライ回数が増えるごとに、リトライ間隔が増えていきます。 リトライ間隔の計算 リトライ間隔 = 2秒 (初回のみ) リトライ回数 = 10回 バックオフレート = 3秒 リトライ間隔を計算するワンライナーのPython スクリプト (python環境があるコンソールに貼り付ければ動きます) python -c "for s in (lambda i,m,b: (i*b**(n-1) for n in range(1, m+1)))(2,10,3): print(s)" 2 ・・・ 2 * 3^(1-1) = 2 * 3^0 = 2 * 1 6 ・・・ 2 * 3^(2-1) = 2 * 3^1 = 2 * 3 18 ・・・2 * 3^(3-1) = 2 * 3^2 = 2 * 9 54 ・・・2 * 3^(4-1) = 2 * 3^3 = 2 * 27 162 ・・・ 以下省略 486 1458 4374 13122 39366 総リトライ時間[s] リトライ間隔 = 2秒 (初回のみ) リトライ回数 = 10回 バックオフレート = 3秒 python -c "print(sum((lambda i,m,b: (i*b**(n-1) for n in range(1, m+1)))(2,10,3)),'[s]')" 59048 [s] 総リトライ時間[h] リトライ間隔 = 2秒 (初回のみ) リトライ回数 = 10回 バックオフレート = 3秒 python -c "print(sum((lambda i,m,b: (i*b**(n-1) for n in range(1, m+1)))(2,10,3))/3600,'[h]')" 16.40222222222222 [h] SFN での書き方 使用するステートマシン 特定のEC2インスタンスを起動するステートマシン 定義(JSON) { "Comment": "Start the EC2 instance.", "StartAt": "StartInstances", "States": { "StartInstance": { "Type": "Task", "Resource": "arn:aws:states:::aws-sdk:ec2:startInstances", "Parameters": { "InstanceIds": [ "i-1234567890abcdef0" ] }, "Retry": [ { "ErrorEquals": [ "States.ALL" ], "IntervalSeconds": 2, "MaxAttempts": 10, "BackoffRate": 3 } ], "End": true } } } 定義(YAML) ※Serverless Framework などでデプロイする時 --- Comment: "Start the EC2 instance." StartAt: "StartInstances" States: StartInstance: Type: "Task" Resource: "arn:aws:states:::aws-sdk:ec2:startInstances" Parameters: InstanceIds: - "i-1234567890abcdef0" Retry: - ErrorEquals: - "States.ALL" IntervalSeconds: "2" MaxAttempts: "10" BackoffRate: "3" End: "true" ErrorEquals このエラーに合致したものが、リトライの対象となります。 以下のようなものがデフォルトで用意されているっぽいですね * States.Runtime * States.Timeout * etc... Lambda なんかだと・・・ ErrorEquals によるエラー判定 (独自実装の例外) 例えばPythonランタイムのLambdaで例外クラスAccountAlreadyExistsException をraise する class AccountAlreadyExistsException(Exception): pass def create_account(event, context): raise AccountAlreadyExistsException("Account is in use!") ステートマシンでAccountAlreadyExistsExceptionをキャッチしたい場合、以下のように書く "ErrorEquals": ["AccountAlreadyExistsException"]
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

cloudwatch 概念について

勉強前イメージ メトリクスとモニタリングがちょっとややこしくなってきた 調査 cloudwatchの概念について Namespaces cloudWatchメトリクスのコンテナになります。 名前空間のメトリクスは切り離され、 異なるアプリケーションのメトリクスが同じ統計に集約されないようになっています。 メトリクスの作成時に名前空間名を指定する必要があります。 Metrics 基本的な概念で監視対象の変数で、その変数の値になります。 作成されたリージョンのみに存在しています。 例えばEC2のCPU利用率は提供される1つのメトリクスになります。 Dimensions メトリクスを一意に識別する名前と値のペアになります。 1つのメトリクスには最大で10個のディメンションを定義することができます。 メトリクスの検索やフィルタなどに利用できます。 Resolution 生成されたメトリクスはデフォルトで標準解像度になりますが、 カスタムメトリクスは 標準解像度 と 高解像度 のいずれかで定義することができ、 高分解能のメトリクスを使用すると1秒・5秒・10秒・30秒、60秒の倍数の期間で読み取り、取得出来ます。 また、高解像度のメトリクスでアラームを設定すると、 10秒・30秒の期間で高解像度のアラームと、60秒の倍数の通常アラームで設定できます。 高解像度アラームは別途費用が発生します。 Statistics 指定した期間のメトリクスデータの集計になります。 指定した期間内に、名前空間・メトリクス名・ディメンション・データポイントの測定単位を用いて行われます。 Percentiles データにおける値の相対的な位置を表しています。 メトリクスの中に統計としてPercentilesがサポートされていて、 平均・最小・最大・合計と同様にPercentilesでモニタリングも出来ます。 Alarms アラームを使用するとアクションを自動的に実行させることが出来ます。 他で使用されているアラームと同様のイメージで、 指定したメトリクスを監視し、一定のしきい値から外れた際にアクションを実行します。 勉強後イメージ 概念についてメトリクスはなかったけど、 メトリクス → 監視対象 モニタリング → 監視間隔 ってことかな。 言葉難しいね??? 参考 Amazon CloudWatch の概念 AWS再入門2018 CloudWatch編
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

参考記事まとめ

はじめに 1つの記事でやりたいことが完結した分かりやすい記事をまとめます。 随時更新。 AWS ・1つのLambdaで、複数のEC2を自動起動・自動停止 ・CloudFrontとLambda@edgeでBasic認証設定 ・API GatewayにLambda(Node.js)でBasic認証 ・CloudWatchでEC2のメモリ・ディスク使用率を監視する ・GuardDutyアラートをChatBotでSlack通知 ・CloudFront FunctionsでIP制限 ・LambdaでSlack通知時使用するEmoji Cheat Sheet WordPress ・WordPress のフォルダ構成
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

初めてのCloudFormation 環境準備からVPC作成まで

この記事を書いている私について AWS CloudTechという動画学習サービスに参加し、AWSエンジニアを目指すための備忘録です これまでに学習してきた内容は下記になります。 ■インフラ基礎  ・サーバー  ・ネットワーク  ・Linux運用 ■AWS  ・VPC  ・EC2  ・IAM  ・RDS  ・ELB  ・Cloudwatch  ・AutoScaling  ・S3  ・Route 53  ・CloudFront AWS CloudTechはAWSの基本を学ぶことができ、slackのコミュニティも素晴らしく、さらにSAA・SOA・DVA対策コースもある。 環境を用意して下さったくろかわさん(@AwsskillC)に感謝です。 残りの課題がまだありますので、こちらも学習していきます ■AWS  ・AWS CLI  ・Lambda  ・Docker  ・Docker-compose  ・ECS←最近講座に追加されました! 本記事の目標 まずは開発環境を整えることから始めます。 その後、Cloud Formationを使いVPCを構築します。 ※CloudFormationではYMLファイルを取り扱います。 Cloud Formationとは AWSリソースをコード化してくれるサービスで、 テキストファイル(=テンプレート)にリソースの構造を記述してAWSリソースを自動作成してくれます。 今回からCloud Formationの構築に入っていきます。 今回の構成図 今回は単純にVPCの作成のみです。 構築の流れ 以下の流れで構築を進めます。 ・環境構築  -VSCodeのインストール   -拡張のインストール ・テンプレートの作成 ・スタックの作成 ・構築出来たか確認 ・環境構築 PCはWindows10前提となります。 Macの方は必要な個所を読み替えていただくようお願いします。 VSCodeのインストール CloudFormationではコードを扱うため、VSCodeをインストールします。 他のエディタでも問題ありませんが、拡張することで構成図も書けますし、 何より使いやすいのでお勧めします。 VSCodeのインストールはこちらの記事を参考にさせていただきました。 VSCode拡張のインストール draw.ioのインストール こちらの記事を参考にさせていただきました。 ちなみに、本記事に記載している構成図もdraw.ioを使って書いています(VPCのみですが、、、笑 YML関連のインストール YMLで快適に書くために下記のインストールを行います。 ・CloudFormation ・YAML ・Japanese Language Pack for Visual Studio Code ↓ここからはお好みでインストールしてください。 ・indent-rainbow ・Indenticator こちらの記事を参考にさせていただきました。 ・テンプレートの作成 CloudFormationにアップロードするymlは以下となります。 AWSTemplateFormatVersion: 2010-09-09 Resources: MyVPC2: Type: AWS::EC2::VPC Properties: CidrBlock: 10.0.8.0/21 EnableDnsSupport: true Tags: - Key: Name Value: MyVPC2fromcf ・スタックの作成 マネージメントコンソールから[CloudFormation]を選択し、[スタックの作成]をクリック。 次に、[テンプレートファイルのアップロード]を選んで、ymlをアップロードします。 ・構築出来たか確認 スタックのステータスが「CREATE_COMPLETE」となったら、 実際にVPCが作成されているか確認します。 本講座は以上となります。 VPCの作成自体は簡単なのですが、 VSCodeのセッティングに時間が掛かってしまいましたので、 これから慣れていきたいと思います。 本課題で発生する費用 VPCのみでは費用は発生しません。 最後に CloudFormationを使っていく準備が出来ました。 次回からの講座でサブネット・EC2・RDSの作成を行っていく予定です。 ※SAAも勉強中です! AWS CloudTechの課題としてこれらが残っていますので、 やったことを今後のQiita記事にして発信していきたいと思います。 これから始められる方の参考になれば嬉しいです。 今後の学習予定↓↓↓ ・CloudFormationの作成、更新 ・Lamda関数 ・Docker ・ECS 内容に不備がございましたら、ご指摘いただけますと幸いです。 今後の励みになりますので、良ければ「LGTM」をお願いします。 閲覧ありがとうございました。 この記事はAWS初学者を導く体系的な動画学習サービス「AWS CloudTech」のハンズオンを基に作成しました。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS SSM パラメータストアから必要な機密データをファイルに書き出すスクリプト

AWS SSM パラメータストアから必要な機密データをファイルに書き出すスクリプトです。 ステージング /stg/hoge 本番 /prd/hoge のように環境変数を管理している場合を想定しています。 ここでは、env_ssm というファイルに出力しています。 CI ツールとかで環境変数を設定したい時とかに使えます。 #!/usr/bin/env bash set -eu echo '' > .env_ssm ssm_parameters_env="stg" # ここでは stg としていますが、条件分岐で値を変えるように設定するといいですね。 parameters=`aws ssm get-parameters-by-path --path "/$ssm_parameters_env" --with-decryption | jq -r .Parameters` parameters_length=`echo $parameters | jq length` declare -A ssm_parameters for ((i=0; i<=`expr $parameters_length - 1`; i++)) do name=`echo $parameters | jq -r ".[$i].Name"` value=`echo $parameters | jq ".[$i].Value"` ssm_parameters[$name]=$value done for key in "${!ssm_parameters[@]}" do env_name=${key#/$ssm_parameters_env/} uppercase=${env_name^^} echo "export $uppercase=`echo ${ssm_parameters[$key]}`" >> .env_ssm done
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS SSM パラメータストアから必要な機密データをファイルに書き出すスクリプト

AWS SSM パラメータストアから必要な機密データをファイルに書き出すスクリプトです。 ここでは、env_ssm というファイルに出力しています。 CI ツールとかで環境変数を設定したい時とかに使えます。 #!/bin/bash set -eu echo '' > .env_ssm parameters=`aws ssm get-parameters-by-path --path "/" | jq -r .Parameters` parameters_length=`echo $parameters | jq length` declare -A ssm_parameters for ((i=0; i<=`expr $parameters_length - 1`; i++)) do name=`echo $parameters | jq -r ".[$i].Name"` value=`echo $parameters | jq ".[$i].Value"` # 必要なデータを抽出する (ここでは先頭が hoge の文字列) if [[ $name =~ ^hoge ]]; then ssm_parameters[$name]=$value fi done for key in "${!ssm_parameters[@]}" do echo "export $key=`echo ${ssm_parameters[$key]}`" >> .env_ssm done
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

VPCの豆知識

初めに AWSに関する知識を身に着けるため 役に立つ用語や知識をに備忘録として残していく。 VPC豆知識 ● VPCは大きな箱のような役割をしており、  その中にルーター・サブネット・EC2などを格納できる。 ● VPCのアドレスレンジは下記から選ぶことができる。 10.0.0.0~10.255.255.255 172.16.0.0~172.32.255.255 192.168.0.0~192.168.255.255 ※ /16 ~ /28の範囲内で作成でないといけない。※ ※ 例えば、10.0.0.0/15といった設定だとエラーが発生するので注意 ※ ● IPアドレスには10進数と2進数での表記方法がある。 2進数は0と1であらわすことができ、10進数は普段私たちが使っている表記。 追記 間違った内容や記述があればコメントで教えてくださいね! この記事が参考になればうれしいです。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

FileMaker開発者に贈る|AWS IoT Core 初級ハンズオン

この記事を読んで欲しい方 全FileMaker開発者 クラウド触ったことない AWS難しい 新しいいこと好き etc... この記事を読むとどうなるか? AWSIoTCoreの概要とFileMakerとAWSの連携方法を理解できる ⇨日々楽しく改善できるようになる! どうやるか AWS IoT Core 初級ハンズオン(https://aws-iot-core-for-beginners.workshop.aws/ ) に沿ってIoT実装の基本を理解し、その後FileMakerとの連携方法を学ぶ。 実践開始 この記事は AWS IoT Core 初級ハンズオン(https://aws-iot-core-for-beginners.workshop.aws/ ) をみながら進めていきます。別タブでこちらを開いておくことをオススメします。 AWS IoT Coreのサービス説明 まずはこちら(https://aws-iot-core-for-beginners.workshop.aws/phase1/step1.html )から AWS IoT Coreのサービス説明動画をご覧ください。 まとめると。AWS IoT Coreとは「ラズパイやマイコンとの通信や管理を効率的に実現できるしくみ」です。 ハンズオン構成 本ハンズオンで使用するAWSサービスの概要説明をこちら(https://aws-iot-core-for-beginners.workshop.aws/phase1/step2.html )からご覧ください。 Cloud9 ブラウザ上でコード記述可能 リアルタイムで共同編集可能 今回はダミークライアントとして利用(センサー信号を送っているふりをさせる) Amazon Kinesis Data Streams 管理が容易 他サービスとのデータ連携を実現 複数データまとめて処理が可能 AWS Lambda コードを書けばすぐに動く仕組み サーバーの準備や管理が不要 使用した分だけ課金 「センサーデータが来たとき」などイベントで起動可能 Amazon DynamoDB Amazonが提供するNoSQLデータベース 低遅延 大規模データに向いている AWSアカウント作成 まずはこちら(https://aws.amazon.com/jp/register-flow/ )に従ってAWSアカウントの作成をお願いします。 アカウント作成後にAWSマネジメントコンソールにログインすると下記のような画面が表示されます。 デバイスのセットアップ Raspberry Piとセンサーを使用される方はこちら(https://aws-iot-core-for-beginners.workshop.aws/phase2/step2.html ) その他の方はこちら(https://aws-iot-core-for-beginners.workshop.aws/phase2/step1.html  ) からセンサー情報をAWSに送信する仕組みを準備してください。 ※Raspberry Piでセットアップを行う場合はファイルの場所にご注意ください。 SSHの設定はこちら(https://qiita.com/tomokin966/items/bc22d09f97ebeb3955d2 )の記事などを参考に設定してください。 IoT Coreのセットアップ こちら(https://aws-iot-core-for-beginners.workshop.aws/phase3.html   ) からAWS IoT Coreの設定をお願いします。 ※Raspberry Piの場合はcertフォルダの作成場所にご注意ください。 アプリケーション向けDB作成 こちら(https://aws-iot-core-for-beginners.workshop.aws/phase4.html   )よりFileMakerと連携するためのDBを作成します。 「(OPTIONAL)API用Lambdaの設定」まで実施してください。 API用Lambdaのコード「lambda_function.py」を修正 |↓ここからFileMakerとの接続のため本記事独自構成 取得するデータに湿度も追加します。また、クエリストリングを使用した検索を実装します。 下記のコードを「lambda_function.py」に貼り付けてください。 from __future__ import print_function import boto3 from boto3.dynamodb.conditions import Key import datetime import json import traceback import os #-----Dynamo Info change here------ TABLE_NAME = os.environ.get('TABLE_NAME', "default") DDB_PRIMARY_KEY = "deviceid" DDB_SORT_KEY = "timestamp" #-----Dynamo Info change here------ dynamodb = boto3.resource('dynamodb') table = dynamodb.Table(TABLE_NAME) #------------------------------------------------------------------------ def dynamoQuery(deviceid, requestTime): print("dynamoQuery start") # データを取得 valList = [] res = table.query( KeyConditionExpression= Key(DDB_PRIMARY_KEY).eq(deviceid) & Key(DDB_SORT_KEY).lt(requestTime), ScanIndexForward = False, Limit = 5 ) # 取得したデータをリストに格納 for row in res['Items']: temper = row['TEMPERATURE'] humid = row['HUMIDITY'] itemDict = { "timestamp":row['timestamp'], "temper":int(temper), "humid":int(humid) } valList.append(itemDict) return valList def lambda_handler(event, context): HttpRes ={ 'isBase64Encoded': False, 'statusCode': 200, 'headers': {}, 'body': '{"message": "Hello from AWS Lambda"}' } try: print("lambda_handler start") print(json.dumps(event)) # get Parameters pathParameters = event['queryStringParameters'] deviceid = pathParameters["deviceid"] requestTime = datetime.datetime.now().strftime('%Y-%m-%dT%H:%M:%S') resItemDict = { deviceid : ""} resItemDict[deviceid] = dynamoQuery(deviceid, requestTime) HttpRes['body'] = json.dumps(resItemDict) except Exception as e: print(traceback.format_exc()) HttpRes["statusCode"] = 500 HttpRes["body"] = "Lambda error. check lambda log" print("response:{}".format(json.dumps(HttpRes))) return HttpRes コードの修正を反映させるために「Deploy」ボタンをクリックしてください。 API Gatewayの設定 外部から上記で作成したLambda関数をAPIで使用するための設定を行います。 API Gatewayの画面を開く こちら( https://console.aws.amazon.com/apigateway )からAPI Gatewayの画面を開いてください。 右上にある「APIを作成」をクリックしてください。 REST APIの「構築」をクリックしてください。 好きなAPI名をつけて右下にある「APIの作成」をクリックしてください。 「アクション」→「リソースの作成」をクリックしてください。 リソース名に「data」と入力し、「リソースの作成」をクリックしてください。 上記で作成した「data」をクリックした状態で「アクション」→「メソッドの作成」をクリックしてください。 「GET」を選択し、チェックをクリックてください。 統合タイプ「Lambda 関数」を選択、Lambda プロキシ統合の使用にチェック、Lambda 関数に「(OPTIONAL) API 用 LAMBDA の設定」で作成したlambda関数名を設定し、「保存」をクリックしてください。 下記のようのようなダイアログが表示されるので「OK」をクリックしてください。 作成されたAPIとlambda関数のテストを行います。「テスト」をクリックしてください。 クエリ文字列に「deviceid={作成したモノのID}」を設定し、「テスト」をクリックしてください。 下記のようなレスポンスが返ってきます。 ここでうまく動かない場合は、センサー→IoTCore→kinesis→dynamoDBまでデータが来ているか、lambdaでエラーは発生していないか、などのご確認をお願いします。 作成したAPIをデプロイし、どこからでも使用できるようにします。 ※本番運用の際はセキュリティを強化してからご使用ください。 「アクション」→「APIのデプロイ」をクリックしてください。 下記ダイアログが出るので、デプロイされるステージに「新しいステージ」を選択、ステージ名に「handson」と設定し、「デプロイ」をクリックしてください。 APIをテストします。URL呼び出しのURLをコピーしてください。 下記のように「/data/?deviceid={モノのID}」と修正し、ブラウザのURL欄に入れてアクセスしてください。 https://****.execute-api.ap-northeast-1.amazonaws.com/handson/data/?deviceid=rasp_ppi_20211005 下記のようにデータが表示されればAPIの設定は完了です。 FileMakerの開発 上記で作成したAPIよりデータを取得するサンプルファイルをこちら (https://drive.google.com/uc?export=download&id=1cHPmAOIz6zfTeDiHmhDKTpCoZmP1f0KT )からダウンロードしてください。 動きの確認 ダウンロードしたファイルを開き、g_base_urlに作成したAPIのURLを、g_deviceidに作成したモノのIDを下記のように設定してください。 「データ取得」をクリックし、g_resultに結果が出力されることを確認してください。 「テーブル表示」をクリックし、ポータルにデータが表示されていることを確認してください。 スクリプトの解説 「データ取得」スクリプトについて 「URLから挿入」にてAWS API Gatewayで作成したAPIに対してリクエストを送り、返ってきた値を$resultに挿入します。 「フィールド設定」にて取得した結果を見やすい形に整形し、g_resultに設定します。 JSONFormatElements ( $result ) 「テーブル表示」スクリプトについて 取得したデータをポータルに表示します。 JSONGetElementを使用して取得したデータの中から各フィールドのデータを取り出します。 データをループさせて「環境情報」テーブルに書き込みます。 まとめ 以上でセンサー→AWS IoT Core→kinesis→dynamoDBにデータを貯めて FileMaker→API Gateway→Lambda→dynamoDB からデータを取得する流れを実装しました。 注意 本記事の実装はあくまでハンズオンの構成となっています。実運用の際はセキュリティ周りを最適なものに置き換えてください。 AWS1年間無料枠での実装を行いましたが1年以上放置すると料金が発生する可能性があります。 こちら(https://aws-iot-core-for-beginners.workshop.aws/phase7.html ) に沿って使用したサービスを削除してください。 つむぎや株式会社について 私が所属するつむぎや株式会社ではFileMakerやIoTや機械学習を使用して業務を楽しく改善するお手伝いを行っています。 IoTについてやFileMakerについてお問い合わせお待ちしております^^ https://tsumugiya-it.com/
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

個人開発で愛用しているNext.jsデプロイ手順 (~5分)

概要 個人開発をしようと思ったら、僕が最初にやることはNext.jsをAWSにホストすることです。 その際の手順を記載します。5分程度でインターネット公開することができます。 手順 ① Create Next App npx create-next-app@latest --ts <アプリ名> serverless.ymlファイルの作成 cd <アプリ名> touch serverless.yml open serverless.yml serverless.ymlに以下の内容を記載します。 myNextApplication: component: "@sls-next/serverless-component" serverlessインストール npm install -D serveless デプロイ 以下コマンドを実行してデプロイ (AWS CLIの設定ができていることが前提です) serveless まとめ 以上の作業だけで、Next.jsをS3 + CloudFront構成でデプロイができます。 作業時間は5分程度でできるので自分はいつも最初にこれをやっています。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Google Cloud の Storage Transfer Serviceを使ってS3→GCSへデータ転送

これは一体…? GCのStorage Transfer Serviceを使ってS3→GCSへデータ転送し、送信後はデータを送信元(S3)から削除する、までをやってみました。 メモとして残します。 なお、今回VPC service controlsは使っていません。 GC公式の手順では、これを使用する方法が載っており、おそらくこの方がセキュアなんだろうと思いますが、デフォルトでHTTPS使っているし、大丈夫だろうということでやってみました。 VPC service controlsを使うと得られるメリットは、今のところ以下だと考えています。 ・承認を受けたネットワーク以外は機密データにアクセスできないようにする ・Access Context Managerと併用することにより、アクセスレベルが絞れる この辺は機会があれば、今度まとめてみたいと思います。 前提 今回は検証、やってみた的なメモなので、本番環境などでは、念のためVPC service controls使用を考えた方がいいかなと思います。 やってみた Access Context Manager, Cloud Storage, and Storage Transfer Service API を有効になっていることを確認 [IAM と管理] で、ストレージ管理者のロールと Access Context Manager 管理者のロールをアカウントに付与する VPC service controls使わないのであれば、Access Context Manager 管理者のロールは必要ないと思います。 Storage Transfer Service 用の AWS IAM ポリシーを作成してバケットに適用する 公式手順 ただ、これだとなぜかできなかったので、画面下の方にあるポリシーに変えました。 AWS IAM ユーザーを AWS IAM ポリシーに追加する 公式手順 Cloud Storage バケットを作成する 公式手順 IAMポリシー 公式参考 { "Version": "2012-10-17", "Statement": [ { "Sid": "ここは任意", "Effect": "Allow", "Action": [ "s3:PutAnalyticsConfiguration", "s3:PutAccessPointConfigurationForObjectLambda", "s3:GetObjectVersionTagging", "s3:DeleteAccessPoint", "s3:CreateBucket", "s3:DeleteAccessPointForObjectLambda", "s3:GetStorageLensConfigurationTagging", "s3:ReplicateObject", "s3:GetObjectAcl", "s3:GetBucketObjectLockConfiguration", "s3:DeleteBucketWebsite", "s3:GetIntelligentTieringConfiguration", "s3:PutLifecycleConfiguration", "s3:GetObjectVersionAcl", "s3:DeleteObject", "s3:CreateMultiRegionAccessPoint", "s3:GetBucketPolicyStatus", "s3:GetObjectRetention", "s3:GetBucketWebsite", "s3:GetJobTagging", "s3:GetMultiRegionAccessPoint", "s3:PutReplicationConfiguration", "s3:PutObjectLegalHold", "s3:GetObjectLegalHold", "s3:GetBucketNotification", "s3:PutBucketCORS", "s3:DescribeMultiRegionAccessPointOperation", "s3:GetReplicationConfiguration", "s3:ListMultipartUploadParts", "s3:PutObject", "s3:GetObject", "s3:PutBucketNotification", "s3:DescribeJob", "s3:PutBucketLogging", "s3:GetAnalyticsConfiguration", "s3:PutBucketObjectLockConfiguration", "s3:GetObjectVersionForReplication", "s3:GetAccessPointForObjectLambda", "s3:GetStorageLensDashboard", "s3:CreateAccessPoint", "s3:GetLifecycleConfiguration", "s3:GetInventoryConfiguration", "s3:GetBucketTagging", "s3:PutAccelerateConfiguration", "s3:GetAccessPointPolicyForObjectLambda", "s3:DeleteObjectVersion", "s3:GetBucketLogging", "s3:ListBucketVersions", "s3:RestoreObject", "s3:ListBucket", "s3:GetAccelerateConfiguration", "s3:GetBucketPolicy", "s3:PutEncryptionConfiguration", "s3:GetEncryptionConfiguration", "s3:GetObjectVersionTorrent", "s3:AbortMultipartUpload", "s3:GetBucketRequestPayment", "s3:DeleteBucketOwnershipControls", "s3:GetAccessPointPolicyStatus", "s3:UpdateJobPriority", "s3:GetObjectTagging", "s3:GetMetricsConfiguration", "s3:GetBucketOwnershipControls", "s3:DeleteBucket", "s3:PutBucketVersioning", "s3:GetBucketPublicAccessBlock", "s3:GetMultiRegionAccessPointPolicyStatus", "s3:ListBucketMultipartUploads", "s3:PutIntelligentTieringConfiguration", "s3:GetMultiRegionAccessPointPolicy", "s3:GetAccessPointPolicyStatusForObjectLambda", "s3:PutMetricsConfiguration", "s3:PutBucketOwnershipControls", "s3:DeleteMultiRegionAccessPoint", "s3:UpdateJobStatus", "s3:GetBucketVersioning", "s3:GetBucketAcl", "s3:GetAccessPointConfigurationForObjectLambda", "s3:PutInventoryConfiguration", "s3:GetObjectTorrent", "s3:GetStorageLensConfiguration", "s3:DeleteStorageLensConfiguration", "s3:PutBucketWebsite", "s3:PutBucketRequestPayment", "s3:PutObjectRetention", "s3:CreateAccessPointForObjectLambda", "s3:GetBucketCORS", "s3:GetBucketLocation", "s3:GetAccessPointPolicy", "s3:ReplicateDelete", "s3:GetObjectVersion" ], "Resource": "arn:aws:s3:::S3バケットの名前" }, { "Sid": "VisualEditor1", "Effect": "Allow", "Action": [ "s3:ListStorageLensConfigurations", "s3:ListAccessPointsForObjectLambda", "s3:GetAccessPoint", "s3:GetAccountPublicAccessBlock", "s3:ListAllMyBuckets", "s3:ListAccessPoints", "s3:ListJobs", "s3:PutStorageLensConfiguration", "s3:ListMultiRegionAccessPoints", "s3:CreateJob" ], "Resource": "arn:aws:s3:::S3バケットの名前/*" } ] } ただ、これだと、なぜか送信できなかったので、ググって以下のポリシーを参考にさせていただきました。 IAMポリシー 参考 { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:ListBucket", "s3:GetBucketLocation" ], "Resource": "arn:aws:s3:::S3バケットの名前" }, { "Effect": "Allow", "Action": [ "s3:GetObject" ], "Resource": "arn:aws:s3:::S3バケットの名前/*" } ] } ただ、こちらだと、ソース元が削除できないエラーが発生したので、最終的に以下にしました。 IAMポリシー /// DeleteObjectを追加 { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:ListBucket", "s3:GetBucketLocation" ], "Resource": "arn:aws:s3:::S3バケットの名前" }, { "Effect": "Allow", "Action": [ "s3:GetObject", "s3:DeleteObject" ], "Resource": "arn:aws:s3:::S3バケットの名前/*" } ] } ここに書いてありました。 転送を開始 公式手順 いざ転送! なんですが、ファイルパス指定が最初よくわかりませんでした。 / 例 Source S3 path:2021/01/ Destination Google Cloud Storage path:logs/2021/01 の場合、GCSに届く時のファイルパスは、gcs-bucket/logs/2021/01/2021/01 になります。 →つまり、GCSのpath指定は、S3のファイル指定まで含める必要はないということを学びました。(二重になる) 転送成功 送信元からも削除されています。 参考 https://cloud.google.com/architecture/transferring-data-from-amazon-s3-to-cloud-storage-using-vpc-service-controls-and-storage-transfer-service https://cloud.google.com/vpc-service-controls https://medium.com/google-cloud/designing-secure-data-pipelines-with-vpc-service-controls-e3b4502307df https://note.com/ucwork/n/n5fe04382409b https://cloud.google.com/storage-transfer/docs/iam-transfer#source-permissions 参考にさせていただきました。ありがとうございます。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWSサービスを利用した機械学習モデルのデプロイメント

English Version (英語版) 機械学習モデルをGPUデバイスや組み込み機器などに実装することは、とても良い方法の一つです。 しかし、その一方で、非常にコストがかかります。 そこで、NVIDIA Jetson Nano Developer Kit B01を使って、物体検出モデル(Pytorch)と認識モデル(Tensorflow-Keras)を実行し、コスト削減を図りました。 しかし、Jetson nanoに展開するために最適化されたモデルを使用しても、メモリを多く消費するようで、同じデバイス上で両方のモデルを実行することは非常に困難でした。そこで、1つのモデルをAWSのクラウドシステムを利用して展開することにしました。 Jetson Nano上の検出モデルとAWS Cloud Services(AWS)上の認識モデルにより、システム全体の性能と速度を向上させることができました。 次の図は、組み込み機器とAWSへのモデル展開について説明しています: 今回は、AWS Lambda関数、docker、Cloudformationを利用しました。Lambda関数とdockerイメージは、AWS Cloudformation pipelineを使って自動的に作成されます。Cloudformation pipelineはyamlファイルを使って作成します。JSONフォーマットを利用することにもできますが、Cloudformationを扱う上でYAMLはJSONよりも多くの利点があります。 Dockerfileを作成する。 こちらがdockerfileの例です。 # ベースイメージにpython 3.8のLambdaランタイムを使用 FROM public.ecr.aws/lambda/python:3.8 # 変数の格納にはArgumentを使用 ARG AWS_CONTAINER_CREDENTIALS_RELATIVE_URI ARG AWS_DEFAULT_REGION # このapp.pyが機械学習の推論スクリプトになります。 COPY app.py ./ # requirements.txtからpythonの要件をインストールします。 RUN python3.8 -m pip install -r requirements.txt # CMDをラムダ関数ハンドラに設定する CMD ["app.handler"] このDockerfileは、次のセクションで説明するCloudformationパイプラインを実行すると、イメージが作成されます。 Dockerについてもっと知りたい方は、こちらをご覧ください。 Cloudformationを使ったパイプラインテンプレートの作成 AWSでは、各サービスについて非常に優れたドキュメントを用意しています。そこで、Lambda関数の作成にはAWS::Lambda::Functionのドキュメントを使用します。 パラメータテンプレートスニペットの設定は以下のように行います: Note:この方法では、各オプションのデフォルト名を設定することができます。例えば、アプリケーション名、S3バケット名、dockerイメージ名、ラムダ関数名などです。パラメーターセクションで名前を設定しないと、パイプラインを実行すると、長くて気持ち悪い名前が作成されてしまいます。 pipeline.yml AWSTemplateFormatVersion: 2010-09-09 Parameters: ApplicationName: Default: project_name_abc Type: String Description: Enter the name of your application CodeBuildImage: Default: 'aws/codebuild/standard:2.0' Type: String Description: Name of CodeBuild image. SourceBranch: Default: 'master' Type: String Description: Name of the branch. Environment: Default: 'development'(or 'production') # We can change depending on the environment Type: String Description: The environment to build. LambdaFunction: Default: 'lambda-function-name' Type: String Description: The predict lambda name. 基本的なスニペットを作成したら、今度はパイプライン用のResourcesを作成します。Resourcesを書く前に注意すべき点があります: 1. リポジトリ名は、命名規則に従ってください。 2. 名前はアルファベットで始まり、アルファベットの小文字、数字、ハイフン、アンダースコア、スラッシュのみを含むことができます。 3. すべてのリソースにAWS::IAM:Roleを与えることが推奨されます。 4. Amazon CloudWatchは、AWS、ハイブリッド、オンプレミスのアプリケーションやインフラリソースのデータや実用的なインサイトを提供する監視・管理サービスです。CloudWatchは、アプリケーション、インフラ、サービスといったスタック全体を監視し、アラーム、ログ、イベントデータを活用して自動化されたアクションを取ることができます。 5. AWS::CodeBuild::Projectリソースは、AWS CodeBuildがどのようにソースコードをビルドするかを設定します。 6. ルートレベルで buildspec.yamlを用意します。 7. AWS::CodePipeline::Pipelineリソースは、ソフトウェアの一部が変更されたときに、リリースプロセスがどのように機能するかを説明するパイプラインを作成します。 8. AWS::Lambda::Functionでは、Lambda関数を作成しています。実行時にLambda関数が使用できる最大メモリは10GBです。 pipeline.yml Resources: SourceRepository: Type: 'AWS::CodeCommit::Repository' Properties: RepositoryName: !Sub '${ApplicationName}-${Environment}' RepositoryDescription: !Sub 'Source code for ${ApplicationName}' MyRepository: Type: AWS::ECR::Repository Properties: RepositoryName: !Sub '${ApplicationName}-${Environment}/repository_name' CodeBuildRole: Type: 'AWS::IAM::Role' Properties: AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Action: - 'sts:AssumeRole' Effect: Allow Principal: Service: - codebuild.amazonaws.com CodeBuildPolicy: Type: 'AWS::IAM::Policy' Properties: PolicyName: CodeBuildPolicy PolicyDocument: Version: 2012-10-17 Statement: - Action: - 'logs:CreateLogGroup' - 'logs:CreateLogStream' - 'logs:PutLogEvents' Resource: '*' Effect: Allow Roles: - !Ref CodeBuildRole MyContainerBuild: Type: 'AWS::CodeBuild::Project' Properties: Artifacts: Type: CODEPIPELINE Environment: ComputeType: BUILD_GENERAL1_SMALL # ビルドには最大で3GBのメモリと2つのvCPUを使用します。 Image: !Ref CodeBuildImage Type: LINUX_CONTAINER PrivilegedMode: True EnvironmentVariables: - Name: REPOSITORY_URI # 環境変数で設定できます(本記事では説明していません)。 Value: !Sub '${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/${MyRepository}' - Name: ENVIRONMENT # Not covered in this article Value: !Sub '${Environment}' Name: !Sub '${ApplicationName}-${Environment}-MyContainer-Build' ServiceRole: !GetAtt - CodeBuildRole - Arn Source: Type: CODEPIPELINE BuildSpec: 'buildspec.yaml' AppPipeline: Type: 'AWS::CodePipeline::Pipeline' Properties: Name: !Sub '${ApplicationName}-${Environment}-Pipeline' ArtifactStore: Type: S3 Location: !Ref ArtifactBucketStore RoleArn: !GetAtt - CodePipelineRole - Arn Stages: - Name: Source Actions: - ActionTypeId: Category: Source Owner: AWS Version: '1' Provider: CodeCommit Configuration: BranchName: !Ref SourceBranch RepositoryName: !GetAtt - SourceRepository - Name OutputArtifacts: - Name: SourceRepo RunOrder: 1 Name: Source - Name: Build-Containers Actions: - InputArtifacts: - Name: SourceRepo Name: Build-My-Container ActionTypeId: Category: Build Owner: AWS Version: '1' Provider: CodeBuild Configuration: ProjectName: !Ref MyContainerBuild RunOrder: 1 CodePipelineRole: Type: 'AWS::IAM::Role' Properties: Policies: - PolicyName: DefaultPolicy PolicyDocument: Version: 2012-10-17 Statement: - Action: - 'codecommit:CancelUploadArchive' - 'codecommit:GetBranch' - 'codecommit:GetCommit' Resource: '*' Effect: Allow - Action: - 'cloudwatch:*' - 'iam:PassRole' Resource: '*' Effect: Allow - Action: - 'lambda:InvokeFunction' - 'lambda:ListFunctions' Resource: '*' Effect: Allow - Action: - 'codebuild:BatchGetBuilds' - 'codebuild:StartBuild' Resource: '*' Effect: Allow AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Action: - 'sts:AssumeRole' Effect: Allow Principal: Service: - codepipeline.amazonaws.com LambdaFunctionRole: Type: 'AWS::IAM::Role' Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - sts:AssumeRole Path: "/" Policies: - PolicyName: LambdaFunctionPolicy PolicyDocument: Version: '2012-10-17' Statement: - Action: - logs:CreateLogGroup - logs:CreateLogStream - logs:PutLogEvents Resource: '*' Effect: Allow - Action: - 'lambda:InvokeFunction' - 'lambda:InvokeAsync' Resource: '*' Effect: Allow LambdaFunction: Type: 'AWS::Lambda::Function' Properties: FunctionName: !Sub '${ApplicationName}-${MyLambda}-${Environment}' MemorySize: 4096 Timeout: 500 Role: !GetAtt LambdaFunctionRole.Arn Code: ImageUri: !Sub '${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/${MyRepository}:latest' PackageType: Image Environment: Variables: S3BUCKETNAME: !Sub ${BucketName} S3BUCKETREGION: !Sub ${AWS::Region} さて、CloudFormationのテンプレートを用意したら、いよいよスタックの作成です。 まず、「Upload a template file」オプションを選択し、pipeline.yml ファイルを選択します。 スタック名の入力: (スタック名には、アルファベット(A-Z、a-z)、数字(0-9)、ダッシュ(-)が使用できます。) また、パイプラインの作成時に設定したすべてのパラメータを確認することができます。 そして最後に、スタックを作成しましょう。 問題やエラーがなければ、dockerイメージが作成され、Elastic Container Registry にアクセスできるようになります。 Lambda関数が作成できたら、次にAWSコンソールから最新版のdockerイメージを手動でデプロイする必要があります。latestのDockerイメージを選択します。現在のところ、Cloudformation pipelineのビルドから自動的にイメージをデプロイすることはできません。 以上、ご紹介しました。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Deploying machine learning models using AWS services

日本語版 (Japanese Version) Implementing machine learning models on GPU devices, embedded devices, etc. is the best option. But on the other hand, it is very costly. The following figure explained about the models deployment on embedded device and AWS: Therefore, I used NVIDIA Jetson Nano Developer Kit B01 to run object detection model (Pytorch) and recognition model (Tensorflow-Keras). I used an optimized model to deploy on Jetson nano but it seems memory hungry and it is very difficult to run both models on same device. Hence, I decided to use AWS cloud system to deploy atleast one model. The detection model on Jetson Nano and Recognition Model on AWS Cloud Services (AWS) helped me to improve the performance and speed of the overall system. For this, I used AWS Lambda function, docker repository and Cloudformation. Lambda function and docker repository will be automatically created by using AWS Cloudformation pipeline. Cloudformation pipeline is created using yaml file. There is no restrictions of using JSON format too but YAML have many advantages over JSON while working on Cloudformation. Creating a Dockerfile: This is just a sample dockerfile. # Pull the base image with python 3.8 as a runtime for your Lambda FROM public.ecr.aws/lambda/python:3.8 # Use Argument to store variables ARG AWS_CONTAINER_CREDENTIALS_RELATIVE_URI ARG AWS_DEFAULT_REGION # This app.py will be the machine learning inference script. COPY app.py ./ # Install the python requirements from requirements.txt RUN python3.8 -m pip install -r requirements.txt # Set the CMD to your lambda function handler CMD ["app.handler"] This Dockerfile will create an image once we run the Cloudformation pipeline which is explained in the next section. Need to know more about Docker, please check here. Creating a Pipeline Template using Cloudformation: AWS has prepared a very good documentation for each services. Therefore, I will use AWS::Lambda::Function documentation for creating a Lambda function. We can setup Parameters Template Snippets as below: Note: This way we can set the default name for each options. For example, Application name, S3 bucket name, docker repository name, lambda function name, etc. If we don't setup the name in the Parameters section, then once we run the pipeline, it will create a scary and long names. pipeline.yml AWSTemplateFormatVersion: 2010-09-09 Parameters: ApplicationName: Default: project_name_abc Type: String Description: Enter the name of your application CodeBuildImage: Default: 'aws/codebuild/standard:2.0' Type: String Description: Name of CodeBuild image. SourceBranch: Default: 'master' Type: String Description: Name of the branch. Environment: Default: 'development'(or 'production') # We can change depending on the environment Type: String Description: The environment to build. LambdaFunction: Default: 'lambda-function-name' Type: String Description: The predict lambda name. Once we create a basic snippet, we will now create a Resources for the pipeline. Some important points to be noted before writing the Resources: 1. Repository name should follow the name convention. 2. The name must start with a letter and can only contain lowercase letters, numbers, hyphens, underscores, and forward slashes. 3. It is a good practice to give AWS::IAM:Role for every Resources. 4. Amazon CloudWatch is a monitoring and management service that provides data and actionable insights for AWS, hybrid, and on-premises applications and infrastructure resources. CloudWatch enables you to monitor your complete stack (applications, infrastructure, and services) and leverage alarms, logs, and events data to take automated actions. 5. The AWS::CodeBuild::Project resource configures how AWS CodeBuild builds the source code. 6. Provide a buildspec.yaml at the root level 7. The AWS::CodePipeline::Pipeline resource creates a pipeline that describes how release process works when a piece of software changes. 8. The AWS::Lambda::Function creates a Lambda function. The maximum memory available to the Lambda function during runtime is 10GB. pipeline.yml Resources: SourceRepository: Type: 'AWS::CodeCommit::Repository' Properties: RepositoryName: !Sub '${ApplicationName}-${Environment}' RepositoryDescription: !Sub 'Source code for ${ApplicationName}' MyRepository: Type: AWS::ECR::Repository Properties: RepositoryName: !Sub '${ApplicationName}-${Environment}/repository_name' CodeBuildRole: Type: 'AWS::IAM::Role' Properties: AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Action: - 'sts:AssumeRole' Effect: Allow Principal: Service: - codebuild.amazonaws.com CodeBuildPolicy: Type: 'AWS::IAM::Policy' Properties: PolicyName: CodeBuildPolicy PolicyDocument: Version: 2012-10-17 Statement: - Action: - 'logs:CreateLogGroup' - 'logs:CreateLogStream' - 'logs:PutLogEvents' Resource: '*' Effect: Allow Roles: - !Ref CodeBuildRole MyContainerBuild: Type: 'AWS::CodeBuild::Project' Properties: Artifacts: Type: CODEPIPELINE Environment: ComputeType: BUILD_GENERAL1_SMALL # Use up to 3 GB memory and 2 vCPUs for builds. Image: !Ref CodeBuildImage Type: LINUX_CONTAINER PrivilegedMode: True EnvironmentVariables: - Name: REPOSITORY_URI # It can be set in the environment variables (Not covered in this article) Value: !Sub '${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/${MyRepository}' - Name: ENVIRONMENT # Not covered in this article Value: !Sub '${Environment}' Name: !Sub '${ApplicationName}-${Environment}-MyContainer-Build' ServiceRole: !GetAtt - CodeBuildRole - Arn Source: Type: CODEPIPELINE BuildSpec: 'buildspec.yaml' AppPipeline: Type: 'AWS::CodePipeline::Pipeline' Properties: Name: !Sub '${ApplicationName}-${Environment}-Pipeline' ArtifactStore: Type: S3 Location: !Ref ArtifactBucketStore RoleArn: !GetAtt - CodePipelineRole - Arn Stages: - Name: Source Actions: - ActionTypeId: Category: Source Owner: AWS Version: '1' Provider: CodeCommit Configuration: BranchName: !Ref SourceBranch RepositoryName: !GetAtt - SourceRepository - Name OutputArtifacts: - Name: SourceRepo RunOrder: 1 Name: Source - Name: Build-Containers Actions: - InputArtifacts: - Name: SourceRepo Name: Build-My-Container ActionTypeId: Category: Build Owner: AWS Version: '1' Provider: CodeBuild Configuration: ProjectName: !Ref MyContainerBuild RunOrder: 1 CodePipelineRole: Type: 'AWS::IAM::Role' Properties: Policies: - PolicyName: DefaultPolicy PolicyDocument: Version: 2012-10-17 Statement: - Action: - 'codecommit:CancelUploadArchive' - 'codecommit:GetBranch' - 'codecommit:GetCommit' Resource: '*' Effect: Allow - Action: - 'cloudwatch:*' - 'iam:PassRole' Resource: '*' Effect: Allow - Action: - 'lambda:InvokeFunction' - 'lambda:ListFunctions' Resource: '*' Effect: Allow - Action: - 'codebuild:BatchGetBuilds' - 'codebuild:StartBuild' Resource: '*' Effect: Allow AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Action: - 'sts:AssumeRole' Effect: Allow Principal: Service: - codepipeline.amazonaws.com LambdaFunctionRole: Type: 'AWS::IAM::Role' Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - sts:AssumeRole Path: "/" Policies: - PolicyName: LambdaFunctionPolicy PolicyDocument: Version: '2012-10-17' Statement: - Action: - logs:CreateLogGroup - logs:CreateLogStream - logs:PutLogEvents Resource: '*' Effect: Allow - Action: - 'lambda:InvokeFunction' - 'lambda:InvokeAsync' Resource: '*' Effect: Allow LambdaFunction: Type: 'AWS::Lambda::Function' Properties: FunctionName: !Sub '${ApplicationName}-${MyLambda}-${Environment}' MemorySize: 4096 Timeout: 500 Role: !GetAtt LambdaFunctionRole.Arn Code: ImageUri: !Sub '${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/${MyRepository}:latest' PackageType: Image Environment: Variables: S3BUCKETNAME: !Sub ${BucketName} S3BUCKETREGION: !Sub ${AWS::Region} Now, once we prepare the CloudFormation template, it's time to create stack. We need to chose Upload a template file option and select the pipeline.yml file. Provide a stack name (Stack name can include letters (A-Z and a-z), numbers (0-9), and dashes (-).) We can also able to see all the parameters we set during creating pipeline. And finally, let's create the stack. If there is no issue or no errors, then a docker image will be created which can be accessed to Elastic Container Registry Once the Lambda function has been created, then we need to manually deploy the newest version of docker image from the AWS console. Select the latest docker image. Currently, it cannot deploy image automatically from the Cloudformation pipeline build. That's all for now!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

S3/CloudFrontで静的サイトホスティングしてみた。

経緯 転職活動をするにあたって、実績をまとめたポートフォリオサイトを作成することにした。 一番簡単な方法はGitHub Pagesを使ってリポジトリを登録して一発でサイトホスティングしてしまう方法だと思うが、これだと過去のポートフォリオや画像を掲載するとサイトの動作が遅くなるという欠点がある。 私の場合はReactのSPAを掲載したかったため、動作が重くなる事態は避けたかった。 その時に実際行った手順を備忘録として残しておきたい。 システム構成図 ・S3とは? AWSが提供するストレージサービス。静的サイトホスティングの機能も有しており、今回はこれを利用する。 ・CloudFroutとは? CDNサービス。あらかじめディストリビューションを登録しておくことでコンテンツを高速で配信する。 メリット ・取得した独自ドメインに対してACMでSSL証明書を発行、これによりサイトをhttps通信で公開できる。(SEOの観点からも有利) ・ユーザーはあらかじめCloudFrontに登録されたコンテンツを閲覧できるため、とにかく動作が高速。 ・サーバーレスで管理が楽。 ・手軽にオリジナルドメインを導入できる。 ・GitHub Pagesを使う場合とは異なり、実務等で静的サイトを公開する場合に応用が利く。 ・費用が安い。 単にGitHub Pagesを使用するよりカッコいいのではないかと個人的には思う。 手順 ①IAMユーザーを作成する セキュリティの観点からadmin権限を持ったIAMユーザーを作成しておく。 今回は「test-admin」としておく。 AdministratorAccessというポリシーを忘れずにアタッチしておく。 このIAMユーザーは全ての権限にアクセスできるみたいな意味。 ②ドメインを登録する 今回はRoute53/お名前.comを利用する。 あらかじめお名前.comでドメインを購入しておく。 demonitoring.workを購入。 Route53の方でホストゾーンを作成。 自動でNSレコードが作成される。 demonitoring.workをクリック。 NSレコード4つを確認、お名前.com Naviから、ネームサーバーの選択。 その他のネームサーバーを使う。 4つのレコードを登録していく。 順番は気にしなくても良いが、末尾に.を含めないように気をつける。 ③ACMで独自ドメインにSSL証明書を発行する 登録したドメインにDNS検証をして、信用できるドメインだと証明する手順。 ※この際に絶対忘れてはならないのがリージョンをバージニア北部(us-east-1)に変更すること。 CloudFrontで利用するドメインはSSL証明がバージニア北部からしか行えない。 画像上部の「証明書のリクエスト」から申請を行い、もう一度画像の画面に戻ってきたところで「Route 53でのレコード作成」ボタンを押す。 数分待てば検証状態:成功、状況:発行済みと表示される。 何時間も待たされるようだと一度手順を確認した方が良い。 何かが間違っている。 自分は何度も検証が通らず、理由も分からないという事態に直面した。笑 ④S3でhtml/CSSを公開する 画像にあるオレンジ色のボタン「バケットを作成」をクリック。 バケット名は一意である必要がある。 リージョンは東京に戻しておいて問題ない。 ここで重要なのが「パブリックアクセスを全てブロック」のチェックを外しておくこと。 後からS3でのホスティングはうまくいっているのか、問題はCloudFrontにあるのか、確認する上で便利である。 バケットのバージョニングは無効で問題ない。 デフォルトの暗号化も今回はいじらない。 詳細設定も無視してバケットを作成をクリック。 作成したバケットにファイルをアップロードしていく。 アップロードするファイルについて、topページに表示したいものはindex.htmlという名前であることが推奨される。 単純にわかりやすい。 次にプロパティのタブをクリック,静的ウェブサイトホスティングを編集。 静的ウェブサイトホスティング:有効にする ホスティングタイプ:静的ウェブサイトをホストする インデックスドキュメント:index.html エラードキュメント - オプション:今回は特に記入しない。 最後にアクセス許可のタブから、バケットポリシーを作成。 https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/HostingWebsiteOnS3Setup.html#step3-add-bucket-policy-make-content-public 下記を貼り付ける。 { "Version": "2012-10-17", "Statement": [ { "Sid": "PublicReadGetObject", "Effect": "Allow", "Principal": "*", "Action": [ "s3:GetObject" ], "Resource": [ "arn:aws:s3:::example.com/*" ] } ] } "Resource"の部分のexample.comのところだけ、用意したドメインに変更する。 もう一度プロパティのタブから、静的ウェブサイトホスティングをクリック。 エンドポイントという項目に、このバケットのURLが表示される。 問題なければエンドポイントにアクセスできるはず。 ⑤CloudFrontのディストリビューションに、作成したバケットを登録する マネジメントコンソールからCloudFrontを選択。 右上のボタン「ディストリビューションを作成をクリック」 オリジナルドメイン:作成したS3バケットを選択 オリジンパス - オプション:空欄で問題なし 名前:オリジナルドメインと一致 S3 バケットアクセス:はい、OAI を使用します (バケットは CloudFront のみへのアクセスとなるように制限できます) オリジンアクセスアイデンティティ:作成したバケットのOAIを選択 カスタムヘッダーを追加 - オプション:特にいじらない オリジンシールドを有効にする:いいえ 追加設定:今回は必要なし パスパターン:デフォルト (*) オブジェクトを自動的に圧縮:Yes ビューワープロトコルポリシー:Redirect HTTP to HTTPS※(HTTPできた通信をHTTPSにリダイレクト) 許可された HTTP メソッド:GET, HEAD ビューワーのアクセスを制限する:No キャッシュキーとオリジンリクエスト:Cache policy and origin request policy (recommended) 追加設定特になし。しばらくデフォルトの設定でよし。 料金クラス:すべてのエッジロケーションを使用する (最高のパフォーマンス) AWS WAF ウェブ ACL - オプション:特にいじらない 代替ドメイン名 (CNAME) - オプション:先に登録したドメインを入力する カスタム SSL 証明書 - オプション:先の手順でSSL証明書を発行したドメインを選択 サポートされている HTTP バージョン:HTTP/2 デフォルトルートオブジェクト - オプション:index.html を入力(S3バケットに登録したtopページに表示されるファイルを指定) 後はデフォルトのままで「ディストリビューションを作成」ボタンをクリック。 ディストリビューションが作成されて、ステータスが:有効になるのを確認する。 作成されたディストリビューションのドメイン(d15nhmn*******.cloudfront.net )にブラウザからアクセスしてみる。 この時まだ代替ドメインからはアクセスできない。 ⑥S3のバケットポリシーを変更する 先に記述したバケットポリシーを変更。 こんな感じにする。 { "Version": "2008-10-17", "Id": "PolicyForCloudFrontPrivateContent", "Statement": [ { "Sid": "1", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity E28L5RUN98ZNCT" }, "Action": "s3:GetObject", "Resource": "arn:aws:s3:::own-portfolio-site/*" }, { "Sid": "2", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity E28L5RUN98ZNCT" }, "Action": "s3:GetObject", "Resource": "arn:aws:s3:::own-portfolio-site/*" } ] } ⑦作成したCloudFrontディストリビューションのドメインを、Route53のAレコードに登録する。 再度Route53から、SSL証明書を発行した独自ドメインをクリック。 レコード名:特にいじらない レコードタイプ:Aレコード 値:エイリアスをクリック→CloudFrontディストリビューションのエイリアス→米国北部(バージニア北部)→ 先ほど作成したCloudFrontディストリビューションのドメインを選択(表示されない場合、手順に誤りがある) ルーティングポリシー:デフォルト ターゲットのヘルスを評価:デフォルト 「レコードを作成」ボタンをクリック。 最終的には4つのレコードが登録されているはず。 ブラウザから無事アクセスできれば成功である。(私の場合は https://demonitoring.work ) お疲れ様でした。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む