20210426のAWSに関する記事は15件です。

RDS / Aurora のパフォーマンスインサイト API を使って S3 に分単位の SQL トップ 10 を転記する

AWS の RDS / Aurora には、各インスタンスの負荷状況を可視化するパフォーマンスインサイトという機能があります。 マネジメントコンソールを使うとパフォーマンスインサイトの情報がグラフ化されるので見やすくて便利ですね。ただし、 追加費用なく保管できる期間が 30 日 追加費用を払えば 2 年間 画面上の表示期間を長くすればするほど、待機イベント・SQL(文)など細部の情報が欠落しやすくなる 詳しくはこちらのスライドを参照してください RDS / Aurora パフォーマンスインサイトを使ってみる(PostgreSQL 編) P.15 RDS / Aurora パフォーマンスインサイトを使ってみる(ちょっとだけ API 編) P.19 といった注意点もあります。 パフォーマンスインサイトを DB チューニングに使う DB まわりのチューニングというと、大きく分けて DB の設定や構成をチューニング SQL(文)をチューニング が考えられますが、ここでは後者を考えます。 どのような処理が性能上のネックになっているのかを知るには待機イベントの分析も良いのですが、実際に SQL(文)をチューニングするときはよく実行される SQL(文)・処理に時間がかかる SQL(文)を優先して、効率的な実行計画が採用されるように調整するほうが一般的だと思います。 そこで、今回はパフォーマンスインサイトの情報のうち、トークン化(正規化)された SQL(文)トップ 10 を分単位で抽出して S3 バケットに転記する Lambda 関数を作ってみました。 S3 転記用 Lambda 関数の内容 以下のとおりです。GitHub にも置いてあります。 コード(Python 3.8) lambda_function.py import boto3 from datetime import date, datetime, timedelta import os db_id = os.environ["DB_ID"] s3_bucket = os.environ["S3_BUCKET"] def lambda_handler(event, context): # 1時間前の時刻を取得(UTC)→対象時間のPerformance InsightsからS3へ lasthour = (datetime.today() + timedelta(hours = -1)).replace(minute=0, second=0, microsecond=0) print("Export: " + (lasthour + timedelta(hours = 9)).strftime('%Y/%m/%d %H:00-%H:59')) # 1分ごとに上位最大10件の正規化SQLを取得してS3へ転記 for minute in range(60): # Performance Insightsからデータを取得 pi_client = boto3.client("pi") starttime = lasthour + timedelta(minutes = minute) response = pi_client.describe_dimension_keys( ServiceType="RDS", Identifier=db_id, StartTime=starttime, EndTime=starttime + timedelta(minutes = 1), Metric="db.load.avg", PeriodInSeconds=60, GroupBy={ "Group": "db.sql_tokenized", "Dimensions": [ "db.sql_tokenized.statement" ], "Limit": 10 } ) if len(response["Keys"]): # 対象となる時刻(分単位)のデータがあればS3へ転記(プレフィクスの時刻はJST) s3_prefix = db_id + "/" + (starttime + timedelta(hours = 9)).strftime('%Y/%m/%d/%Y%m%d%H%M') + "_" + db_id + ".tsv" exporttime = starttime.strftime('%Y-%m-%dT%H:%M:%SZ') body_data = "start_time\tsql_tokenized\ttotal\n" # すべてのKeysから正規化SQLと合計値を抽出 for item in response["Keys"]: sqltk = item["Dimensions"]["db.sql_tokenized.statement"] total = item["Total"] body_data += exporttime + "\t" + sqltk + "\t" + str(total) + "\n" # S3へ s3_client = boto3.client("s3") s3_client.put_object( Bucket=s3_bucket, Key=s3_prefix, Body=body_data ) return "Completed." 設定など タイムアウトは 1 ~ 3 分程度に トリガーで 1 時間ごとの実行を指定(毎時 5 ~ 10 分頃に実行) ロールは Lambda の一般的な権限に、S3 バケットアップロード権限+パフォーマンスインサイトフル権限+(必要に応じて KMS ユーザー権限)を追加 ロールに設定するポリシー(追加部分) { "Effect": "Allow", "Action": "s3:*", "Resource": [ "【転送先S3バケットのARN】", "【転送先S3バケットのARN】/*" ] }, { "Effect": "Allow", "Action": "pi:*", "Resource": "arn:aws:pi:*:*:metrics/rds/*" }, { "Effect": "Allow", "Action": [ "kms:Encrypt", "kms:Decrypt", "kms:ReEncrypt*", "kms:GenerateDataKey*", "kms:DescribeKey" ], "Resource": "【Performance Insightsの暗号化用KMSのARN(※)】" } (※)転送先S3バケットの暗号化用KMSが別にあれば配列で定義 環境変数では RDS / Aurora インスタンスの ID(DB-ID)と転記先の S3 バケット名(S3_BUCKET)を指定 補足 現状では、トークン化(正規化)された SQL トップ 10 を、1 分(60 秒)単位で、 start_time : 時刻 sql_tokenized : トークン化(正規化)された SQL(文) total : 同 SQL(文)の平均負荷 の 3 項目だけ転記していますが、コードを調整することで、秒単位での集計結果やカウンターメトリクス値、待機イベント・SQL(トップ 10)別待機イベントなどを転記することも可能です。 Performance Insights API によるデータの取得(AWS ドキュメント) PI(Boto3 Docs) また、このコードでは Glue を介して Athena で分析することを意図して .tsv 形式で出力するようにしていますが、もちろん .csv 形式や JSON 形式のまま出力することも可能です(JSON 形式で出力するときは、日付を文字列に変換する必要がある点に注意)。 おまけ:Athena や QuickSight での表示例 データはいずれも Aurora MySQL 2 系でmysqlslap・sysbench(ベンチマークツール)を使用したときのもの パフォーマンスインサイト(元のグラフ画面・SQL 別のスライス) Athena QuickSight
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ネットワークの範囲

プログラミング勉強日記 2021年4月26日 ネットワークの範囲  ネットワークの範囲はIPアドレスの利用可能な範囲のこと。ネットワークに対してIPアドレスの範囲が付与されていてネットワークの範囲を決めている。(IPアドレスについては昨日の記事で説明している。)プライベートネットワークを作成するときは、まずネットワークの範囲を定義する。  ネットワークの範囲の表記方法は、10.0.0.0/16といった形になる。これは、IPアドレス(10.0.0.0)とサブネットマスク(/16)がIPの範囲(ネットワークの範囲)を決める。 AWSのネットワーク構成の例  10.0.1.0/16はIPアドレスではなく、/16という範囲がついたIPアドレスの範囲をこのネットワークでは持つという意味。  ネットワークをさらに細かく分割した単位をサブネットという。パブリックサブネットとプライベートサブネットは、それぞれ10.0.1.0/24と10.0.2.0/24の新しい範囲を付けることができる。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Google Maps API】本番環境でGoogle Mapが正しく読み込まれない原因と解決法

本番環境でGoogle Mapを表示できない このページではGoogleマップが正しく読み込まれませんでした。 結論 APIキーを config/credentials.yml.encファイルで管理する (.envファイルでなく) 原因 本番環境にAPIキーを渡せていない 経緯 Google Maps API 導入 ローカル環境でマップ表示できた APIキーを.envファイルで管理していた .envファイルは外部から見えぬよう、Gitの対象から外していた AWSにデプロイ後、ドメイン取得、HTTPS化してアクセスすると、マップ表示できなくなった 本番環境にAPIキーを渡せていないのかも?(仮説) 本番環境からは.envファイルを参照できない! 本番環境にも、APIキーを隠して渡す config.credentials.yml.encファイルにAPIキーを記述 ローカルのターミナル EDITOR=vi rails credentials:edit #vimでファイルを開く config/credentials.yml.enc google_map_api_key: xxxxxxxxxxxxxxxxxxxxxxxx #APIキーを追記 ビューで、config/credentials.yml.encファイルの記述を読み取る map.html.erb <script src="https://maps.googleapis.com/maps/api/js?key=<%= Rails.application.credentials.google_map_api_key %>&callback=initMap" async defer></script> #<%= Rails.application.credentials.google_map_api_key %> #これで「config.credentials.yml.enc」ファイルの「google_map_api_key」を取得できる キーの読み取り方(記述の違い) <%= Rails.application.credentials.google_map_api_key %> #credentials.yml.encファイルからキー取得 <%= ENV['google_map_api_key'] %> #.envファイルからキー取得 Google Mapが表示されない時の確認事項 取得したAPIキーをhtml内に記述しているか 支払い情報を登録しているか 請求先アカウントを未設定の場合、マップが1日1回しか表示できないらしい 表示回数の制限「割り当て」が1回になっていないか 回数制限がかかっているとMapが表示エラーになる可能性がある 請求アカウントとプロジェクトがひも付いているか 参考 GoogleMapが表示されないエラーが出た時の対処法 Rails5.2から追加された credentials.yml.enc のキホン さいごに Google Maps API導入は比較的スムーズに設定できました。(ローカルで) マップがうまく読み込まれない主な原因は、Google Cloud Platformでの設定が多いようですが、 APIキーを本番環境に渡せていないのは盲点でした。 パスワードやキーの管理方法について、セキュリティ面を見直すいい機会とはなりました。 間違っている点がありましたら、ご指摘いただけるとありがたいです。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Google Maps API】本番環境でGoogle Mapが正しく読み込まれなかった原因と解決法

本番環境でGoogle Mapを表示できない このページではGoogleマップが正しく読み込まれませんでした。 結論 APIキーを config/credentials.yml.encファイルで管理する (.envファイルでなく) 原因 本番環境にAPIキーを渡せていない 新しく取得したキー設定の誤りだと思ったら、キーの管理方法という基礎部分の誤りでした。。 経緯 Google Maps API 導入 ローカル環境でマップ表示できた APIキーを.envファイルで管理していた .envファイルは外部から見えぬよう、Gitの対象から外していた AWSにデプロイ後、ドメイン取得、HTTPS化してアクセスすると、マップ表示できなくなった 本番環境にAPIキーを渡せていないのかも?(仮説) 本番環境からは.envファイルを参照できない! 本番環境にも、APIキーを隠して渡す config.credentials.yml.encファイルにAPIキーを記述 ローカルのターミナル EDITOR=vi rails credentials:edit #vimでファイルを開く config/credentials.yml.enc google_map_api_key: xxxxxxxxxxxxxxxxxxxxxxxx #APIキーを追記 ビューで、config/credentials.yml.encファイルの記述を読み取る map.html.erb <script src="https://maps.googleapis.com/maps/api/js?key=<%= Rails.application.credentials.google_map_api_key %>&callback=initMap" async defer></script> #<%= Rails.application.credentials.google_map_api_key %> #これで「config.credentials.yml.enc」ファイルの「google_map_api_key」を取得できる キーの読み取り方(記述の違い) <%= Rails.application.credentials.google_map_api_key %> #credentials.yml.encファイルからキー取得 <%= ENV['google_map_api_key'] %> #.envファイルからキー取得 Google Mapが表示されない時の確認事項 取得したAPIキーをhtml内に記述しているか 支払い情報を登録しているか 請求先アカウントを未設定の場合、マップが1日1回しか表示できないらしい 表示回数の制限「割り当て」が1回になっていないか 回数制限がかかっているとMapが表示エラーになる可能性がある 請求アカウントとプロジェクトがひも付いているか 参考 GoogleMapが表示されないエラーが出た時の対処法 Rails5.2から追加された credentials.yml.enc のキホン さいごに Google Maps API導入は比較的スムーズに設定できました。(ローカルで) マップがうまく読み込まれない主な原因は、Google Cloud Platformでの設定が多いようですが、 APIキーを本番環境に渡せていないのは盲点でした。 キーやパスワードの管理方法について、セキュリティ面を見直すいい機会とはなりました。 間違っている点がありましたら、ご指摘いただけるとありがたいです。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

マルチアカウント環境でAWS Configのルール非準拠判定の通知を一元化させてみた

はじめに AWSのマルチアカウントでのシステム構成も増えてきて、サービスの役割ごとにアカウントを使い分けるケースもあるかと思います。 構成例として、Configルールは各アカウントで設定するが、メール通知やログ管理は一つのアカウントに集約させるといったような構成があげられます。 本記事では、アカウントA(送信側アカウント)で非準拠判定されたConfigルールを、アカウントB(受信側アカウント)のSNSトピックを利用してEメール通知させる設定方法について書いていきたいと思います。 構成図 アカウントAでAWS Configルールを「required-tags」で新規作成し、EC2インスタンスのタグに「Name」「Application」の2つが含まれているかを判定します。 判定結果が非準拠となると、アカウントAのEventBridgeで検知しアカウントBのEventBridgeへ連携され、紐づけられたSNSを使って対象者にメール通知されます。 (参考:AWS Configのルールで非準拠判定されたらメール通知したい) アカウントBをバージニアリージョンにしていますが、受信側のイベントバスがバージニア、オレゴン、アイルランドリージョンに限定されてしまっているためです。 (参考:AmazonEventBridgeを使用したクロスリージョンイベントルーティングの紹介) 今回は送信側のアカウントAを東京リージョン、受信側のアカウントBをバージニアリージョンで構築していきます。 構築順 本記事では以下の流れで環境構築を進めていきます。 アカウントA(送信側アカウント) 1. Configルール作成 アカウントB(受信側アカウント) 2. KMSキー(カスタマー管理型 以降CMK)作成 3. SNSトピック作成 4. EventBridge作成 アカウントA(送信側アカウント) 5. EventBridge作成 以下に詳細な構築手順を記載していくので、実際に構築していってみましょう。 環境構築手順 1. Configルール作成 アカウントAにログインし、東京リージョンを選択した状態でAWS Configに移動し、「ルールの追加」をクリックします。 ルールタイプ「AWSによって管理されるルールの追加」を選択します。 「required-tags」を検索し、チェックを入れて「次へ」をクリックします。 以下でルールの設定を行い、「次へ」をクリックします。 名前:任意の名前(ここでは「required-tags」) 説明:任意の説明(ここではデフォルトのまま) 変更範囲:リソース リソース:任意のリソース(ここでは「AWS EC2 Instance」) tag1Key:Name tag2Key:Application 上記以外は記載せず 「確認と作成」で設定内容を確認し、「ルールを追加」をクリックします。 無事ルールが作成されたことを確認します。 2. CMK作成 アカウントBにログインし、バージニアリージョンを選択した状態でKMSに移動します。カスタマー管理型のキーを選択し、「キーの作成」をクリックします。 以下でキーを設定し、「次へ」をクリックします。 キーのタイプ:対象 キーマテリアルオリジン:KMS 以下でラベルの追加をし、「次へ」をクリックします。 エイリアス:任意のエイリアス名(ここでは「test-sns」) ステップ3とステップ4はデフォルト設定のまま「次へ」をクリックします。 ステップ5のキーポリシーに以下の内容を記載し「完了」をクリックします。 { "Id": "key-consolepolicy-3", "Version": "2012-10-17", "Statement": [ { "Sid": "Enable IAM User Permissions", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::<Account B>:root" }, "Action": "kms:*", "Resource": "*" }, { "Sid": "Allow_EventBridge_for_CMK", "Effect": "Allow", "Principal": { "Service": "events.amazonaws.com" }, "Action": [ "kms:Decrypt", "kms:GenerateDataKey" ], "Resource": "*" } ] } ※「"Sid": "Allow_EventBridge_for_CMK"」以降の設定を記載することで、EventBridgeからKMSへのアクセスを許可します。見落としがちですが、SNSの暗号化をCMKで行う場合は、KMSのキーポリシーが原因で想定通りに動作できないといったことも起こり得るので設定内容には注意しましょう。 無事CMKが作成されたことを確認します。 3. SNSトピック作成 3-1.トピック作成 アカウントBにログインし、バージニアリージョンを選択した状態でAmazon SNSに移動し、トピックを選択し「トピックの作成」をクリックします。 詳細は以下の設定を行います。 タイプ:スタンダード 名前:任意の名前(ここでは「test-sns」) 表示名:任意の表示名(ここでは「AWSConfig-NON_COMPLIANT」) 暗号化は以下の設定を行います。 暗号化:暗号化の有効化 カスタマーマスターキー(CMK):「2. CMK作成」で作成したKMSキー(ここでは「alias/test-sns」) アクセスポリシーは以下の設定を行います。 メソッドの選択:高度な JSONエディタ:以下テキスト { "Version": "2008-10-17", "Id": "__default_policy_ID", "Statement": [ { "Sid": "__default_statement_ID", "Effect": "Allow", "Principal": { "AWS": "*" }, "Action": [ "SNS:Publish", "SNS:RemovePermission", "SNS:SetTopicAttributes", "SNS:DeleteTopic", "SNS:ListSubscriptionsByTopic", "SNS:GetTopicAttributes", "SNS:Receive", "SNS:AddPermission", "SNS:Subscribe" ], "Resource": "arn:aws:sns:us-east-1:<Account B>:test-sns", "Condition": { "StringEquals": { "AWS:SourceOwner": "<Account B>" } } }, { "Sid": "AWSEvents_Allow", "Effect": "Allow", "Principal": { "Service": "events.amazonaws.com" }, "Action": "sns:Publish", "Resource": "arn:aws:sns:us-east-1:<Account B>:test-sns" } ] } ※「"Sid": "AWSEvents_Allow"」以降の設定を記載することで、EventBridgeからSNSへのアクセスを許可します。こちらもKMSのキーポリシー同様、アクセスポリシーが原因で想定通りに動作できないといったことも起こり得るので設定内容には注意しましょう。 無事トピックが作成されていることを確認します。 3-2.サブスクリプションの作成 3-1で作成したSNSトピックに移動し、サブスクリプションタブを開いた状態で「サブスクリプションの作成」をクリックします。 詳細は以下の設定を行い、「サブスクリプションの作成」をクリックします。 トピックARN:3-1で作成したSNSトピック(ここでは「test-sns」) プロトコル:Eメール エンドポイント:通知させるメールアドレス 以下のようなメールが届くので、メール本文中の「Confirm subscription」をクリックします。 ブラウザに遷移し、以下の画面が表示されることを確認します。 マネジメントコンソール上でも、ステータスが「確認済み」になったことを確認します。 4. EventBridge作成(受信側アカウントB) 4-1.イベントバスのアクセス設定 アカウントBにログインし、バージニアリージョンを選択した状態でEventBridgeに移動し、イベントバスのdefaultを開きます。 「アクセス許可を管理」をクリックします。 リソースベースのポリシーに以下テキストを記載し、「作成」をクリックします。 { "Version": "2012-10-17", "Statement": [{ "Sid": "allow_account_to_put_events", "Effect": "Allow", "Principal": { "AWS": "<Account A>" }, "Action": "events:PutEvents", "Resource": "arn:aws:events:us-east-1:<Account B>:event-bus/default" }] } ※このアクセス許可でアカウントAからのEventBridgeのアクセスを許可します。受信側のアカウントでは必要な設定となるので気を付けましょう。 イベントバスのARNは後述の5. EventBridge作成時に必要になるので、メモを取っておきましょう。 4-2.ルールの作成 ルールを開き、イベントバスに「default」が選択されている状態で「ルールを作成」をクリックします。 名前と説明は以下を設定します。 名前:任意の名前(ここでは「test-config」) 説明:任意の説明(ここではデフォルトのまま) パターンを定義は以下を設定します。 イベントパターンorスケジュール:イベントパターン イベント一致パターン:カスタムパターン イベントパターン:以下テキスト { "source": ["aws.config"], "detail-type": ["Config Rules Compliance Change"], "detail": { "messageType": ["ComplianceChangeNotification"], "configRuleName": [ "required-tags" ], "newEvaluationResult": { "complianceType": ["NON_COMPLIANT"] } } } ※「"configRuleName"」の箇所は、作成したConfigルール名によって適宜書き換えてください。 イベントバスがデフォルトのものが選択されていることを確認します。 ターゲットを選択は以下の設定を行います。 ターゲット:SNSトピック トピック:3-1で作成したSNSトピック(ここでは「test-sns」) 入力の設定:入力トランスフォーマー 入力トランスフォーマー 入力パス:以下①テキスト 入力テンプレート:以下②テキスト ①.txt { "awsRegion": "$.detail.awsRegion", "resourceId": "$.detail.resourceId", "awsAccountId": "$.detail.awsAccountId", "compliance": "$.detail.newEvaluationResult.complianceType", "rule": "$.detail.configRuleName", "time": "$.detail.newEvaluationResult.resultRecordedTime", "resourceType": "$.detail.resourceType" } ②.txt "発生時刻 : <time>" "ルール名 : <rule> " "リソースタイプ : <resourceType>" "リソースID : <resourceId>" "AWSアカウント : <awsAccountId>" "上記リソースが <compliance> 判定となりました。" "詳細は以下URLよりご確認ください。" "https://console.aws.amazon.com/config/home?region=<awsRegion>#/timeline/<resourceType>/<resourceId>/configuration" 上記入力が完了したら、「作成」をクリックします。 無事ルールが作成されていることを確認します。 5. EventBridge作成(送信側アカウントA) アカウントAにログインし、東京リージョンを選択した状態でEventBridgeに移動します。 ルールを開き、イベントバスでdefaultが選択されている状態で「ルールを作成」をクリックします。 「イベントバスを選択」までは4-2.ルールの作成と同様のものを設定します。(ここではルール名を「test-notice-config」とし、それ以外は4-2と同様の設定を行います。) ターゲットを選択は以下の設定を行います。 ターゲット:別のアカウントまたはリージョンのイベントバス イベントバス:「4-1.イベントバスのアクセス設定」で設定したイベントバスARN IAMロール:この特定のリソースに対して新しいロールを作成する。 ※IAMロールを別途手動で作成する場合は、アカウントBのイベントバスへのアクセスを許可する内容で作成された、以下IAMポリシーを含んだIAMロールを作成する必要があります。 { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "events:PutEvents" ], "Resource": [ "arn:aws:events:us-east-1:<Account B>:event-bus/default" ] } ] } ターゲットを選択まで設定が完了したら「作成」をクリックし、ルールの作成を行います。 無事ルールが作成されていることを確認します。 以上で環境構築は完了です。このあと動作確認をしていきます。 動作確認 今回はEC2インスタンスのタグに「Name」「Application」が含まれているか判定するConfigルールを作成しているので、 アカウントA側の任意のEC2インスタンスから、タグ「Application」を削除してみます。 EC2の画面を表示し、任意のEC2インスタンスを選択したら、「タグを管理」をクリックします。 キーがApplicationのタグを削除し、「保存」をクリックします。 Configの画面を表示し、1. Configルール作成で作成した「required-tags」を表示します。 アクションから再評価をクリックします。 数分後、非準拠のルールとしてApplicationタグを削除したEC2インスタンスが検知され、3-2.サブスクリプションの作成で設定したメールアドレスあてにメールが届くことを確認します。 以上で実装は完了です。 おわりに 今回はマルチアカウントのシステムで活用できる、Configで非準拠ルールが検知された際に他アカウントのSNSトピックでメール通知させる構成を作成してみました。 複数アカウントのマルチアカウントシステムとなる場合、各アカウントでSNSトピックを管理するよりも圧倒的に管理工数が削減できるかと思います。 また、メール通知させるメール本文をEventBridgeで設定できるのがよいですね。 通知に必要な情報をピックアップして本文をカスタマイズするのもよいと思います。 以下に本構成を検討する際に参考にしたURLを貼っておきますので、こちらもあわせてご参照ください。 参考記事 AWS リソースが準拠していない場合に AWS Config を使用して通知を受けるにはどうすればよいですか? AWS Configのルールで非準拠判定されたらメール通知したい AmazonEventBridgeを使用したクロスリージョンイベントルーティングの紹介 AWSアカウント間でAmazon EventBridgeイベントを送受信してみた
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

S3のクロスアカウントレプリケーション設定

前提 レプリケーション元のアカウントをA レプリケーション先のアカウントをB とする 手順 1. アカウントBにレプリケーション用のバケットを作成する このバケットには「プロパティ」からバージョニングの設定を行う また、必ずライフサイクルルールも設定しておく(これやっておかないと無限にバージョンが作られてめっちゃ料金かかります) 例えばこんな感じ(最新から3日前までのバージョンは保持する、最新バージョンが3日以上古くなったらストレージクラスをGlacierに移行する) 2. アカウントAのレプリケーションしたいバケットの「管理」からレプリケーションルールを作成する 「送信先」のアカウントIDにアカウントBのアカウントIDを入れる バケット名には先ほど作成したレプリケーション用のバケット名を入れる 「オブジェクト所有者を送信先バケット所有者に変更」にチェックを入れる IAMロールを作成もしくは選択する そのほかあれば設定し保存する 3. アカウントBのレプリケーション用のバケットの「管理」のレプリケーションルールから受信設定を行う レプリケーションルールのアクションから「レプリケートされたオブジェクトの受信」を選択 ソースバケットアカウントIDにアカウントAのIDを入れて「ポリシーの作成」をクリック 「ケットポリシーの表示」をクリックして、「オブジェクト所有者を送信先バケット所有者に変更するアクセス許可を含める」にチェックを入れる(忘れがちなので注意) 「設定の適用」をクリックして閉じる 4. しばらく待つとレプリケーションされます レプリケーションされない場合 ファイルに更新がないとレプリケーションされないらしいので(もともとあったファイルはレプリケーションされない)、適当なファイルを追加してみてください それでもされない場合は、レプリケーションしてほしいファイルのプロパティの「オブジェクト管理の概要」にある「レプリケーションステータス」を確認してください ステータスがFAILになってる場合、こちらを参考にしてみてください 参考
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Dockerコンテナ上でGreengrass(V1)を実行する

はじめに AWSはGreengrass Coreソフトウェアと依存関係がインストールされたDocker file、Dockerイメージを公開しています。 今回は、以下の公式ドキュメントを参考に、EC2上のDockerコンテナでGreengrassを実行します。 参考:Docker コンテナでの AWS IoT Greengrass の実行 1 環境構築 公式ドキュメントの「Prerequisites」を参考に、Greengrassを実行する環境を用意します。 今回は最終的に以下の構成となります。 1-1 ネットワーク設定 VPC周辺を以下の通り作成します。 なお、作業は東京リージョンで行い、サブネットはap-northeast-1aに作成しています。 ※詳細な手順は以下を参照のこと  参考:AWS上にエッジ環境を構築してGreengrass(V1)の動きを確認する - 1-1 ネットワーク周りの作成 作成するもの 詳細 VPC CIDR:10.0.0.0/16 サブネット CIDR:10.0.0.0/24 インターネットゲートウェイ VPCにアタッチする ルートテーブル 10.0.0.0/16 -> local , 0.0.0.0/0 -> IGW 1-2 インスタンスの作成 次に、今回Greengrassを動かすEC2インスタンスを作成します。 ※詳細な手順は以下を参照のこと  参考:AWS上にエッジ環境を構築してGreengrass(V1)の動きを確認する - 1-2 EC2インスタンスの作成 1.以下の通りセキュリティグループを作成する ※アウトバウンドルールはデフォルトのままとしている タイプ ポート範囲 ソース 備考 SSH 22 マイIP 自身の環境からEC2にSSH接続できるようにするため カスタムTCP 8883 任意の場所 IoT Coreとの通信用 2.インスタンスを以下の通り作成する 設定項目 選択した内容 AMI Amazon Linux 2 AMI(64ビット(x86)) インスタンスタイプ t2.micro ネットワーク ※作成したVPC サブネット ※作成したサブネット 自動割り当てパブリックIP 有効 セキュリティグループ ※作成したセキュリティグループ 3.yum upgrade と yum update を実施する $ sudo yum upgrade -y $ sudo yum update -y 4.タイムゾーンを変更する 参考:【Linux】タイムゾーン(Timezone)の変更 #タイムゾーンファイルの変更 $ sudo ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime #タイムゾーンが変更されていることを確認 $ date Wed Apr 14 18:29:31 JST 2021 #再起動後にUTCに戻ることを防ぐため /etc/sysconfig/clock を編集 $ sudo vim /etc/sysconfig/clock /etc/sysconfig/clock ZONE="Asia/Tokyo" UTC=false 1-3 DockerとAWS CLIのインストール 公式ドキュメントのPrerequisitesにある通り、DockerとAWS CLIをインストールします。 「AWS CLI version 2」タブの要件に従います。 1.Dockerをインストールする 参考:Amazon Linux2にDockerをインストールする #Dockerインストール $ sudo yum install -y docker #ec2-userをdockerグループに追加(コマンド実行後ログインし直す) $ sudo usermod -a -G docker ec2-user #バージョン確認 $ docker version Client: Version: 20.10.4 #中略 Server: Engine: Version: 20.10.4 #後略 #自動起動設定 $ sudo systemctl enable docker 2.AWS CLIをバージョン2にアップデートする 参考:Linux で AWS CLI バージョン 2 をインストールする #現在のバージョン確認 $ aws --version aws-cli/1.18.147 Python/2.7.18 Linux/4.14.225-169.362.amzn2.x86_64 botocore/1.18.6 #AWS CLI V1の削除 $ which aws /usr/bin/aws #AWS CLI V2のインストール $ curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" $ unzip awscliv2.zip $ sudo ./aws/install You can now run: /usr/local/bin/aws --version #インストールされたことの確認 $ aws --version aws-cli/2.1.38 Python/3.8.8 Linux/4.14.225-169.362.amzn2.x86_64 exe/x86_64.amzn.2 prompt/off 以上で以下の構成まで作成できました。 2 Amazon ECRからGreengrassコンテナイメージを取得する 公式ドキュメントに記載の通り、Greengrassのコンテナイメージを取得します。 参考:ステップ 1. Amazon ECR から AWS IoT Greengrass コンテナイメージを取得する 1.awsコマンドを実行するため、ユーザのクレデンシャル情報環境変数に設定する ※あるいはaws configureコマンドで設定を行う  なお、利用するIAMユーザには ecr:GetAuthorizationToken のポリシーがアタッチされている必要がある #環境変数の設定 $ export AWS_ACCESS_KEY_ID='AWSのアクセスキー' $ export AWS_SECRET_ACCESS_KEY='AWSのシークレットアクセスキー' #設定されていることの確認 $ echo $AWS_ACCESS_KEY_ID $ echo $AWS_SECRET_ACCESS_KEY 2.Greengrassのコンテナイメージをプルする #Amazon ECRレジストリにログイン $ aws ecr get-login-password --region us-west-2 | docker login --username AWS --password-stdin https://216483018798.dkr.ecr.us-west-2.amazonaws.com WARNING! Your password will be stored unencrypted in /home/ec2-user/.docker/config.json. Configure a credential helper to remove this warning. See https://docs.docker.com/engine/reference/commandline/login/#credentials-store Login Succeeded #Greengrassコンテナイメージを取得 $ docker pull 216483018798.dkr.ecr.us-west-2.amazonaws.com/aws-iot-greengrass:latest #取得結果 $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE 216483018798.dkr.ecr.us-west-2.amazonaws.com/aws-iot-greengrass latest d32ac0324f03 8 weeks ago 1.25GB 3.シンボリックリンクとハードリンクの保護を有効にする #rootユーザに切り替え(sudoで実行してもPermission Deniedになったため) $ sudo su - #/etc/sysctl.confに設定を追加 $ echo '# AWS Greengrass' >> /etc/sysctl.conf $ echo 'fs.protected_hardlinks = 1' >> /etc/sysctl.conf $ echo 'fs.protected_symlinks = 1' >> /etc/sysctl.conf 4.IPv4 ネットワーク転送を有効にする #ファイル末尾に「net.ipv4.ip_forward = 1」を追記 vim /etc/sysctl.conf #設定の反映 $ sysctl -p fs.protected_hardlinks = 1 fs.protected_symlinks = 1 net.ipv4.ip_forward = 1 3 GreengrassグループとCoreの作成 IoT CoreのマネジメントコンソールでGreengrassグループを作成します。 作成後、証明書とコアの設定ファイルを取得します。 参考:AWS IoT Greengrass の AWS IoT の設定 1.IoT Coreのマネジメントコンソールで Greengrass > クラシック(V1) > 「グループの作成」の順にクリック 2.「デフォルト作成を使用」をクリック 3.任意のグループ名を入力して「次へ」をクリック 4.任意のCoreの名前を入力して「次へ」をクリック 5.「グループとCoreの作成」をクリック 6.「これらのリソースはtar.gzとしてダウンロードしてください」をクリックしてセキュリティリソースを取得したら、「完了」をクリック ※ルートCAの取得はのちの手順で行う ※Greengrass CoreのソフトウェアはDockerイメージとして取得済なのでここでは不要 4 Greengrassをローカルで実行 セキュリティリソースをEC2インスタンスにアップロードし、Greengrass Coreを起動します。 1.先ほどダウンロードしたtar.gzファイルをEC2インスタンスにアップロードする ※今回はFileZillaを利用した 2.tar.gzファイルを解凍し、greengrass用のディレクトリに格納する #格納先のディレクトリを作成 $pwd /home/ec2-user $ mkdir greengrass #解凍する $ tar xzvf xxxxxxxxxx.tar.gz -C greengrass/ certs/xxxxxxxxxx.cert.pem certs/xxxxxxxxxx.private.key certs/xxxxxxxxxx.public.key config/config.json $ ls greengrass/ certs config 3.AmazonのルートCA証明書を取得する #モノの証明書、秘密鍵が格納されているディレクトリに移動 $ cd greengrass/certs/ #ルートCA証明書を取得 $ sudo wget -O root.ca.pem https://www.amazontrust.com/repository/AmazonRootCA1.pem $ ls root.ca.pem root.ca.pem 4.IoT Greengrassコンテナをを実行する #certs、configディレクトリをバインド、8883のフォワーディングなどを行い実行 $ docker run --rm --init -it --name aws-iot-greengrass \ --entrypoint /greengrass-entrypoint.sh \ -v '証明書を格納したディレクトリのパス':/greengrass/certs \ -v 'configファイルを格納したディレクトリのパス':/greengrass/config \ -p 8883:8883 \ 216483018798.dkr.ecr.us-west-2.amazonaws.com/aws-iot-greengrass:latest #成功すると以下の通り出力される grep: /greengrass/ggc/deployment/group/group.json: No such file or directory Setting up greengrass daemon Validating hardlink/softlink protection Waiting for up to 1m10s for Daemon to start Greengrass successfully started with PID: 12 5 検証用の各種設定 今回は、最終的にGreengrassデバイスからのMQTTメッセージで実行するLambdaを用意し、動作することを確認します。 これを検証するための準備を行います。 5-1 グループのLambda設定 公式ドキュメントの以下の引用の通り、GreengrassをDocker上で実行する場合は、Lambdaを「コンテナなし」で実行する必要があります。 対象グループのLambdaのデフォルト設定を先に変えておきます。 Docker コンテナで AWS IoT Greengrass で実行する場合、すべての Lambda 関数はコンテナ化を使用しないで実行する必要があります。このステップでは、グループのデフォルトのコンテナ化を [No container (コンテナなし)] に設定します。グループを初めてデプロイする前に行う必要があります。 引用元:ステップ 4. Greengrassグループに対して「コンテナなし」コンテナ化を構成する 1.IoT Coreのマネジメントコンソールで Greengrass > クラシック(V1) > グループ の順にクリック 2.対象のグループ名 > 設定 の順にクリック 3.「Lambda ランタイム環境」でデフォルトの Lambda 関数コンテナ化で「コンテナなし」を選択し、「デフォルトのLambda実行設定を更新する」をクリック 4.「続行」をクリック 5-2 Lambdaの作成 MQTTメッセージを受け取ったあとに以下の挙動をするLambdaを作成します。 ローカルのログファイルに書き込む IoT CoreにMQTTメッセージを送る 1.ローカルで以下のプログラムを作成する docker_test.py import greengrasssdk import logging import sys import json import datetime logger = logging.getLogger(__name__) logging.basicConfig(stream=sys.stdout, level=logging.DEBUG) client = greengrasssdk.client("iot-data") logfile = "/tmp/docker_test.log" def docker_test(event, context): date = datetime.datetime.now() timestamp = date.strftime("%Y-%m-%d %H:%M:%S") client.publish( topic="test/dockertest", payload=json.dumps( { "function": "docker_test", "message": "This is Test", "version": "1.0", "timestamp": timestamp } ) ) f = open(logfile, mode="a") f.write(timestamp + " success!\n") f.close() 2.以下で「AWS IoT Greengrass SDK for Python」をダウンロードし、「greengrasssdk」フォルダと先ほど作成したプログラムをまとめてzipファイルとして圧縮する GitHub:aws-iot-devise-sdk-for-python 3.Lambdaのマネジメントコンソール画面で 関数 > 「関数の作成」の順にクリック 4.以下の通り設定して「関数の作成」をクリック 一から作成 関数名:※任意の関数名を設定 ランタイム:Python3.7 5.アップロード元 > .zipファイル > アップロード > 先ほど作成したzipファイルを選択し、「保存」をクリックする 6.ランタイム設定の「編集」をクリックし、ハンドラを「[ファイル名].[関数名]」にして「保存」をクリック ※上記プログラムのファイル名を「docker_test.py」としていた場合は「docker_test.docker_test」となる 7.アクション > 新しいバージョンを発行 > 「発行」の順にクリック 8.エイリアスタブ > 「エイリアスを作成」の順にクリックして、任意のエイリアス名を入力し、先ほど発行したバージョンを選択して「保存」をクリック 5-3 Greengrassデバイスの用意 Docker上で動くGreengrass Coreと通信するGreengrassデバイスを用意します。 今回はこちらもEC2を利用して仮想デバイスという形で用意します。 1.IoT Coreのマネジメントコンソールで Greengrass > クラシック(V1) > グループ の順にクリック 2.対象のグループ名 > デバイス > 「デバイスの追加」の順にクリック 3.「新しいデバイスの作成」をクリック 4.任意のモノの名前を入力して「次へ」をクリック 5.1-Clickデプロイの「デフォルトを使用」をクリック 6.「これらのリソースはtar.gzとしてダウンロードしてください」をクリックしてファイルをダウンロードし、「完了」をクリック 7.Greengrassデバイス用に「1-2 インスタンスの作成」と同じ設定でEC2インスタンスを用意する ※VPC、サブネット、セキュリティグループは上記で指定したものと同じものを利用 8.インスタンスが起動したらsshで接続し sudo yum upgrade と sudo yum updateを行う 9.Greengrassデバイス用のインスタンスに先ほどダウンロードしたtar.gzファイルをアップロードして解凍する ※私はFileZillaを利用した #ファイル格納用のディレクトリを作成 $ pwd /home/ec2-user $ mkdir .certs #tar.gzファイルの解凍 $ tar xzvf xxxxxxxxxx-setup.tar.gz -C .certs xxxxxxxxxx.cert.pem xxxxxxxxxx.private.key xxxxxxxxxx.public.key 10.以下のPythonプログラムを作成、実行して、グループ証明書を取得 ※/home/ec2-user/.certs はいかにgroupCA.crtとしてグループ証明書を上書きで作成 get_groupCA.py import requests import json import argparse #get args psr = argparse.ArgumentParser( description = "get groupCA" ) psr.add_argument("-t", "--things", required=True, help="thing name") psr.add_argument("-c", "--cert", required=True, help="cert file") psr.add_argument("-k", "--key", required=True, help="private key") args = psr.parse_args() things = args.things cert = args.cert key = args.key #set variables for requests url = "https://greengrass-ats.iot.ap-northeast-1.amazonaws.com:8443/greengrass/discover/thing/" + things #set path for CA file CAfile = "/home/ec2-user/.certs/groupCA.crt" #get present group CA response = requests.get(url, cert=(cert, key)) #make groupCA file jsonData = response.json() groupCA = jsonData["GGGroups"][0]['CAs'][0] f = open(CAfile, "w") f.write(groupCA) f.close() $ python --things 'モノの名前' --cert 'モノの証明書' --key '秘密鍵' 11.MQTT通信用にmosquittoをインストールする $ sudo amazon-linux-extras install epel -y $ sudo yum install mosquitto -y 5-4 Greengrassグループの設定 Lambdaの実行、各通信のためにGreengrassグループの設定を行います。 Lambdaの設定 作成したLambdaをグループに紐づけます。 1.IoT Coreのマネジメントコンソールで Greengrass > クラシック(V1) > グループ の順にクリック 2.対象のグループ名 > Lambda > 「Lambdaの追加」の順にクリック 3.「既存のLambdaを使用」 > 作成したLambdaを選択して「次へ」 > 作成したエイリアスを選択して「完了」をクリック 4.追加されたLambdaの「…」 > 設定の編集 の順にクリック 5.設定の以下項目を設定して、「更新」をクリック コンテナ化:グループのデフォルトを使用(現在:コンテナなし) Lambdaのライフサイクル:オンデマンド関数 サブスクリプション 実行したLambdaからIoT Coreへのメッセージ、IoT CoreおよびGreengrassデバイスからLambdaへのメッセージをPub/Subできるようにサブスクリプションを追加します。 1.対象のグループでサブスクリプション > 「サブスクリプションの追加」の順にクリック 2.以下のサブスクリプションを作成する ソース ターゲット トピック Lambda IoT Core test/dockertest ※Lambda内で指定したtopic IoT Core Lambda ※任意のtopic Greengrassデバイス Lambda ※任意のtopic コアの接続情報検出設定 コンテナ上のGreengrass Coreの接続情報を手動で設定します。 ※自動検出にした場合、コンテナ内のIPのみに上書きされてしまい、GreengrassデバイスからEC2インスタンスのIP宛にメッセージを送っても受け取ることができなかった 1.対象のグループで 設定 をクリック 2.Core接続情報を「接続情報の手動管理」に変更する 3.対象のグループで コア > コア名 の順にクリック 4.接続 > 編集 の順にクリック 5.接続情報を追加して「更新」をクリック エンドポイント:※Greengrassコンテナを動かしているEC2インスタンスのローカルIP ポート:8883 5-5 ログの格納先作成 Lambdaがログを書き出す先はコード上はGreengrassコンテナの/tmpとしています。 ここで書き出されたログファイルがコンテナ終了後も残るように、コンテナ上の/tmpとマッピングするローカルディレクトリを用意します。 1.Greengrassコンテナを動かすEC2インスタンスにsshで接続してディレクトリを作成する $ cd /home/ec2-user/greengrass $ mkdir tmp $ ls certs config log #コンテナ上でLambdaが書き込めるように全権を付与 $ chmod 777 log 2.Greengrassコンテナを起動中のターミナルで Ctrl + C を実行してコンテナを停止する ※これで上手くいかない場合は docker ps -a でコンテナIDを控えて、docker stop [控えたコンテナID] で停止する 3.先ほど作成したディレクトリとコンテナ上の /tmp をマッピングして再度コンテナを起動する docker run --rm --init --name aws-iot-greengrass \ --entrypoint /greengrass-entrypoint.sh \ -v /home/ec2-user/greengrass/certs:/greengrass/certs \ -v /home/ec2-user/greengrass/config:/greengrass/config \ -v /home/ec2-user/greengrass/tmp:/tmp \ -p 8883:8883 \ 216483018798.dkr.ecr.us-west-2.amazonaws.com/aws-iot-greengrass:latest 以上の手順が完了したらGreengrassグループをデプロイする。 ※AWS上で設定したグループの情報はコンテナを停止→起動するたびにデプロイが必要 デプロイによって、予定していた以下の構成となります。 6 検証 MQTTメッセージをトリガとしてコンテナ上のGreengrassがLambdaを実行できることを確認します。 6-1 IoT Core -> Lambdaで検証 IoT CoreからのMQTTメッセージをトリガとしてLambdaを実行できることを確認します。 1.IoT Coreのマネジメントコンソールで テスト をクリック 2.トピックのフィルターに「test/dockertest」と入力し、「サブスクライブ」をクリック ※Lambda内で指定しているtopic 3.トピックに公開するタブに移動し、トピック名にサブスクリプションで指定したtopicを入力し、「発行」をクリック 4.以下を確認 IoT Coreでメッセージをサブスクライブできる Greengrassコンテナを動かしているEC2のローカルにログファイルが書き出されている 6-2 Greengrassデバイス -> Lambda で検証 次にGreengrassデバイスからのMQTTメッセージでLambdaが実行されることを確認します。 この検証は、コンテナ上のGreengrassとGreengrassデバイスが通信できることの確認も含んでいます。 1.先ほどの検証で開始したIoT Coreのサブスクライブはそのままとする 2.Greengrassデバイス用のEC2に接続してMQTTをパブリッシュする mosquitto_pub --cafile 'グループ証明書' --cert 'モノの証明書' --key '秘密鍵' \ -i 'モノの名前' --tls-version tlsv1.2 \ -h 'Greengrassコンテナを動かしているEC2インスタンスのローカルIP' -p 8883 \ -q 0 -t 'サブスクリプションで指定したtopic' \ -m "{\"message\":\"Helloworld\"}" -d 3.同じく以下を確認 IoT Coreでメッセージをサブスクライブできる Greengrassコンテナを動かしているEC2のローカルにログファイルが書き出されている 7 おわりに 以上、Dockerコンテナ上で動くGreengrass(V1)の挙動を簡単に確認しました。 GreengrassデバイスからCoreへの通信がハマりどころでした。 自動検出を有効にしていたためにコンテナのローカルIPがGreengrass Coreの接続情報とされており、通信が成功しませんでした。 ※手順でも記載した通りですが、Greengrass Coreの接続情報としてEC2インスタンス自体のローカルIPを静的に指定することで解消 8 参考文献(文中で登場していないもの) Dockerコンテナ上でGreengrassを動かしている記事 GreengrassをDocker for Windows上で使用する準備とファイル読み出しテストの手順 「#2 Amazon ECRからGreengrassコンテナイメージを取得する」で実行している内容について Linux豆知識197 /etc/sysctl.conf Dockerはサービス起動時に勝手にIPフォワーディングを有効にする CentOS / RHEL 7でハードリンクおよびシンボリックリンクを保護する方法 - Centos - 2021 Docker周辺で参考にした記事 「Got permission denied while trying to connect to the Docker daemon socket」への対応 dockerでvolumeをマウントしたときのファイルのowner問題
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWSソリューションアーキテクトアソシエイト受験記

2021年4月中旬にAWSソリューションアーキテクトアソシエイトを受験してきたので、 備忘録の意味も込めて、やってきたことをまとめます。 AWSソリューションアーキテクトアソシエイトとは AWS認定の資格試験です。 ソリューションアーキテクトアソシエイトは1年間の業務経験を積んだ中級者向けの試験です。 気になる方は、以下URLから詳細をご確認ください。 AWS 認定 ソリューションアーキテクト – アソシエイト 受験の背景 この資格試験を受験しようと思った背景は以下です。 日頃業務でクラウドサービスを利用している 内訳としては AWSを1年程度(2年前)、Azureを2年半程度 しかし資格を何一つ持ってない 自分の実力を測ってみたかった 自社でAWS資格試験取得を推進している クラウドサービスの最新動向が知りたい 経歴としてはAzureの方が長く触っていましたが、クラウドサービスの考え方を学んだのはAWSで、個人的にAWSの方が好きだったため、先にAWSの資格試験を受験しました。 5〜6月にAzureの資格試験も受験しようと思ってるので、そちらも受験後に記事を書こうと思ってます。 受験前にやったこと 私が受験前にやったことは、オンライン問題集を使っての勉強がメインでした。 問題を解いてわからないことがあったらひたすらドキュメントを読み、理解を深めていきました。 勉強期間としては2週間程度です。 使用教材としては以下2つです。 udemyの問題集 【SAA-C02版】AWS 認定ソリューションアーキテクト アソシエイト模擬試験問題集(6回分390問) koiwaclubの問題集 それぞれの解いてみた感想を次に書きます。 udemyの問題集 この問題集は、難易度の高い問題を集めたものということもあって、かなり難しかったです。 そして何より、AWSにほとんど触れていなかった期間が2年ほどあり、その間でサービスがどんどん新しくなっていたため、空白期間を埋めるのに一苦労しました。 初回に解いた際のスコアは以下でした。(合格は72%です) 試験番号 正答率 1 75% 2 56% 3 52% 4 70% 5 61% 6 56% 各回解いてから、わからなかった問題や気になった問題を中心にドキュメントを読みました。 そして自分なりの解釈をひたすらノートに書き起こし、読み上げ、耳で聞くという五感をフル活用した覚え方をしてました。 (高校・大学受験をちょっと思い出しました) koiwaclubの問題集 有料会員登録するとソリューションアーキテクトアソシエイト対策の問題を約1000問見ることができます。 一問ずつ短時間で解けるので、隙間時間に問題が解けるというのがとてもよかったです。 私の場合、勉強期間を短く設定してしまったため、全ての問題をゆっくり勉強する余裕がなかったので、降順に解いてわからない問題を重点的に振り返る方針で進めました。 結果 結果として、ギリギリのスコアで合格できました。 今回この資格試験を通して学んだこととしては、AWSの最新情報は常にキャッチアップしていかなければ取り残されるということです。 「別のクラウドサービスを使ってるから大丈夫だろう」という気持ちは取っ払い、常に最新情報をキャッチアップしていこうと思います。 まずはRSSを使って自分のスマホに通知する仕組みづくりからやっていこうと思います。 これから受験を考えられている方の参考になれば幸いです。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

CodeDeployを使ってアプリケーションをEC2インスタンスへデプロイする

はじめに CodeDeployを使ってEC2インスタンスへアプリケーションをデプロイしたいと思います。 基本的にはコマンドラインを利用しますが、一部難しい部分があるためそこはコンソール操作で行います。 前提条件 以下の準備ができている上で作業を行います。 GitHub アカウント: アプリケーションのアップロード先を用意するのに必要です。 EC2インスタンス: アプリケーションのデプロイ先で利用します。 IAMロールがアタッチされていること。 sshとhttpアクセスができること。 コマンドインストール gitコマンド: リポジトリへプッシュするのに必要です。 aws-cli: CodeDeployやIAMロールを作成するのに利用します。 構成 作業 まずはGitHub関連の設定を行い、その後にCodeDeployの設定を行なっていきます。 GitHub リポジトリの準備 GitHubへログインし [ New ] をクリックします。 Repository name に CodeDeployGitHubDemo を入力し、Public を選択して [ Create repository ] をクリックします。 コマンドラインでリポジトリの初期コミットを行います。 作業ディレクトリの用意 $ mkdir /tmp/CodeDeployGitHubDemo $ cd /tmp/CodeDeployGitHubDemo READMEの作成 $ touch README.md init $ git init add $ git add README.md commit $ git commit -m "My first commit" remote $ git remote add origin https://github.com/************/CodeDeployGitHubDemo.git push $ git push -u origin master 以上でリポジトリの準備が完了です。 アプリケーションをGitHubリポジトリへアップロード 今回はAWSで提供しているサンプルアプリケーションを利用します。 作業は先ほどgitで準備をしたディレクトリで行います。 まず、アプリケーションをダウンロードします。 アプリケーションのダウンロード $ aws s3 cp s3://aws-codedeploy-ap-northeast-1/samples/latest/SampleApp_Linux.zip . --region ap-northeast-1 リポジトリへアップロードをします。 展開 $ unzip SampleApp_Linux.zip $ rm SampleApp_Linux.zip add $ git add . commit $ git commit -m "Added sample app" push $ git push 以上でアップロードが完了です。 また、CodeDeployでは appspec.yml というファイルが必要になります。 今回ダウンロードしたコンテンツにはこのファイルが存在するため、そのまま利用します。 appspec.yml version: 0.0 os: linux files: - source: /index.html destination: /var/www/html/ hooks: BeforeInstall: - location: scripts/install_dependencies timeout: 300 runas: root - location: scripts/start_server timeout: 300 runas: root ApplicationStop: - location: scripts/stop_server timeout: 300 runas: root ファイルの詳細説明は割愛しますが、簡単に説明すると apacheをインストール して index.html を配置しています。 CodeDeployエージェントのインストール インスタンスにサインインし、エージェントをインストールします。 まずはエージェントをインストールするために必要なパッケージのインストールです。 必要パッケージのインストール $ sudo yum install ruby $ sudo yum install wget エージェントインストールツールのダウンロードを行います。 インストールツールのダウンロード $ wget https://aws-codedeploy-ap-northeast-1.s3.ap-northeast-1.amazonaws.com/latest/install --2021-04-22 05:30:49-- https://aws-codedeploy-ap-northeast-1.s3.ap-northeast-1.amazonaws.com/latest/install aws-codedeploy-ap-northeast-1.s3.ap-northeast-1.amazonaws.com (aws-codedeploy-ap-northeast-1.s3.ap-northeast-1.amazonaws.com) をDNSに問いあわせています... 52.219.16.215 aws-codedeploy-ap-northeast-1.s3.ap-northeast-1.amazonaws.com (aws-codedeploy-ap-northeast-1.s3.ap-northeast-1.amazonaws.com)|52.219.16.215|:443 に接続しています... 接続しました。 HTTP による接続要求を送信しました、応答を待っています... 200 OK 長さ: 17231 (17K) [] `install' に保存中 100%[==============================================================================================================================>] 17,231 --.-K/s 時間 0s 今回は東京リージョンですが、もし他のリージョンの場合は aws-codedeploy-ap-northeast-1 と ap-northeast-1 の部分を以下を参考に変更してください。 地域別のリソースキットバケット名 インストールを行います。 実行権限付与 $ chmod +x ./install エージェントインストール $ sudo ./install auto インストールが完了したら以下のコマンドで起動していることを確認しておきます。 インストール確認 $ sudo service codedeploy-agent status The AWS CodeDeploy agent is running as PID 7801 以上でCodeDeployエージェントのインストールが完了ですが、たまにうまく起動していない場合があるのでログを確認しておくと良いです。 codedeploy-agent.log $ tail -f /var/log/aws/codedeploy-agent/codedeploy-agent.log もし、以下のエラーが出力されていた場合、エージェントがIAMロールをうまく認識できずに起動している状態になります。 ERRORログ 2021-04-22 11:27:13 ERROR [codedeploy-agent(6387)]: InstanceAgent::Plugins::CodeDeployPlugin::CommandPoller: Missing credentials - please check if this instance was started with an IAM instance profile IAMロールがインスタンスにアタッチされていることを確認した上でエージェントの再起動をしてください。 今回はS3アクセスが不要なため、ロールに必要な権限はありませんが、付与されていないとエージェントエラーとなりCodeDeployを実行した際に失敗となってしまいます。 CodeDeploy で利用するサービスロールの作成 まず、ロールを作成するのに必要な信頼ポリシーを用意します。 信頼ポリシーの作成 $ vim trust-policy.json trust-policy.json { "Version": "2012-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "Service": "codedeploy.amazonaws.com" }, "Action": "sts:AssumeRole" } ] } ポリシーを作成したらサービスロールを作成します。 サービスロールの作成 $ aws iam create-role \ --role-name CodeDeployGitHubDemo-Role \ --assume-role-policy-document file://trust-policy.json CodeDeploy で利用するポリシーをアタッチします。 ポリシーのアタッチ $ aws iam attach-role-policy \ --role-name CodeDeployGitHubDemo-Role \ --policy-arn arn:aws:iam::aws:policy/service-role/AWSCodeDeployRole 以上でロールの準備ができました。 CodeDeploy の設定 デプロイするためのアプリケーションとデプロイグループの作成を行います。 アプリケーションの作成 アプリケーション名は CodeDeployGitHubDemo-App で作成します。 アプリケーションの作成 $ aws deploy create-application --application-name CodeDeployGitHubDemo-App デプロイグループの作成 アプリケーションを作成したらデプロイグループの作成です。 デプロイグループ名は CodeDeployGitHubDemo-DepGrp にします。 また、対象インスタンスを指定するためのタグキーに CodeDeploy を指定し、バリューを Demo を設定します。 これで、CodeDeployタグにDemoという値が設定されているインスタンスに対してデプロイ処理が行われるようになります。 デプロイグループの作成 $ aws deploy create-deployment-group \ --application-name CodeDeployGitHubDemo-App \ --ec2-tag-filters Key=CodeDeploy,Type=KEY_AND_VALUE,Value=Demo \ --deployment-group-name CodeDeployGitHubDemo-DepGrp \ --service-role-arn arn:aws:iam::123456789012:role/CodeDeployGitHubDemo-Role デプロイの作成 GitHub連携を行う都合上、初めはコンソールから行う必要があります。 まずは [ デプロイの作成 ] をクリックします。 先ほど作成した デプロイグループ を指定し、リビジョンタイプ のところではGitHubを指定します。 GitHubトークン名 に先ほどアップロードしたGitHubのアカウントを入力すると GitHubに接続 がクリックできるようになるためクリックします。 すると以下のポップアップが表示されるため [ Authorize aws-codesuite ] をクリックします。 次に [ 確認 ] をクリックします。 成功すると リポジトリ名 と コミットID が表示されるので入力し、一番下にある [ デプロイの作成 ] をクリックして完了です。 以下のような画面へ遷移し、進行中 が 成功 になれば無事にデプロイ完了となります。 ブラウザから対象インスタンスへアクセスすると以下の画面が確認できます。 また、一度GitHub連携できていれば2回目以降はコマンドで実行可能になります。 $ aws deploy create-deployment \ --application-name CodeDeployGitHubDemo-App \ --deployment-config-name CodeDeployDefault.OneAtATime \ --deployment-group-name CodeDeployGitHubDemo-DepGrp \ --description "My GitHub deployment demo" \ --github-location repository=************/CodeDeployGitHubDemo,commitId=7e0a45963967c307d837477e74f5d34798a65e68 おわりに 今回、S3を利用しないためIAMロールは不要と思ったのですがないとうまく動かないことがわかりました。 基本を知ることで、一つ一つの設定について理解を深めることができて良かったです。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

minikubeインストール時のエラー解決方法【Kubernetes】

上記サイトに従ってminikubeをインストールしていたところ、エラーにぶち当たったため解決方法を共有します。 エラー1 Exiting due to GUEST_MISSING_CONNTRACK: Sorry, Kubernetes 1.20.2 requires conntrack to be installed in root's path 解決方法1 エラーメッセージに従って、conntractをインストールします。 $ sudo apt install conntrack エラー2 Exiting due to RSRC_INSUFFICIENT_SYS_MEMORY: System only has 953MiB available, less than the required 1800MiB for Kubernetes 解決方法2 EC2インスタンスのスペックに問題があったようです。 t3.micro から t3.midium に変更することにより、対処することができました。 それでは、チュートリアルをお楽しみください。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWSでエラー【Redirecting to /bin/systemctl start mysqld.service】sudo service mysqld start 実行時

タイトルの通りのエラーが発生し、mysqlが起動できない 問題を探す 1. 別のDBがインストールされている? 確か、mariaというDBが最初から入っている、と聞いたことがあるので、もしかしたらそれかもしれない。下記実行。 $ yum list installed | grep mariadb 何も表示されない。問題はここじゃない。 2. そもそもmysql はインストールされているよね? mysqld --version *実行 mysql Ver 8.0.24 for Linux on x86_64 (MySQL Community Server - GPL) *結果 mysql 8.0.** は確かに存在している。 3. インスタンス起動時は自動起動するようにしてみる $ sudo systemctl start mysqld.service $ sudo systemctl enable mysqld.service これで起動してないだろうか。 再度、下記実行 sudo service mysqld start Redirecting to /bin/systemctl start mysqld.service 結果は変わらず。 mysql のステータス確認 下記実行。 systemctl status mysqld.service 結果: mysqld.service - MySQL Server Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled; vendor preset: disabled) Active: active (running) since Thu 2020-06-04 06:12:59 UTC; 6min ago Docs: man:mysqld(8) http://dev.mysql.com/doc/refman/en/using-systemd.html Process: 11780 ExecStartPre=/usr/bin/mysqld_pre_systemd (code=exited, status=0/SUCCESS) Main PID: 11854 (mysqld) Status: "Server is operational" CGroup: /system.slice/mysqld.service └─11854 /usr/sbin/mysqld 「Active: active (running)」だから、起動しているのでは? じゃあ、Redirecting to /bin/systemctl start mysqld.service ってなんだ?? 結論 Redirecting to /bin/systemctl start mysqld.serviceはエラーじゃないっぽい。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【AWS】【超初心者ハンズオン】3. AWS API Gatewayによって、パラメータを含むHttpGetRequestをトリガーとしてLambdaを実行する

【AWS】【超初心者ハンズオン】 シリーズ シリーズ概要 前の記事: 2. AWS API Gatewayによって、URLへのアクセスをトリガーとしてLambdaを実行する この記事の目的 パラメータを含んだURLにアクセスした際のHttpGetRequestをトリガーとして、AWS Lambdaを実行する API GatewayとLambdaの間での変数の受け渡しのイメージを理解する 手順 URLにパラメータを付加して、GETメソッドを行う GETを行った時のログを見る json形式の応答からパラメータを取り出し、Lambdaに入力する AWS API Gatewayってどういうサービスなの?(おさらい) 前回、API Gatewayを触って、"URLアクセスをトリガーにして、AWS Lambdaを実行する"ということを行いました。 API Gatewayが"HTTP APIやWebsocket APIによって、AWSに展開された他のサービスをトリガーすること"ができるサービスだということの片鱗を理解できたのではないでしょうか。 Amazon API Gateway は、あらゆる規模の REST、HTTP、WebSocket API を作成、公開、管理、モニタリング、保護するための AWS のサービスです。 Amazon API Gateway とは何ですか? URLにパラメータを付加して、GETメソッドを行う 参考: ページリンクのURLにパラメーターをつける ここではURLにて、min、maxのパラメータを指定した上で、URLにアクセスします https://hogehoge.execute-api.ap-northeast-1.amazonaws.com/random_integer_generator_001?min=100&max=1000 min = 100 max = 1000 としてみました.> 結果: 0~9までの整数しか返ってきません 原因: URLに付加されたパラメータを、Lambda側で受け取っていないため GETを行った時のログを見る URLを開いたとき、API GatewayにはGetRequestが送られ、Lambdaがトリガーされます。 Lambda内には、どのようなRequestが送られたのかをログとして表示する部分を仕込んでいるため、ログが見れるはずです。 ログはどこにprintされているかというと... 0~9の間の整数をランダムに1つ返す import json def lambda_handler(event, context) -> int: print("Received event: " + json.dumps(event, indent=2)) ログを見てみよう 下図、'モニタリング' -> 'CloudWatchのログを表示'と開いてください。 'ログストリーム'にて、これまでLambdaを実行したときのログが表示されます。 さきほどURLに $min=100&max=1000 と付加した際のログを見ると、下記のような部分がjsonオブジェクトに含まれていることがわかります。 queryStringParameters"というkeyの中に、"max", "min"が"というkeyがある "max", "min"に対応するvalueは、int型ではなくstr型になる { "queryStringParameters" : { "max": "1000", "min": "100" } } json形式の応答からパラメータを取り出し、Lambdaに入力する Lambdaに対して、URLに付加されたパラメータを入力できるよう、Lambdaを以下のように変更しました。 -lambda_handlerはeventとしてjsonオブジェクトを受け取る -logから明らかなように、event内に"queryStringParameters"が、その中に"min", "max"がある -忘れずにint型に変換する URLに受け取ったmin,maxの範囲の整数を返す import json import random print('Loading function') def lambda_handler(event, context) -> int: print("Received event: " + json.dumps(event, indent=2)) int_min = int(event["queryStringParameters"]["min"]) int_max = int(event["queryStringParameters"]["max"]) generated_int = random.randrange(int_min, int_max, 1) return generated_int もう一度URLにパラメータを付加して、GETメソッドを行う URL呼び出し結果 190 狙い通り、URLに付加したmin, maxの範囲の値が返ってきましたね。 この先やること URLに手入力でパラメータを与えるのは流石にアレなので、ユーザーフォームを作成してmin, maxの値を入力できるようにする
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[AWS]ssh: connect to host xxx.xxx.xxx.xxx port 22: Operation timed outを解消

今回はこちらの記事を参考にさせていただきました。 エラー内容 EC2でSSH接続をしようとした所エラー発生 ssh: connect to host xxx.xxx.xxx.xxx port 22: Operation timed out 結論 元々作業していた所からコワーキングスペースに移動した為エラーが起きた。 要するにEC2インスタンスのセキュリティグループ、SSH接続設定と自分の接続元(IPアドレス)に問題があった。 具体的にはEC2のインスタンスのセキュリティのインバウンドルールのSSH接続のソースを「マイIP」に設定した。これにより、設定した作業場所じゃないとSSH接続ができなくなってしまう。 コワーキングスペースに移動すると接続元のIPアドレスが変わってしまった為、接続元が許可されずエラーになった。 解決方法 AWSのサービス検索欄から「EC2」を検索 「セキュリティグループ」を選択 該当EC2インスタンスにチェック インバウンドルールから「インバウンドルールを編集」を選択 タイプSSHのソースで「マイIP」を選び直す。※推奨 もしくは「任意の場所」にを選ぶ ルールを保存をクリック こうすると、作業場所のIPアドレスからのSSH接続を許可したことになります。 $ ssh -i .ssh/ファイル名.pem ec2-user@xxx.xxx.xxx.xxxa #EC2インスタンスのパブリックIP なぜ「マイIP」が推奨かというと万が一SSHキーが流出し時の危険性を考えるとこちらの方がセキュアだからです。 毎回接続元を変えなければならないのは面倒ですが、もし流出してしまった場合はAWSから高額請求がくることがあるのでここで保険を打っておいた方が無難ですね。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Rails & AWS]https化によるNginxの設定

はじめに AWSのEC2で上げているRailsアプリをHTTPS化したのでメモとして残しておきます。 画像なしで説明しますのであしからず。 少しだけrailsのファイルの設定もしていきます。 Nginxとは HTTPおよび、HTTPSでのアクセスに使われる軽量サーバーのことでWebサーバーとしての基本的な機能を持っています。 Nginxの設定 以下のファイルを編集します /etc/nginx/nginx.conf httpでアクセスされたものをhttpsへリダイレクトする記述へ変更します。 EC2サーバー環境 $ sudo vim /etc/nginx/nginx.conf server { listen 80 default_server; listen [::]:80 default_server; server_name www.hogehoge.com; #ドメイン名に変更 root /usr/share/nginx/html; # Load configuration files for the default server block. include /etc/nginx/default.d/*.conf; location / { } error_page 404 /404.html; location = /404.html { } error_page 500 502 503 504 /50x.html; location = /50x.html { } } ドメイン名を記述したら:wqで保存します。 次にRailsアプリに移動します。 そして/config/environments/production.rbファイルを編集します EC2サーバー環境 $ sudo vim /config/environments/production.rb /config/environments/production.rb config.force_ssl = true これをすることで常時SSL化対応となります。 NginxとUnicornの再起動 Nginxの再起動 EC2サーバー環境 $ sudo service nginx restart 次にUnicornを再起動させます。 まずUnicornの起動を確認 EC2サーバー環境 $ ps -ef | grep unicorn | grep -v grep ryogo 11658 1 0 4月24 ? 00:00:02 unicorn_rails master -c /var/www/rails/travelour/config/unicorn.conf.rb -D -E production ryogo 11662 11658 0 4月24 ? 00:00:02 unicorn_rails worker[0] -c /var/www/rails/travelour/config/unicorn.conf.rb -D -E production ryogo 11663 11658 0 4月24 ? 00:00:02 unicorn_rails worker[1] -c /var/www/rails/travelour/config/unicorn.conf.rb -D -E production 表示されたUnicornの番号をkillします。 1行目の11658のみkillすれば良いです EC2サーバー環境 $ kill 11658 Unicornを再度起動させます。 EC2サーバー環境 $ bundle exec unicorn_rails -c /var/www/rails/アプリ名/config/unicorn.conf.rb -D -E production これでhttpsでドメインにアクセスできるようになります。 EC2サーバー環境 https://www.hogehoge.com 参考
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[AWS]https化によるRoute53の設定

はじめに AWSのEC2で上げているRailsアプリをHTTPS化したのでメモとして残しておきます。 画像なしで説明しますのであしからず。 また今回はアプリを既にEC2に上げている(HTTPで)、ACM(AWS Certificate Manager)でSSL証明書を取得している、ロードバランサーでHTTPSのアクセス許可をしている前提とします。 Route53で作成したホストゾーンのレコードからタイプAの編集 ※ちなみにレコードタイプAとは「Address」頭文字。ドメインに対するIPv4アドレスを登録している。 サービス検索欄から「Route53」と入力し検索します。 「ホストゾーン」を選択して作成済みの「ドメイン名」を選択します。 その中の「タイプA」の「www.ドメイン名」のレコードにチェックを入れて「レコードを編集」をクリックします。 以下のように項目を修正します 名前:「www.ドメイン名」 レコードタイプ:「A-IPv4アドレス」 エイリアス : バーをクリックして有効にする トラフィックのルーティング先 :「Application Load Balancer と Classic Load Balancerへのエイリアス」→「アジアパシフィック(東京)[ap-northeast-1]」→「アプリ名-ELBを選択」 「保存」を選択 参考
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む