20220224のAWSに関する記事は19件です。

Route53にサブドメインを登録する手順

はじめに ドメイン周りの設定、期間が空くと忘れがちですよね。 (自分だけかもしれないですが) なので今回はGoogle Domainにて取得済みのドメインのサブドメインをRoute53にて管理し、証明書の取得までの流れを記録しておきます。 当記事にて記載されているスクリーンショットは2022年2月24日現在時点でのものになります。閲覧時期によってはレイアウト等が変更されている可能性がありますのでご注意を。 前提条件 AWSのアカウントを所持している Google Domain等のドメインサービスにて独自ドメインを所持している サブドメインを登録する こちら(Route53)にアクセスし 右上のホストゾーンの作成をクリック ドメイン名は {登録したいサブドメイン名}.{取得しているドメイン名}を入力してください 他の部分は変更せずにホストゾーンの作成をクリック ホストゾーンの詳細画面に移動したら、 NS SOA の二つのレコードが存在していると思います(今回は既存の物をスクショしているので他のレコードもありますが・・・) 今回はNSと書かれた部分の一番右側にある4つの文を自身が所持しているドメインに適応させる形になります。 今回はGoogle Domainを利用するのでサイトへ行きます 上記画像のように左のメニューからDNSを選択、カスタムレコード欄のカスタムレコードを管理ボタンから先ほどの4つのNSを登録していきます。例として Route53に登録したサブドメイン名 | NS | 3600 | 先ほどの文から文末のピリオドを削除したもの 行の追加はこのレコードにさらに追加ボタンを押すことで可能ですので4つ分登録します。 登録が完了しましたら当手順は終了です、次項に続きます。 証明書の取得 こちら(ACM)に移動します 証明書をリクエストの画面まで来ましたら、完全修飾ドメイン名の部分に先ほどRoute53に登録したドメイン名を入力します。 青く記載の情報部分をクリックすると解説が表示されます。ワイルドカード等の情報が記載されているので必要に応じて確認してください。今回は触れません。 他部分は変更せずにリクエストボタンをクリックします すると上記画像のようなページに遷移します。 本来であればステータスは保留中の検証といった文字列になっていると思いますので、もうひと手順を踏みます。 証明書IDの文字列をクリックすると、ページ中部に Route53でレコードを作成 というボタンがありますのでそちらをクリックします。すると保留中のドメインが表示されますのでそのまま右下のレコードを作成ボタンをクリックすることで当手順の完了です。実際の反映には5分~30分ほどかかるとされています。 さいごに 今回はサブドメインをRoute53に登録し、証明書をリクエストする手順を紹介しました。 ここまで実行できた場合はALBにつなげるなり、私の場合はkusanagiにてwordpressを建てる際のホスト名に利用しています。SSL設定も簡単ですしね。 何方かのお役に立てることを祈っております。 余談 記事を書くのに全く慣れておらず、見辛い部分等多くあったかもしれません。また誤字脱字や認識・手順違いありましたらお気軽にコメントにて教えて頂けると幸いです。ではまた。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS IAM Access Analyzerによるポリシーチェックを自動化する方法

はじめに AWSのIAMロールに付与するIAMポリシーの権限は、セキュリティリスクを考えれば、必要最小限にとどめる必要があります。 AWSの任意のインスタンスに関連付けられたIAMロールでは、設定時は最小権限になっていても、その後の運用で過剰な権限が付与される可能性があります。 また、開発者や運用者が作るIAMポリシーの権限も、必ずセキュリティベストプラクティスに沿っているかどうかは分かりません。 このIAMポリシーの検査を継続的に実施可能な環境を作るために、自動化されたメカニズムの導入を検討します。 アプローチ AWS IAM Access Analyzerには、IAMポリシーのチェック機能があり、この機能を利用してポリシーを検証できます。 検証は、マネジメントコンソール上だけではなく、AWS CLIやSDKでも実行可能であり、自動化できます。 IAM Access Analyzerのポリシーチェック機能では、IAM ポリシーの文法、ベストプラクティスに対する違反を検証します。 検証でセキュリティ警告、エラー、一般的な警告、ポリシーの提案があれば、結果が表示されます。 実装 EventBridgeで、ポリシーチェックするLambda関数を毎日実行します。 以下のLambda関数のコードは、最低限の動作を確認したものです。 lambda_handler def lambda_handler(event, context): # TODO implement iam_client = boto3.client('iam') analyzer_client = boto3.client('accessanalyzer') iam_policy_list_istruncated = True iam_policy_list_marker = None iam_policy_arn_list = [] iam_policy_document_list = {} iam_policy_document_list['Documents'] = [] # To get all iam policy ARNs while iam_policy_list_istruncated == True: if iam_policy_list_marker: iam_policy_list = iam_client.list_policies( Scope = 'Local', OnlyAttached = False, Marker = iam_policy_list_marker ) else: iam_policy_list = iam_client.list_policies( Scope = 'Local', OnlyAttached = False, ) for iam_policy in iam_policy_list['Policies']: iam_policy_arn_list.append(iam_policy['Arn']) iam_policy_list_istruncated = iam_policy_list['IsTruncated'] if 'Marker' in iam_policy_list: iam_policy_list_marker = iam_policy_list['Marker'] # To get all iam policy documents for arn in iam_policy_arn_list: iam_policy = iam_client.get_policy( PolicyArn = arn ) iam_policy_version = iam_client.get_policy_version( PolicyArn = arn, VersionId = iam_policy['Policy']['DefaultVersionId'] ) iam_policy_document_list['Documents'].append( { 'PolicyArn' : arn, 'PolicyVersionId' : iam_policy['Policy']['DefaultVersionId'], 'PolicyDocument' : iam_policy_version['PolicyVersion']['Document'] } ) # To check all policies iam_policy_check_results = {} iam_policy_check_results['Results'] = [] for document in iam_policy_document_list['Documents']: iam_policy_check = analyzer_client.validate_policy( locale = 'JA', policyDocument = json.dumps(document['PolicyDocument']), policyType='IDENTITY_POLICY' ) iam_policy_check_results['Results'].append( {**document, **iam_policy_check} ) return iam_policy_check_results 実装上のポイントは以下となります。 IAMとIAM Access AnalyzerはAWS内では別サービスの扱いなので、clientを2つ作る必要があります。 IAM Access Analyzerのvalidate_policyの引数には「policyDocument」、つまりIAMポリシーのJSONを指定する必要があります。 このJSONを取得するまでには、IAMのlist_policiesで各ポリシーのARNを取得し、get_policyでボリシーのバージョン文字列を取得した後、この両方を引数にしてget_policy_versionを実行しなければなりません。 結果 テストのために、わざとセキュリティ違反が起きるようなポリシーを作っておき、Lambda関数を実行します。 結果 { "PolicyArn": "arn:aws:iam::xxxxxxxxxxxx:policy/Testpolicy-201502161625", "PolicyVersionId": "v2", "PolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "iam:*", "Resource": "*" } ] }, (中略) "findings": [ { "findingDetails": "ワイルドカード (*) をアクションおよびリソースで使用すると、すべてのリソースで iam:CreateServiceLinkedRole アクセスが許可されるので、意図しないサービスにリンクされたロールが作成されることがあります。これを避けるために、代わりにリソース ARN を指定することをお勧めします。", "findingType": "WARNING", "issueCode": "CREATE_SLR_WITH_STAR_IN_ACTION_AND_RESOURCE", "learnMoreLink": "https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/access-analyzer-reference-policy-checks.html#access-analyzer-reference-policy-checks-general-warning-create-slr-with-star-in-action-and-resource", "locations": [ { "path": [ { "value": "Statement" }, { "index": 0 }, { "value": "Action" } ], "span": { "end": { "column": 77, "line": 1, "offset": 77 }, "start": { "column": 70, "line": 1, "offset": 70 } } }, { "path": [ { "value": "Statement" }, { "index": 0 }, { "value": "Resource" } ], "span": { "end": { "column": 94, "line": 1, "offset": 94 }, "start": { "column": 91, "line": 1, "offset": 91 } } } ] }, (以下略) 以上のように、AWS IAM Access Analyzerによるポリシーチェックの結果を得ることができました。 応用 validate_policy の policyType='IDENTITY_POLICY' の部分ですが、この他に RESOURCE_POLICY と SERVICE_CONTROL_POLICY を指定できますので、このコードをベースに作り込めば、IAMポリシー以外の検査もできます。 (詳細) AWSにおける「ポリシー」の種類とは そもそもAWS全体でポリシー呼ばれる設定のタイプは3種類あり、それぞれ (1)IDポリシー、(2)リソースポリシー、(3)サービスコントロールポリシー と呼ばれています。 (1)IDポリシーは、IAMのプリンシパルにアクセス許可を付与するものです。 また、IAMの管理ポリシーやインラインポリシーは、IDポリシーの細かい分類です。 (2)リソースポリシーは、AWSリソースに対するアクセス許可を付与するものです。 IAMロールの信頼ポリシーとS3バケットのバケットポリシーは、リソースポリシーの細かい分類です。 (3)サービスコントロールポリシーは、AWS Organizations、組織単位 (OU)、アカウントにアタッチされる SCP (Service Control Policy) を指し、そのままの意味となります。 IAM Access Analyzerがチェックする観点 記事執筆時点では、以下のリンク先に記載されている項目がチェックされます。 かなり多くの項目がチェックされますが、肝心のセキュリティの観点については、現時点では項目が少なめとなっています。 例えば、S3バケットポリシーでNotPrincipalでAllowしている場合に警告してくれるなど、クリティカルな穴を塞げる点では非常に助かります。 ただ、単独のAction (NotAction) の広さに対しての警告はまだ弱く、例えば ec2:* と書いた場合に、権限が広すぎるとは警告してくれません。 セキュリティに関しては、今後のアップデートに期待したいポイントと言えます。 まとめ IAMの最小権限の継続的検査を自動化することは、AWSがセキュリティの推奨事項として提唱しているものであり、実施すべきことです。 自動検査方法の一つとして、IAM Access Analyzerのvalidate_policyを定期的に自動で実行するアプローチを紹介しました。 しかし、上記で書いたように、IAM Access Analyzerに頼りきるだけでは不完全ですので、AWS Configを利用した差分確認などと組み合わせて運用することをお勧めします。 参考文献 IAM - Boto3 Docs 1.21.5 documentation IAM Access Analyzer- Boto3 Docs 1.21.5 documentation Access Analyzer ポリシーチェックリファレンス Automate resolution for IAM Access Analyzer cross-account access findings on IAM roles Continuously monitor unused IAM roles with AWS Config
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS IAM Access Analyzerによる継続的ポリシーチェックを自動化する方法

はじめに AWSのIAMロールに付与するIAMポリシーの権限は、セキュリティリスクを考えれば、必要最小限にとどめる必要があります。 AWSの任意のインスタンスに関連付けられたIAMロールでは、設定時は最小権限になっていても、その後の運用で過剰な権限が付与される可能性があります。 また、開発者や運用者が作るIAMポリシーの権限も、必ずセキュリティベストプラクティスに沿っているかどうかは分かりません。 このIAMポリシーの検査を継続的に実施可能な環境を作るために、自動化されたメカニズムの導入を検討します。 アプローチ AWS IAM Access Analyzerには、IAMポリシーのチェック機能があり、この機能を利用してポリシーを検証できます。 マネジメントコンソール上だけではなく、AWS CLIやSDKでも実行可能であり、自動化できます。 IAM Access Analyzerのポリシーチェック機能では、IAM ポリシーの文法、ベストプラクティスに対する違反を検証します。 検証でセキュリティ警告、エラー、一般的な警告、ポリシーの提案があれば、結果が表示されます。 実装 EventBridgeで、ポリシーチェックするLambda関数を毎日実行します。 以下のLambda関数のコードは、最低限の動作を確認したものです。 lambda_handler def lambda_handler(event, context): # TODO implement iam_client = boto3.client('iam') analyzer_client = boto3.client('accessanalyzer') iam_policy_list_istruncated = True iam_policy_list_marker = None iam_policy_arn_list = [] iam_policy_document_list = {} iam_policy_document_list['Documents'] = [] # To get all iam policy ARNs while iam_policy_list_istruncated == True: if iam_policy_list_marker: iam_policy_list = iam_client.list_policies( Scope = 'Local', OnlyAttached = False, Marker = iam_policy_list_marker ) else: iam_policy_list = iam_client.list_policies( Scope = 'Local', OnlyAttached = False, ) for iam_policy in iam_policy_list['Policies']: iam_policy_arn_list.append(iam_policy['Arn']) iam_policy_list_istruncated = iam_policy_list['IsTruncated'] if 'Marker' in iam_policy_list: iam_policy_list_marker = iam_policy_list['Marker'] # To get all iam policy documents for arn in iam_policy_arn_list: iam_policy = iam_client.get_policy( PolicyArn = arn ) iam_policy_version = iam_client.get_policy_version( PolicyArn = arn, VersionId = iam_policy['Policy']['DefaultVersionId'] ) iam_policy_document_list['Documents'].append( { 'PolicyArn' : arn, 'PolicyVersionId' : iam_policy['Policy']['DefaultVersionId'], 'PolicyDocument' : iam_policy_version['PolicyVersion']['Document'] } ) # To check all policies iam_policy_check_results = {} iam_policy_check_results['Results'] = [] for document in iam_policy_document_list['Documents']: iam_policy_check = analyzer_client.validate_policy( locale = 'JA', policyDocument = json.dumps(document['PolicyDocument']), policyType='IDENTITY_POLICY' ) iam_policy_check_results['Results'].append( {**document, **iam_policy_check} ) return iam_policy_check_results 実装上のポイントは以下となります。 IAMとIAM Access AnalyzerはAWS内では別サービスの扱いなので、clientを2つ作る必要があります。 IAM Access Analyzerのvalidate_policyの引数には「policyDocument」、つまりIAMポリシーのJSONを指定する必要があります。 このJSONを取得するまでには、IAMのlist_policiesで各ポリシーのARNを取得し、get_policyでボリシーのバージョン文字列を取得した後、この両方を引数にしてget_policy_versionを実行しなければなりません。 結果 テストのために、わざとセキュリティ違反が起きるようなポリシーを作っておき、Lambda関数を実行します。 結果 { "PolicyArn": "arn:aws:iam::xxxxxxxxxxxx:policy/Testpolicy-201502161625", "PolicyVersionId": "v2", "PolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "iam:*", "Resource": "*" } ] }, (中略) "findings": [ { "findingDetails": "ワイルドカード (*) をアクションおよびリソースで使用すると、すべてのリソースで iam:CreateServiceLinkedRole アクセスが許可されるので、意図しないサービスにリンクされたロールが作成されることがあります。これを避けるために、代わりにリソース ARN を指定することをお勧めします。", "findingType": "WARNING", "issueCode": "CREATE_SLR_WITH_STAR_IN_ACTION_AND_RESOURCE", "learnMoreLink": "https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/access-analyzer-reference-policy-checks.html#access-analyzer-reference-policy-checks-general-warning-create-slr-with-star-in-action-and-resource", "locations": [ { "path": [ { "value": "Statement" }, { "index": 0 }, { "value": "Action" } ], "span": { "end": { "column": 77, "line": 1, "offset": 77 }, "start": { "column": 70, "line": 1, "offset": 70 } } }, { "path": [ { "value": "Statement" }, { "index": 0 }, { "value": "Resource" } ], "span": { "end": { "column": 94, "line": 1, "offset": 94 }, "start": { "column": 91, "line": 1, "offset": 91 } } } ] }, (以下略) 以上のように、AWS IAM Access Analyzerによるポリシーチェックの結果を得ることができました。 応用 validate_policy の policyType='IDENTITY_POLICY' の部分ですが、この他に RESOURCE_POLICY と SERVICE_CONTROL_POLICY を指定できますので、このコードをベースに作り込めば、IAMポリシー以外の検査もできます。 (詳細) AWSにおける「ポリシー」の種類とは そもそもAWS全体でポリシー呼ばれる設定のタイプは3種類あり、それぞれ (1)IDポリシー、(2)リソースポリシー、(3)サービスコントロールポリシー と呼ばれています。 (1)IDポリシーは、IAMのプリンシパルにアクセス許可を付与するものです。 また、IAMの管理ポリシーやインラインポリシーは、IDポリシーの細かい分類です。 (2)リソースポリシーは、AWSリソースに対するアクセス許可を付与するものです。 IAMロールの信頼ポリシーとS3バケットのバケットポリシーは、リソースポリシーの細かい分類です。 (3)サービスコントロールポリシーは、AWS Organizations、組織単位 (OU)、アカウントにアタッチされる SCP (Service Control Policy) を指し、そのままの意味となります。 IAM Access Analyzerがチェックする観点 記事執筆時点では、以下のリンク先に記載されている項目がチェックされます。 かなり多くの項目がチェックされますが、肝心のセキュリティの観点については、現時点では項目が少なめとなっています。 例えば、S3バケットポリシーでNotPrincipalでAllowしている場合に警告してくれるなど、クリティカルな穴を塞げる点では非常に助かります。 ただ、単独のAction (NotAction) の広さに対しての警告はまだ弱く、例えば ec2:* と書いた場合に、権限が広すぎるとは警告してくれません。 セキュリティに関しては、今後のアップデートに期待したいポイントと言えます。 まとめ IAMの最小権限の継続的検査を自動化することは、AWSがセキュリティの推奨事項として提唱しているものであり、実施すべきことです。 自動検査方法の一つとして、IAM Access Analyzerのvalidate_policyを定期的に自動で実行するアプローチを紹介しました。 しかし、上記で書いたように、IAM Access Analyzerに頼りきるだけでは不完全ですので、AWS Configを利用した差分確認などと組み合わせて運用することをお勧めします。 参考文献 IAM - Boto3 Docs 1.21.5 documentation IAM Access Analyzer- Boto3 Docs 1.21.5 documentation Access Analyzer ポリシーチェックリファレンス Automate resolution for IAM Access Analyzer cross-account access findings on IAM roles Continuously monitor unused IAM roles with AWS Config
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Cloudwatch logs insight のクエリ結果でアラーム設定する

Cloudwatch logs insightは、クエリ的にログ検索ができるが、検索結果をそのままメトリクス化して監視やアラーム設定することができない。同じくCloudwatchのロググループにメトリクスフィルタを設定することでメトリクス化できるが、Cloudwatch logs insightほど複雑なフィルタ条件は設定できない。 前提条件 Cloudwatchを使ったログ収集をしていること AWS CLIが実行できる環境があること jqが実行できる環境があること Cloudwatch logs insightの結果をメトリクス化する 一定時間毎にCloudwatch logs insightにクエリした結果を、メトリクス化する。 shell scriptで、AWS CLIを使ってCloudwatch logs insightの情報を取得し、さらにCloudwatchのメトリクス として設定します。 AWS CLIを使ったscriptの準備 AWS CLIを使ってCloudwatch logs insightの情報を取得し、ヒット件数をCloudwatchのメトリクス として設定します。AWS CLIが実行できる環境にshell scriptを配置します insight_to_metrics.sh #CLI environment 各自の環境に合わせて設定してください PROFILE=XXXXXXXX #AWS PROFILE名を設定 AWS_CLI=/usr/bin/XXXXXXXXX #AWS CLIのパスを設定 JQ=/XXX/XXX/jq # jqのパスを設定 C_PASS=/home/XXXXXX #本スクリプトファイルのディレクトリを設定 #Cloudwatch insight #query time STARTTIME=`date --date '-30 minute' +%s` ENDTIME=`date +%s` #query log name LOG_GROUP_NAME="XXXXXXXXXX" #クエリ対象のロググループを指定 #Cloudwatch metrics NAME_SPACE="CWinsight" #メトリクスのNAME SPACEを指定 METRIC_NAME="recordsMatched_COUNT" #メトリクス名を指定 #tmp files QUERY_FILE=$C_PASS/query.txt TMP_FILE=$C_PASS/tmp_query_id.txt #start query while read line do QUERY=$line echo $LOG_GROUP_NAME $QUERY QUERY_ID=`$AWS_CLI logs start-query \ --log-group-name $LOG_GROUP_NAME \ --start-time $STARTTIME \ --end-time $ENDTIME \ --output text \ --query-string "$QUERY" ` echo $QUERY_ID >> $TMP_FILE DIMENSHON=`echo $QUERY | awk '{print substr($0, index($0, "#")+1)}'` echo $DIMENSHON >> $TMP_FILE done < $QUERY_FILE #wait for query finish sleep 20s #クエリ時間によって調整すること #output result while read line do QUERY_ID=$line RESULT=`$AWS_CLI logs get-query-results --query-id $QUERY_ID --output json` STATUS=`echo $RESULT | $JQ '.status'` # check query status if [ $STATUS != \"Complete\" ] ; then echo "[ERROR] exit Script" $QUERY_ID $STATUS rm -f $TMP_FILE exit 1 fi COUNT=`echo $RESULT | $JQ '.statistics.recordsMatched'` read line echo $line " / query status = "$STATUS " matched count = "$COUNT # put Metric data of CloudWatch aws cloudwatch put-metric-data --metric-name $METRIC_NAME --namespace $NAME_SPACE --unit Count --value $COUNT --dimensions insight_script=$line done < $TMP_FILE #END script rm -f $TMP_FILE query条件の設定 query条件は、変更しやすいように別ファイルで記載、クエリの表記方法はCloudwatch logs insightをGUIで使う時と同じ shell scriptと同じディレクトリに配置しておく query.txt stats count(@message) | filter @message like "hoge" | filter @message not like "fuga" #hogefuga_count stats count(@message) | filter @message like "peke" | filter @message not like "poko" #pekepoko_count 実行 cronで定期実行するようにします 上記の例だと、過去30分のログを対象にqueryしているため、cronも30分毎に設定します 間隔は要件に合わせて設定してください 15,45 * * * * /home/XXXXXX/insight_to_metrics.sh 注意点 クエリ対象のログ量が大きい場合、コスト(と実行時間)が増えるので、コストに見合うか判断して利用しましょう 参考 AWS料金 結果 CloudwatchのCustom namespacesにメトリクスとして値が入っていればOK あとはお好みでアラート設定したり出来ます
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Powershell】ALBのリスナールールのプライオリティ値を変更しSorryページへ切り替えるps1を作成

1. はじめに ALBのリスナールールの優先順位を変更して、Sorryページを表示させるPowershellスクリプトを作成しました。 Webサイトのメンテナンス時に、ALBで設定した固定ページへ通信を切り替える際、手作業だったり、Lambdaを使うのは少々手間がかかるので、shで一撃で切り替えられたら楽だなと思い、作成に至った次第です。 思いつきで書いたものでコードが若干汚いですが、ご了承下さい・・ 2. 概要 本記事の概要を以下に記載します。 2.1 本記事の概要 AWS ELBのリスナールールのPriority値を変更するPowershellスクリプトを作成しました。 2.2 機能要件 AWS ELBのリスナールールのPriority値を変更する ※複数変更非対応 Windows環境での実装を想定して、Powershellを使用する 2.3 実行環境 Windows10 Windows Server 2016,19 2.4 事前準備 AWS CLIがインストール済であること ps1ファイルの実行可能権限が付いていること 3. Sorryページ切り替えスクリプト 本スクリプトは以下GitHubに置いてあります。 https://github.com/chibiharu/AWSCLI-Tools/tree/master/ShellScript/AWS-Get-EC2Resources 3.1 使用方法 手順1:設定ファイルのパラメータを各項目に従い指定する。 setting.conf ####################################################################################### ## 設定ファイル ####################################################################################### ### 実行ログの保管先パスを指定 ### $OutputPass="" ### 対象ALBのTagNameを指定 ### $ALBName="" ### リスナーポートを取得 ### $LISTENERPort="" ### リスナールールの現在のプライオリティ値を指定 ### $Priority_Before="" ### リスナールールの変更後のプライオリティ値を指定 ### $Priority_After="" ### AWSクレデンシャル生成 ### $Env:AWS_ACCESS_KEY_ID="" $Env:AWS_SECRET_ACCESS_KEY="" $Env:AWS_DEFAULT_REGION="" 手順2:メインスクリプトの設定ファイルのパスを指定する Switch_ListenerRule_Priority.ps1 ~~~ 略 ~~~ # 設定ファイル(setting.ini)パス $SettingFile="" ~~~ 略 ~~~ 手順3:メインスクリプトを実行する ./Switch_ListenerRule_Priority.ps1 手順4:実行ログを確認し、スクリプトが正常に終了していることを確認する。 $ cat ./elb_switch_20220224124101.log ########## $ Start switch_sorry_page_alb_listrner ########## aws-cli/2.2.5 Python/3.8.8 Windows/10 exe/AMD64 prompt/off ###### info:<ELB名> が存在しているので、後続処理を行います。###### ###### info:<ELB名> に以下のリスナーが所属しております。後続処理を行います。###### 443 <リスナーARN> 80 <リスナーARN> ###### info:以下のリスナーに対して処理を実行します。後続処理を行います。###### <リスナーARN> ###### info:以下のリスナールールのプライオリティ値を3に変更します。後続処理を行います。###### <リスナールールARN> ###### info:対象リスナーのリスナールール一覧を出力します。後続処理を行います。###### <リスナールールの一覧情報をjson形式で出力> ###### info:全ての処理が正常に終了しました。###### ########## $ END switch_ListenerRule_Priority ########## 3.2 Switch_ListenerRule_Priority.ps1 Switch_ListenerRule_Priority.ps1 ####################################################################################### # <説明> # AWS ELBのリスナールールの優先順位を切り替える # # <更新日> # 作成日:20220223 # 最終更新日:20220223 # # <使用時における注意事項> # ・本スクリプト、及び設定ファイル(setting.ini)の文字コードは「ANSI(SJIS)」を指定すること # ・- # # <コメント> # ・Sorryページの切り替え等にご使用下さい # ・- # ####################################################################################### ####################################################################################### # 事前設定 ####################################################################################### # 現在の時刻(yyyyMMddhhmmss)を取得 $str_date = Get-Date -Format "yyyyMMddhhmmss" ####################################################################################### # パラメータ ####################################################################################### # 設定ファイル(setting.ini)パス $SettingFile="" # 設定ファイル読み込み Get-Content ${SettingFile} | where-object {$_ -notmatch '^\s*$'} | where-object {!($_.TrimStart().StartsWith("#"))}| Invoke-Expression # 実行ログ $output = "$OutputPass/elb_switch_${str_date}.log" ####################################################################################### # メイン処理 ####################################################################################### # ログ見出し出力 echo "########## $ Start switch_sorry_page_alb_listrner ##########" | Out-File $output -Append # AWS CLIのバージョンを出力 aws --version | Out-File $output -Append # TagNameからALBのARNを取得する $ELBARN=aws elbv2 describe-load-balancers --name ${ALBName} --query 'LoadBalancers[].[LoadBalancerArn]' --output text # 対象のELBが存在するか確認する if(${ELBARN} -eq 0 ){ echo "###### error:${ALBName} が存在しておりません。######" | Out-File $output -Append }else{ echo "###### info:${ALBName} が存在しているので、後続処理を行います。######" | Out-File $output -Append } # 対象ELBのリスナーARNを取得 $LISTENER_ARN=$(aws elbv2 describe-listeners --load-balancer-arn ${ELBARN} --query "Listeners[][].[Port,ListenerArn]" --output text) # 対象のELBにリスナーが所属しているか確認する if(${LISTENER_ARN} -eq 0 ){ echo "###### error:${ALBName}にリスナーが所属しておりません。######" | Out-File $output -Append }else{ echo "###### info:${ALBName} に以下のリスナーが所属しております。後続処理を行います。######" | Out-File $output -Append } # 取得したリスナーのARNを分割する Write-Output $LISTENER_ARN | Out-File $output -Append $data = Get-Content $output $Num=Select-String $LISTENERPort $output | ForEach-Object { $($_ -split":")[2]} $Num=$Num-1 $DefaultListener=$data[$Num] $DefaultListener=$DefaultListener -replace $LISTENERPort,"" $DefaultListener=$DefaultListener.Trim() echo "###### info:以下のリスナーに対して処理を実行します。後続処理を行います。######" | Out-File $output -Append echo $DefaultListener | Out-File $output -Append # リスナールールのARNを取得 echo "###### info:以下のリスナールールのプライオリティ値を${Priority_After}に変更します。後続処理を行います。######" | Out-File $output -Append aws elbv2 describe-rules --listener-arn $DefaultListener --query "Rules[?Priority=='${Priority_Before}'][].[RuleArn]" --output text | Out-File $output -Append $LISTENERRULE_ARN=$(aws elbv2 describe-rules --listener-arn $DefaultListener --query "Rules[?Priority=='${Priority_Before}'][].[RuleArn]" --output text) # リスナールールのプライオリティ値を変更 aws elbv2 set-rule-priorities --rule-priorities RuleArn=${LISTENERRULE_ARN},Priority=${Priority_After} | Out-Null # 対象リスナーの変更後のリスナールールを出力 echo "###### info:対象リスナーのリスナールール一覧を出力します。後続処理を行います。######" | Out-File $output -Append aws elbv2 describe-rules --listener-arn $DefaultListener --query "Rules[][].[Priority,Actions]" --output text | Out-File $output -Append ####################################################################################### # 後処理 ####################################################################################### # AWSクレデンシャルを削除 [Environment]::SetEnvironmentVariable("AWS_DEFAULT_REGION", "") [Environment]::SetEnvironmentVariable("AWS_SECRET_ACCESS_KEY", "") [Environment]::SetEnvironmentVariable("AWS_ACCESS_KEY_ID", "") # ログ見出し出力 echo "###### info:全ての処理が正常に終了しました。######" | Out-File $output -Append echo "########## $ END switch_ListenerRule_Priority ##########" | Out-File $output -Append 4. まとめ シェルスクリプトで実装する方が簡単で利用者も多いかなとは思ったのですが、自分が以前いた現場ではPowershellバリバリといった感じでググっても情報が無くこういうツール作るのに非常に苦労したので、そういう方の助けになればと思います。 [参照] ALBのSorryページ切り替えシェルを作成してみました(CLI) awscliを使ったALBによるメンテナンス画面表示
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Amazon EMRのセキュリティグループに関してはまった事

はじめに EMRをプライベートサブネットで利用する場合最低3つのセキュリティグループが必要になります。 マスターインスタンスの Amazon EMR 管理セキュリティグループ コアインスタンスとタスクインスタンスのセキュリティグループ サービスアクセス用のセキュリティグループ 今回はこれらのSecurity Groupをカスタムとして手動で作成した際にはまった事を備忘で書いておきたいと思います。 はまった事 EMRではマスター/スレーブ間で別々にセキュリティグループをアタッチし、各々通信しなければならないポート/プロトコルが決まっています。プレイベートサブネットを利用する場合はサービスアクセス用のセキュリティグループも要件にあったポート/プロトコルを解放する必要があります。 私の環境ではプライベートサブネットでクラスターを起動している事もありSecurity Group間の通信は SG-to-SGでALL解放していたので問題なく使えていました。 問題は Amazon EMR リリース 5.30.0 以降を利用し始めた時に発生しました。 上のリンク先に記載があるのですが、サービスアクセス用のセキュリティグループではインバウンドのルールとして マスター用のセキュリティグループからの9443/TCPを許可する必要があるのですが、元々ALL解放していた事もあり 変更はしていませんでした。 しかしながらEMRを利用しようとしたところ以下のエラーが表示されました。 ServiceAccessSecurityGroup is missing ingress rule from EmrManagedMasterSecurityGroup on port 9443 どうやらEMR側で明示的に9443/TCPが許可されているかをチェックしているようです。 9443/TCPを別途解放したところ利用できるようになりました。 マスター側セキュリティグループのアウトバウンドはALL開放だけで明示的にポートを開放する必要はありませんでした。 教訓 AWSマネージドサービスによっては通信が許可されているかではなく設定が入っているかをチェックしているものもあるようです。 もし同様の経験をされた方がいれば、参考になれば幸いです。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ExternalSecretsOperator(ESO)をEKSとGKEに導入して各SecretsManagerからシークレットを取得する

はじめに マルチクラウド構成の検討とか色々とやってる中で、アプリケーションで使用するシークレットを取得するにあたって、マネージドサービスのKubernetes(EKS/GKE)からどうやって呼び出すか?を検討しました。環境の前提条件などから色々とハマったので、導入からシークレットの取得までを整理したいと思います。 ※間違ってたらコメントなどで指摘を頂けますとありがたいです。 前提条件 AWS EKSクラスタが構築されていること ノードグループではなく、Fargateで起動する(ここが色々と制限になりました) FargateプロファイルはDefaultとKube-systemを別個に作成 ParametorStoreへの値の設定は事前に行っている Google Cloud GKEクラスタが構築されていること モードはAutoilotとする SecretsManagerへの値の設定は事前に行っている いろいろ kubectlの認証などは省略してます ファイルの中身は記載しますが、applyコマンドは省略してます 検討コンポーネント まず、AWS側でサンプルアプリをデプロイしてシークレットを取得するまでを検討しました。 SecretStoreSCIDriver ボリュームを通してシークレットストアとK8sを統合するドライバ。 ただし、Fargate起動の場合は、ボリュームマウント関連で制限があるため、本ドライバは使えませんでした。 https://github.com/aws/secrets-store-csi-driver-provider-aws/issues/34 kubernetes-external-secrets(KES) 次に確認したのが上記です。日本語でもSecretsを取得する方法で検索すると良く出てくるものでした。が、正式に非推奨になり、記事タイトルにあるExternalSecretsOperator(ESO)に変わりました。 https://github.com/external-secrets/kubernetes-external-secrets/issues/864 ExternalSecretsOperator(ESO) そのため、KESの後継であるESOを使用してSecretsを取得することとしました。が、2021年11月にKESで非推奨のアナウンスが出たので、公式ドキュメントはあるにせよ日本語の情報が多くない。よし、なら導入して書こう(本記事) クラウド間で違うコンポーネントを使うのは避けるため、Google Cloudも同じESOを使用することとしました。 ESO概念図 ※公式サイト(https://external-secrets.io/v0.4.1/) から引用 ExternalSecretsOperatorのPodが起動し、各クラウドサービスの権限を設定したServiceAccountを使用してシークレットを取得します。KESではアクセスに使う設定と、K8s内Secretsの設定がまとまっていましたが、ESOではアクセス設定(SecretStore/ClusterSecretStore)とSecretsの紐づけ(ExternalSecret)が別となっているので、役割分担もわかりやすいかなと思います。 SecretStore アクセスに使用する設定 K8sにあるServiceAccountを指定する 名前空間を考慮する必要がある ClusterSecretStore アクセスに使用する設定 K8sにあるServiceAccountを指定する 名前空間を横断して共通で使用できる ExternalSecrets フェッチするデータの宣言 どのSecretStoreを使用して取得するかを指定する K8s Secretsの定義、どこから取得するかを指定する 名前空間を考慮する必要がある 構築する を参照しつつ、色々と前提条件の環境に合うように修正を実施しました。 AWS Terraform OIDCプロバイダとRole関連 権限のリソース周りなどは読み替えてください。個人的には*ですべての権限などを与えたくなかったので、下記のようにしています。あと、コード化したいので、可能な限りTerraformに寄せました。 Terraformコード iam.tf ## # Create OIDC Provider (K8s Cluster) ## resource "aws_iam_openid_connect_provider" "k8s_oidc" { url = "[ClusterのOpenID Connect プロバイダー URL]" client_id_list = [ "sts.amazonaws.com", ] # 証明書のサムプリントはEKS Clusterで基本は共通 thumbprint_list = [ "[値を手動で確認するなどして入れる]", ] } data "aws_iam_policy_document" "secrets_inline_policy" { statement { actions = [ "kms:GenerateDataKey", "kms:Decrypt", ] resources = ["*"] } statement { actions = [ "secretsmanager:GetSecretValue", "secretsmanager:DescribeSecret", "secretsmanager:ListSecretVersionIds", ] resources = [ "arn:aws:secretsmanager:[REGION]:[ACCOUNT]:secret:[RESOURCE]" ] } statement { actions = [ "ssm:GetParameters", "ssm:GetParameter", ] resources = [ "arn:aws:ssm:[REGION]:[ACCOUNT]:parameter[RESOURCE]" ] } } data "aws_iam_policy_document" "secrets_assume_role" { statement { actions = ["sts:AssumeRoleWithWebIdentity"] # K8sのOIDCを設定する principals { type = "Federated" identifiers = [aws_iam_openid_connect_provider.k8s_oidc.arn] } # 信頼関係を制限する condition { test = "StringEquals" variable = "[ClusterのOpenIDConnectプロバイダーURLからhttps://を削除した値]:sub" values = [ "system:serviceaccount:default:test-eso-sa", ] } } } ## ESO向けにRoleを作成する resource "aws_iam_role" "k8s_serviceaccount_secrets" { name = "ExternalSecretOperator-role" description = "Managed by Terraform / K8s ESO ROLE" assume_role_policy = data.aws_iam_policy_document.secrets_assume_role.json inline_policy { name = "ExternalSecretOperator-inlinepolicy" policy = data.aws_iam_policy_document.secrets_inline_policy.json } depends_on = [ aws_iam_openid_connect_provider.k8s_oidc, ] } kubernetes helm ガイドでは新しくNamespaceを作成しているが、Fargateプロファイル上存在しないので、Defaultで動かすこととします。FargateでHelmInstallを行う場合は、regionとvpcIDが必要になります。 helm install external-secrets external-secrets/external-secrets \ -n default \ --set clusterName=[クラスタ名] \ --set serviceAccount.create=false \ --set serviceAccount.name=test-eso-sa \ --set region=[REGION] \ --set vpcId=[ClusterがあるVPCのID] 上手く動くと、ワークロードにexternal-secretsのDeploymentが存在し、Podが起動します。 ServiceAccount serviceaccout.yaml ### # ESOに対してSSM/SecretsManagerからSecretsを取得することを許可するServiceAccount(IAM紐づけ) ### apiVersion: v1 kind: ServiceAccount metadata: labels: app.kubernetes.io/component: secrets app.kubernetes.io/name: external-secrets name: test-eso-sa annotations: eks.amazonaws.com/role-arn: arn:aws:iam::[ACCOUNT]:role/ExternalSecretOperator-role SecretStore / ExternalSecret secretstore.yaml ### # Secretの認証方法の設定 ### apiVersion: external-secrets.io/v1alpha1 kind: SecretStore metadata: name: secretstore-sample spec: provider: aws: service: ParameterStore region: [REGION] auth: jwt: serviceAccountRef: name: test-eso-sa externalsecrets.yaml apiVersion: external-secrets.io/v1alpha1 kind: ExternalSecret metadata: name: example spec: refreshInterval: 1h secretStoreRef: name: secretstore-sample kind: SecretStore target: name: multicloud-db-info creationPolicy: Owner data: - secretKey: dburl remoteRef: key: [ParametorStoreのPath] - secretKey: user remoteRef: key: [ParametorStoreのPath] - secretKey: password remoteRef: key: [ParametorStoreのPath] ハマった点 公式のHelmだと名前空間を新しく作るが、Fargateなのでkube-systemで良いかと軽く考えると、各リソース間の検索ができずにErrorとなりました(Notfound) ExternalSecret > SecretStore > ServiceAccount > IAM と呼び出すので、同じ名前空間でないと見れないという単純なミスでした。 Google Cloud Terraform ServiceAccountとRoleBinding関連 OIDCプロバイダーは内部のためかAWSと違い不要でした。Secretsを読むためのServiceAccountを作成し、必要なRoleをBindingしています。Roleはあまり制限かけてませんが、AWSとの習熟度の違いですのでご容赦ください。本当なら制限かけるべきかと思っています。公式からリンクされているGoogle Cloudのドキュメントだとコマンドベースで記載されていますが、こちらも、コード化したいので、Terraformに寄せました。 Terraformコード iam.tf ### # Service Account(ExternalSecretsOperator用ユーザ) ### resource "google_service_account" "eso" { account_id = "eso-sa" display_name = "ExternalSecrets Account" description = "ExternalSecretsOperator Use SecretManager" } ### # Role Binding(ESOへSecretsを読み込む権限を) ### resource "google_project_iam_binding" "secret-pull" { project = local.const.google.project role = "roles/secretmanager.secretAccessor" members = [ "serviceAccount:${google_service_account.eso.email}", ] } ### # GKEに対して、WorkloadIdentityUserを付与する ### resource "google_service_account_iam_binding" "gkec" { service_account_id = google_service_account.eso.name role = "roles/iam.workloadIdentityUser" members = [ "serviceAccount:[project].svc.id.goog[default/external-secrets]", ] } kubernetes helm ガイドでは新しくNamespaceを作成しているが、AWSに合わせてDefaultで動かすこととします。AWSより引数が少なく簡単にインストールできます。 helm install external-secrets \ external-secrets/external-secrets \ -n default ServiceAccount serviceaccout.yaml ### # ESOに対してSSM/SecretsManagerからSecretsを取得することを許可するServiceAccount(IAM紐づけ) ### apiVersion: v1 kind: ServiceAccount metadata: labels: app.kubernetes.io/component: secrets app.kubernetes.io/name: external-secrets name: external-secrets annotations: iam.gke.io/gcp-service-account: [Terraformで作ったGCPのServiceAccountEmail] SecretStore / ExternalSecret secretstore.yaml apiVersion: external-secrets.io/v1alpha1 kind: ClusterSecretStore metadata: name: example spec: provider: gcpsm: projectID: [project] auth: workloadIdentity: clusterLocation: [REGION] clusterName: [Cluster名] serviceAccountRef: name: external-secrets namespace: default externalsecrets.yaml apiVersion: external-secrets.io/v1alpha1 kind: ExternalSecret metadata: name: example spec: refreshInterval: 1h secretStoreRef: name: example kind: ClusterSecretStore target: name: multicloud-db-info creationPolicy: Owner data: - secretKey: dburl remoteRef: key: [SecretManagerの名前] - secretKey: user remoteRef: key: [SecretManagerの名前] - secretKey: password remoteRef: key: [SecretManagerの名前] 確認方法 上手く設定ができれば、以下のように見えます。ただ、Base64でHash化されているだけなので、EKSやGKEではsecretを暗号化する設定を作成時に可能なので、入れておく方が良いと思います。 kubectl get secrets NAME TYPE DATA AGE multicloud-db-info Opaque 3 2d1h kubectl describe secrets multicloud-db-info Name: multicloud-db-info Namespace: default Labels: <none> Annotations: reconcile.external-secrets.io/data-hash: XXXXXXX Type: Opaque Data ==== dburl: 10 bytes password: 32 bytes user: 5 bytes 個人的に考える分界点 Terraformで環境を管理することを考えると、取得するアクセス方法まではプラットフォームチームなどのクラスタを作成・管理しているチームが準備した方が楽なのかな?と思います。セクションごとにアクセスできるシークレットを制限することが多いと考えるためです。 さいごに Pod自体に権限を付与して取得する方法とか、ConfigMapを使う方法など、色々とやりかたはあるとは思います。ただ、アプリケーション部門が使いかつマルチクラウド構成と考えたら、準備する各種Deploymentなどのファイルの記述はできうる限り統一した方が負荷が少ないかなと感じました。定期的に更新をしてくれますし。 ノードの管理をしないサーバレスのKubernetesでは、EKSよりやはりGKEが統合が進んでいて使いやすいというのも感じました。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWSで機械学習を試してみたい方のための便利なツール

AWS INNOVATEで紹介されていたので、利用できそうなツールをいくつか紹介します。 AmazonSageMakerCanvas ビジネスアナリスト向けに作られたデータ分析ツール。 機械学習用の学習データをノーコードで準備できます。 AmazonSageMakerJumpStart コードを書かずにすでに学習済みのモデルを利用できます。 AmazonSageMakerStudioLab AmazonSageMakerのみを無料で利用したい方はこちらから登録をすることをお勧めします。 AmazonSageMakerStudioLab ※ただし、アカウント作成の申請後、承認をもらわないと利用できないためすぐに利用はできません。 学習データの精度向上ツール群 学習元となるデータの偏りをなくし、よりよいデータ群に変更する支援ツールを提供してくれています。 Data Wrangler:データの可視化、グラフ化 Feature Store:特徴量の管理 Clarify:偏りの検知 まとめ 機械学習とAIシステム構築については、継続的に学んでいきたいと思います。 面白いツール作れないかな。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS RDSのlog_bin_trust_function_creatorsとはなにか?

log_bin_trust_function_creatorsとは? RDSに設定できるオプションのひとつ MySQL DB インスタンスの関数、プロシージャ、トリガーの実行を行えるようになります。 このパラメーターを設定しないと動きません。 ref: https://aws.amazon.com/jp/premiumsupport/knowledge-center/rds-mysql-functions/ Super権限は設定しなくてもいいの?  SYS アクセス (SUPER 権限) は提供されていません。MySQL DB インスタンスでバイナリログが有効になっている場合は、DB インスタンス用に作成するカスタム DB パラメータグループで log_bin_trust_function_creators パラメータを true に設定します。 AWSのRDSにおいてはそもそもSUPER権限を使ったアクセスができないそうで、パラメータ変更のみでいいみたいです。 リスクはないのか? このオプション自体には特に問題はない が、Triggerやストアドファンクションを安易に使うことのリスクは存在する Triggerのリスク DBに設定するという特性上アプリケーションコード上に表示されていないが、 特定のDB操作を行うと処理が発生するという副作用が場合によっては負債となる場合がある その場しのぎ的に使い長期的には、アプリケーションコードで表現する方が安全性は高いので消すのを忘れないようにすること大事
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

SageMaker同じロールでインスタンスを特定するCloudTrailログの作成

背景 同じロールでSageMakerインスタンスを作成することは管理上で容易でありますが、CloudTrailログでは全部同じロールが見えます。 実現方法 すべてのインスタンスが同じ IAM ロールを使用する場合、どの SageMaker ノートブックインスタンスが特定の API コールを行ったかを判断するにはどうすればよいですか? 上記のAWSブログによると実現すればOKです。 ※20211111後の画面スナップショット 実現ポイント: 1、SageMakerライフサイクルスクリプトで起動時にCLI認証情報を書き込む #!/bin/bash set -ex # Obtain the name of the notebook instance nbname=$(jq -r '.ResourceName' /opt/ml/metadata/resource-metadata.json) echo "Notebook Name = $nbname" # Use the AWS Command Line Interface (AWS CLI) to obtain the Amazon Resource Name (ARN) of the IAM execution role nbinfo=$(aws sagemaker describe-notebook-instance --notebook-instance-name $nbname) nbrole=$(jq -r '.RoleArn' <<< "$nbinfo") echo "Notebook Role = $nbrole" # Obtain the Region of the notebook instance nbregion=$(aws configure get region) echo "Notebook Region = $nbregion" # Write Assume Role Provider Settings to a new config file echo "Writing new config file" cat > /home/ec2-user/.aws/config.new <<EOF1 [default] region=$nbregion role_arn = $nbrole credential_source = Ec2InstanceMetadata role_session_name = $nbname sts_regional_endpoints = regional EOF1 echo "Moving new config to config file" sudo mv /home/ec2-user/.aws/config.new /home/ec2-user/.aws/config 2、EC2インスタンスプロファイルにアタッチされたIAMロールを使用する role_arn = $nbrole:SageMaker自分のロールを使用する credential_source = Ec2InstanceMetadata:当インスタンスの認証情報を使用する role_session_name = $nbname:インスタンス名をセッション名に指定する 参考:AWS CLI での IAM ロールの使用 おまけ 2021年3月17日(すべてのインスタンスが同じ IAM ロールを使用する場合、どの SageMaker ノートブックインスタンスが特定の API 呼び出しを行ったかを判断するにはどうすればよいですか?) 2021年11月11日以前のAWSブログでの記事で、ロールの連鎖を起こすから、現在の記事になりました。 ロール連鎖現象: SageMakerインスタンスで作成したClientまたはResourceを利用する場合、1時間後に使えなくなります、権限が足りないエラーです。 参考:ロール連鎖
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

「Amazon Lightsail」をWebサーバに採用する判断材料

はじめに Webサーバ (主にWordPressの環境) のリリーススピードを加速するために様々なアプローチがありますが、最近、AWSで「Amazon Lightsail」を採用する選択肢が再注目 (再評価) されています。 AWSであればEC2やECS (Fargate) の採用が真っ先に思い浮かぶ中、なぜLightsailに向かう選択肢があるのかについてまとめます。 Amazon Lightsail を選ぶポイント Lightsailにしかない特徴によってもたらされるメリットが多数あり、これらのメリットが企業にLightsailを選ばせる動機となります。 1. WordPressの初期環境構築までの時間が短い 以下の画面が最も分かりやすく特徴を表しますが、EC2やECSのコンソールよりも遥かに簡単で、選択項目も少ないため、WordPressインストール直後の初期画面を表示するまでを素早く構築できます。 さらに、この選択によってWordPressやApacheなどは全てインストールされるため、Webサーバ起動後の作業ステップも減らすことができます。 2. WordPressの初期環境構築までの専門スキルが必要ない 上記の特徴を裏返せば、開発者のAWSスキル (AWS専門のエンジニア) が不足している場合でも構築が進められます。 Lightsailを利用すれば、サーバ構築のハードルが下がると言えるでしょう。 3. コストメリットが高い Lightsailでは、Linuxインスタンスの「4GBメモリ、2コアプロセッサ、80GB SSDディスク、4TBデータ転送」と書かれているタイプが、20USD/月で利用できます。 (アウトバウンドデータ転送の超過分は追加課金) 上記と同じ条件を通常のEC2インスタンスで満たそうとすると、インスタンスタイプにt4g.medium、EBSはgp3の80GB (IOPSとスループットは無料範囲) を選んだ場合、約40USD/月となります。 コストが最優先されるのであれば、Lightsailを真っ先に選んで良いと言えるでしょう。 4. 性能の選択肢が広い Lightsail=簡易Webサーバのイメージが強いようですが、性能は8vCPU & メモリ32GBの組み合わせまで選ぶことができます。 これだけの性能があれば、Apacheなどのチューニング次第ではありますが、経験上、月間100万PV (30万〜40万UU) であれば困ることはありません。 5. EC2への環境移行も可能 後述のようにIPアドレスを維持することはできませんが、SnapshotをEC2にエクスポートする機能により、後からEC2に移行することが可能です。 Amazon Lightsail を選ぶことによって手放すもの Lightsailには、このようにメリットが多数ありますが、一方でLightsailを選ぶことによって放棄するメリットもあります。 何を優先するかが、選ぶポイントとなります。 特に大きな選択肢は、初期構築の簡便さを求めるか、リリース後の柔軟な拡張を求めるかです。 1. 環境を維持したままスケールアップ EC2では、まずインスタンスを停止し、インスタンスタイプを変更し、起動すればスケールアップできます。 しかし、Lightsailではこのような手順でスケールアップできず、一度作成したインスタンスの変更はできません。 どうしても変更したい場合、一度インスタンスのSnapshotを作成し、Snapshotから新たにインスタンスを作り、パブリックIPアドレスを旧→新でアタッチし直す必要があります。 2. Auto Scaling Lightsailによって作成したインスタンスは、EC2のようにAuto Scalingできません。 3. IAMロール IAMロールをアタッチすることができないため、AWS CLIや、AWSのサービスアクションを必要とするエージェントを実行したい場合はアクセスキーの発行が必要となります。 但し、アクセスキーを発行してインスタンス内部に格納することはバッドプラクティスなので、EC2ならば回避している実装を敢えて行う必要があります。 4. EC2移行時の同一IPアドレス維持 SnapshotをEC2にエクスポートする場合に、Lightsailで使用していたIPアドレスを維持できませんので、必ずIPアドレスが変更となります。 Lightsail (Instance) で設定できる項目一覧 運用 コンソールからSSH接続が可能 パブリックIPが自動割当 停止・起動・再起動が直感的に可能 監視 CPU利用率の監視が可能 アラートをEメールで運用者に通知可能 ネットワーキング Security Groupと同様にインバウンドのアクセス制限が可能 アウトバウンドのアクセス制限は不可 IPv6で接続可能 ロードバランサーを利用した負荷分散が可能 CDNを利用可能 バックアップ 手動スナップショット 自動スナップショット (取得時間をHH:mmで指定) ディスク 初期構築時に指定した容量や性能値は、構築後に変更不可 追加のディスクをアタッチ可能 ハードウェア (CPU/メモリ) 初期構築時に指定した容量や性能値は、構築後に変更不可 タグ管理 インスタンスにタグの付与が可能 その他 CloudFormationでリソースの構築と管理が可能 但しパラメータの名称と値の定義は、EC2と異なる 参考: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lightsail-instance.html まとめ (所感) 記事執筆時点でLightsailのリリースから約5年が経ちますが、企業が導入するケースはお世辞にも多いとは言えず、主に小規模または検証用途のサービスとして認知されてきた側面が大きいものです。 そんなLightsailですが、近年「内製化」というキーワードがクローズアップされたあたりから、Webサーバ構築の選択肢として急に再注目されるようになってきたと感じます。 再注目の主な要因ですが、自社でAWSエンジニアが育ちきっていない状況でも開発着手のハードルが低く、特にインフラの開発を省力化でき、さらにランニングコストも小さく実現できることが挙げられると考えます。 ノーコード・ローコードと同じとは言えないものの、似たような背景があるのではないかと考えます。 少なくとも、この記事で上げた「手放すもの」を取り急ぎ諦めてでも、コーポレートサイトや自社サービス紹介サイトを最速でリリースすることに尖れば、AWSの数あるサービスの中では最も使えます。 また、従来はEC2を最小構成 (スペック) で構築することが最初のスモールスタートと言われてきましたが、Lightsailはその更に前段に位置づけることができ、ビジネス全体の究極のスモールスタートを支えるサービスとも言えます。 リリース後にビジネスの発展やエンジニアのスキル向上に合わせてEC2に移行し、本格運用に移る選択肢を取れることも、大きなメリットと言えるでしょう。 参考文献 Lightsail ドキュメント Lightsail resource type reference
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS Step Functions Localでモックテストをする

はじめに AWS Step Functions Local にモックテストができる機能が1/31に追加されました。 AWS Step Functions でローカルなワークフローを模擬的にテストすることが可能に 私はこのモック機能でStep Functions Localのことを知ったわけですが、2019年の2月には出ていた機能になります。 AWS Step Functions ワークフローをローカルで開発してテストする 弊社にはStep Functionsを軸として複数のLambdaを呼ぶシステムがあるため、モックテストを追加していく流れと注意点を紹介します。 実際の導入工程を例にしていますが、値をマスクしたり本記事とズレる箇所は省略したりしています。 弊社システムのステートマシーンの定義はこのようなものです。 Step Functions Localのメリット ステートを追加する際に検証がしやすくなります。 Step Functions LocalからAWS上にある指定したLambdaを呼べるので、動作確認が簡易になります。 Lambda以外にもStep Functionsが対応しているサービスのレスポンスをモックできます。 リトライ処理が意図通りかの確認がしやすくなります。 前提条件 Step Functions Localを追加するシステムは下記のようなつくりになっています。 SAM aslファイルはYAMLで記載 SAMテンプレートのDefinitionSubstitutionsプロパティでLambdaのARNを指定 IAM User Lambdaを実行するAWSアカウントのクレデンシャル情報を保持している Dockerを使ったローカル開発環境がある 先に記載しますが、Lambdaを呼ぶクレデンシャルに下記の制限が存在します。 Lambdaを呼ぶ場合、クロスアカウントアクセスはできません。 2022/02/18時点では、ドキュメントへの記載はありませんでした。 上記の条件のもと、いくつか詰まった箇所があったため、まとめていきます。 ディレクトリ構成 . ├── docker-compose.yaml └── statemachine ├── MockConfigFile.json ├── aws-stepfunctions-local-credentials.txt └── test-sample-statemachine.asl.json ステートマシーンのデータフロー 以降にASLでの定義ファイルも記載しますが、本記事では本番稼働しているシステムから必要な分のLambdaのみを残したデータフローを例にします。 Step Functions Localを追加する AWS公式ドキュメントにも実装のステップは記載されていますが、今回は下記の手順で追加、モックテストを実施していきます。 Docker ComposeにStep Functions Localを追加 Step Functions Localのモック用設定ファイルの追加 Step FunctionsのASLファイルの用意 ローカルにステートマシーンを作成 ハッピーパスの実行 リトライパスの実行 Hybridパスの実行 Docker ComposeにStep Functions Localを追加 Step Functions Localの導入には、公式ドキュメントでDocker版とJava版が用意されています。 今回は既にdocker-compose.yamlが開発環境に存在しているので、Docker版を利用しYAMLに追加します。 version: "3" services: statemachine: image: amazon/aws-stepfunctions-local:latest container_name: "statemachine" ports: - 8083:8083 environment: - SFN_MOCK_CONFIG=/home/StepFunctionsLocal/MockConfigFile.json volumes: - ./statemachine:/home/StepFunctionsLocal env_file: - ./statemachine/aws-stepfunctions-local-credentials.txt networks: lambda-local: ipv4_address: 172.18.0.7 networks: lambda-local: external: false driver: bridge ipam: driver: default config: - subnet: 172.18.0.0/16 gateway: 172.18.0.1 docker-compose.yamlの各種設定 image AWS公式のレポジトリにイメージが存在します environment 後述のモックテストケースの設定ファイルパスを環境変数に追加します。 volumes SFN_MOCK_CONFIGでセットしたパスに共有できるように設定しています。 コンテナのユーザはstepfunctionslocalユーザとなっているため、パスには注意が必要です。 env_file クレデンシャル情報を記載する、aws-stepfunctions-local-credentials.txtのパスを指定して、環境変数に追加します。 Step Functions Localのモック用設定ファイルの追加 モック機能を使うにあたって、設定ファイルが3つあります。 aws-stepfunctions-local-credentials.txt MockConfigFile.json ステートマシーン定義ファイル aws-stepfunctions-local-credentials.txt AWS_ACCESS_KEY_IDなどのクレデンシャル情報や、ローカル開発環境にLocalStackなどを利用してAWSサービスを用意している場合には、LAMBDA_ENDPOINTなどのエンドポイント先をこちらに記載します。 エンドポイントの設定項目名などは、AWS公式ドキュメントに記載があります。 AWS_DEFAULT_REGION=ap-northeast-1 AWS_ACCESS_KEY_ID=************** AWS_SECRET_ACCESS_KEY=************** AWS_ACCOUNT_ID=000000000000 WAIT_TIME_SCALE=1 ここでAWS_ACCOUNT_IDを設定しない場合、内部では123456789012がアカウントIDとして設定されます。 以降は、000000000000とマスクしています。 MockConfigFile.json モックテストの設定ファイルです。 大きく分けて、StateMachinesとMockedResponsesがあります。 StateMachines モック用ステートマシーンの設定です。テストケースに記載された内容が、ローカル環境のステートマシーンでモック実行されます。 MockedResponses 各ステートに対する、モックのレスポンス設定です。 { "StateMachines": { "sample-statemachine": { "TestCases": { "HappyPath": { "Get data": "MockedGetData", "Aggregate messages": "MockedMessages" }, "RetryPath": { "Get data": "MockedGetData", "Aggregate messages": "MockedMessagesRetryStatus", }, "HybridPath": { "Get data": "MockedGetDataFailed" } } } }, "MockedResponses": { "MockedGetData": { "0": { "Return": { "message": "json messages HOGE", } } }, "MockedMessages": { "0": { "Return": { "message": "response from mocked state", } } }, "MockedMessagesRetryStatus": { "0-6": { "Throw": { "Error": "RetryUntilSentStatusException", "Cause": "not ready." } }, "7": { "Return": { "StatusCode": 200, "Payload": { "StatusCode": 200, "body": "OK" } } } }, "MockedGetDataFailed": { "0": { "Throw": { "Error": "FileNotFoundException", "Cause": "[ERROR] FileNotFoundException Traceback (most recent call last):  File \"/var/task/app.py\", line 72, in lambda_handler    raise FileNotFoundException" } } } } } StateMachines部分 "StateMachines": { "sample-statemachine": { "TestCases": { "HappyPath": { "Get data": "MockedGetData", "Aggregate messages": "MockedMessages" }, "RetryPath": { "Get data": "MockedGetData", "Aggregate messages": "MockedMessagesRetryStatus", }, "HybridPath": { "Get data": "MockedGetDataFailed" } } } } StateMachinesの要素である、ステートマシーン名はローカル環境にステートマシーンを作成する、CreateStateMachineを実行する際のnameと一致する必要があります。 TestCasesの中には、今回3つのモックテストケースを記載しています。それぞれのパス名をモックテスト実行時に指定することで、そのテストができます。そのため、どのようなモックテストなのか、わかりやすいパス名の方が良さそうです。 HappyPath 成功する想定のモックテストです。すべてステートをモックテストで構成しています。 RetryPath エラーレスポンスするモック実行を含んだリトライ処理の確認をします。 モックがエラーを返すため、ステートマシーンはステートがエラーと判断し、Retryにしたがって複数回リトライします。 HybridPath エラーレスポンスをモックで返し、エラー時に呼ばれるLambdaをASLファイルの定義に従って実行します。 エラーレスポンスを返すモックを実行後、エラー時の後続処理を実行します。 MockConfigFile.jsonに書かれていない後続処理は、ASLファイルのResourceに従いAWS上のリソースを実行します。 MockedResponses部分 "MockedMessagesRetryStatus": { "0-6": { "Throw": { "Error": "RetryUntilSentStatusException", "Cause": "not ready." } }, "7": { "Return": { "StatusCode": 200, "Payload": { "StatusCode": 200, "body": "OK" } } } } "0-6"のように記載をすることで、最初の7回はRetryUntilSentStatusExceptionのモックレスポンスが返り、8回目で"7"で記載しているOKのレスポンスを返すことができます。 これにより、リトライ処理の確認がローカル環境でできます。 動的な並列実行の場合の記載は、公式ドキュメントに注意書きがあります。 ステートマシーン定義ファイル 素直には行かなかったポイント1つ目です。先に今回の問題と、その解決方法を記載します。 問題 create-state-machineコマンドで、既存のYAMLが使えません。 create-state-machineコマンドはDefinitionSubstitutionsのようにLambdaのARNを渡せません。 解決 describe-state-machineコマンドで実際のStep Functionsから定義ファイルを取得、作成します。 YAMLが使えない create-state-machineコマンドでYAMLを指定した場合、InvalidDefinitionエラーになりました。 create-state-machineのリファレンスにもある通り、JSONにしか対応していないので、読めば当たり前のことでした。 aws stepfunctions create-state-machine --endpoint http://localhost:8083 --definition file://sample-statemachine.asl.yaml --name "sample-statemachine" --role-arn "arn:aws:iam::000000000000:role/service-role/LambdaSQSIntegration" # An error occurred (InvalidDefinition) when calling the CreateStateMachine operation: Invalid State Machine Definition: ''INVALID_JSON_DESCRIPTION: Unrecognized token 'Comment': was expecting (JSON String, Number, Array, Object or token 'null', 'true' or 'false') ここでは1行目でCommentを記載しているため、これがJSONになっていないことを指摘されています。 ARNを渡せない SAMテンプレートのDefinitionSubstitutionsで定義していたARNを参照する方法がないため、これまたInvalidDefinitionエラーになりました。 APIリファレンスを確認しましたが、実現する方法がありませんでした。 これまではSAMの恩恵に与っていたということに気づきました。 aws stepfunctions create-state-machine --endpoint http://localhost:8083 --definition file://sample-statemachine.asl.json --name "sample-statemachine" --role-arn "arn:aws:iam::000000000000:role/service-role/LambdaSQSIntegration" # An error occurred (InvalidDefinition) when calling the CreateStateMachine operation: Invalid State Machine Definition: ''SCHEMA_VALIDATION_FAILED: Value is not a valid resource ARN at /States/Get data/Resource', Step FunctionsのASLファイルの用意 YAMLも使えず、ARNも渡せないため、YAMLをJSONに変換し、ARNはsedで書き換えるしかないかと考えましたが、変換後のASLファイルはデプロイされたStep Functionsの定義と同じであることに気がつきました。 そのため、DescribeStateMachineコマンドから定義を取得し、JSONファイルを生成します。 aws stepfunctions describe-state-machine --state-machine-arn arn:aws:states:ap-northeast-1:000000000000:stateMachine:stg-sample-statemachine | jq '.definition | fromjson' > sample-statemachine.asl.json 今回、利用する定義ファイルは下記のような形です。 実際にシステムで利用している定義ファイルから、モックテストに不要な箇所は省いています。 { "Comment": "A API relay state machine", "StartAt": "Get data", "States": { "Get data": { "Type": "Task", "Resource": "arn:aws:lambda:ap-northeast-1:000000000000:function:stg-data-provider-function", "Retry": [ { "ErrorEquals": [ "RetryServiceException", "Lambda.ServiceException", "Lambda.AWSLambdaException", "Lambda.SdkClientException" ], "IntervalSeconds": 10, "MaxAttempts": 3, "BackoffRate": 5 } ], "Next": "Aggregate messages" }, "Aggregate messages": { "Type": "Task", "Resource": "arn:aws:lambda:ap-northeast-1:000000000000:function:stg-aggregate-request-function", "Retry": [ { "ErrorEquals": [ "RetryUntilSentStatusException" ], "IntervalSeconds": 10, "MaxAttempts": 7, "BackoffRate": 2 } ], "Catch": [ { "ErrorEquals": [ "States.TaskFailed" ], "ResultPath": "$.Cause", "Next": "Failed to execute" } ], "End": true }, "Failed to execute": { "Type": "Task", "Resource": "arn:aws:lambda:ap-northeast-1:000000000000:function:stg-failed-state-function", "Parameters": { "error_info.$": "$.Cause" }, "End": true } } } ローカル開発環境にステートマシーンを作成 ここまで用意ができれば、あとはモックテストを実施していくだけです。 まずはコンテナを立ち上げます。 docker compose up -d ステートマシーンのエンドポイントに対して、CreateStateMachineコマンドを実行し、ステートマシーンを作成します。 aws stepfunctions create-state-machine --endpoint http://localhost:8083 --definition file://statemachine/test-sample-statemachine.asl.json --name "sample-statemachine" --role-arn "arn:aws:iam::000000000000:role/service-role/LambdaSQSIntegration" # { # "stateMachineArn": "arn:aws:states:ap-northeast-1:000000000000:stateMachine:sample-statemachine", # "creationDate": "2022-02-07T17:32:11.208000+09:00" # } ARNからわかる通り、アカウントIDはaws-stepfunctions-local-credentials.txtのAWS_ACCOUNT_IDが指定されています。 statemachineコンテナのログ上も、作成されていることが確認できます。 docker compose logs statemachine # statemachine | 2022-02-07 08:32:11.225: [200] CreateStateMachine <= {"sdkResponseMetadata":null,"sdkHttpMetadata":null "stateMachineArn":"arn:aws:states:ap-northeast-1:000000000000:stateMachine:sample-statemachine","creationDate":1644222731208} ハッピーパスの実行 StartExecutionコマンドを使います。 state-machineオプションのARNの末尾に、#とテストパス名を指定するとモック実行ができます。 ステートマシーンの実行名が被らないように、dateコマンドで別名にしています。 aws stepfunctions start-execution --endpoint http://localhost:8083 --name sample-statemachine-`date +%Y%m%d-%H%M%S` --state-machine arn:aws:states:ap-northeast-1:000000000000:stateMachine:sample-statemachine#HappyPath # { # "executionArn": "arn:aws:states:ap-northeast-1:000000000000:execution:sample-statemachine:sample-statemachine-20220207-193033", # "startDate": "2022-02-07T19:30:33.879000+09:00" # } リトライパスの実行 RetryPathも同じく、ARNの末尾のみを変えて実行します。 aws stepfunctions start-execution --endpoint http://localhost:8083 --name sample-statemachine-`date +%Y%m%d-%H%M%S` --state-machine arn:aws:states:ap-northeast-1:000000000000:stateMachine:sample-statemachine#RetryPath # { # "executionArn": "arn:aws:states:ap-northeast-1:000000000000:execution:sample-statemachine:sample-statemachine-20220208-171915", # "startDate": "2022-02-08T17:19:15.897000+09:00" # } コンテナのログから、リトライしている様子が確認できます。 statemachine | 2022-02-08 08:19:16.816: arn:aws:states:ap-northeast-1:000000000000:execution:sample-statemachine:sample-statemachine-20220208-171916 : {"Type":"LambdaFunctionFailed","PreviousEventId":23,"LambdaFunctionFailedEventDetails":{"Error":"RetryUntilSentStatusException","Cause":"not ready."}} statemachine | 2022-02-08 08:19:26.820: arn:aws:states:ap-northeast-1:000000000000:execution:sample-statemachine:sample-statemachine-20220208-171916 : {"Type":"LambdaFunctionFailed","PreviousEventId":26,"LambdaFunctionFailedEventDetails":{"Error":"RetryUntilSentStatusException","Cause":"not ready."}} statemachine | 2022-02-08 08:19:46.803: arn:aws:states:ap-northeast-1:000000000000:execution:sample-statemachine:sample-statemachine-20220208-171916 : {"Type":"LambdaFunctionFailed","PreviousEventId":29,"LambdaFunctionFailedEventDetails":{"Error":"RetryUntilSentStatusException","Cause":"not ready."}} statemachine | 2022-02-08 08:20:26.785: arn:aws:states:ap-northeast-1:000000000000:execution:sample-statemachine:sample-statemachine-20220208-171916 : {"Type":"LambdaFunctionFailed","PreviousEventId":32,"LambdaFunctionFailedEventDetails":{"Error":"RetryUntilSentStatusException","Cause":"not ready."}} statemachine | 2022-02-08 08:21:46.730: arn:aws:states:ap-northeast-1:000000000000:execution:sample-statemachine:sample-statemachine-20220208-171916 : {"Type":"LambdaFunctionFailed","PreviousEventId":35,"LambdaFunctionFailedEventDetails":{"Error":"RetryUntilSentStatusException","Cause":"not ready."}} statemachine | 2022-02-08 08:24:26.631: arn:aws:states:ap-northeast-1:000000000000:execution:sample-statemachine:sample-statemachine-20220208-171916 : {"Type":"LambdaFunctionFailed","PreviousEventId":38,"LambdaFunctionFailedEventDetails":{"Error":"RetryUntilSentStatusException","Cause":"not ready."}} statemachine | 2022-02-08 08:29:46.406: arn:aws:states:ap-northeast-1:000000000000:execution:sample-statemachine:sample-statemachine-20220208-171916 : {"Type":"LambdaFunctionFailed","PreviousEventId":41,"LambdaFunctionFailedEventDetails":{"Error":"RetryUntilSentStatusException","Cause":"not ready."}} statemachine | 2022-02-08 08:40:25.958: arn:aws:states:ap-northeast-1:000000000000:execution:sample-statemachine:sample-statemachine-20220208-171916 : {"Type":"LambdaFunctionSucceeded","PreviousEventId":44,"LambdaFunctionSucceededEventDetails":{"Output":"{\"StatusCode\":200,\"body\":\"OK\"}"}} ASLファイルではリトライ処理を下記のように設定していました。 "IntervalSeconds": 10, "MaxAttempts": 7, "BackoffRate": 2 リトライ時間はIntervalSeconds * BackoffRate^(n - 1) (n >1の時)になるため、10、20、40、80、160、320秒ごとにリトライ処理でモック実行が走り、その都度、エラーレスポンスを返しています。 そして、7回目のリトライから640秒後、最初の実行から8回目の実行であるリトライ処理時に、OKの成功レスポンスが返ってきていることが確認できます。 Hybridパスの実行 こちらも同じく、ARNの末尾のみを変えて実行します。 aws stepfunctions start-execution --endpoint http://localhost:8083 --name sample-statemachine-`date +%Y%m%d-%H%M%S` --state-machine arn:aws:states:ap-northeast-1:000000000000:stateMachine:sample-statemachine#HybridPath # { # "executionArn": "arn:aws:states:ap-northeast-1:000000000000:execution:sample-statemachine:sample-statemachine-20220221-172535", # "startDate": "2022-02-21T17:25:36.607000+09:00" # } コンテナのログにもステートの遷移が確認できますが、Lambdaを呼んでいるのかは少しわかりづらいです。 statemachine | 2022-02-21 08:28:57.590: arn:aws:states:ap-northeast-1:000000000000:execution:sample-statemachine:sample-statemachine-20220221-172856 : {"Type":"LambdaFunctionFailed","PreviousEventId":4,"LambdaFunctionFailedEventDetails":{"Error":"FileNotFoundException","Cause":"[ERROR] FileNotFoundException Traceback (most recent call last):??File \"/var/task/aws_lambda_powertools/tracing/tracer.py\", line 315, in decorate ????response = lambda_handler(event, context, **kwargs)??File \"/var/task/aws_lambda_powertools/metrics/metrics.py\", line 184, in decorate????response = lambda_handler(event, context)??File \"/var/task/app.py\", line 72, in lambda_handler????raise FileNotFoundException"}} statemachine | 2022-02-21 08:36:49.853: arn:aws:states:ap-northeast-1:000000000000:execution:sample-statemachine:sample-statemachine-20220221-173648 : {"Type":"LambdaFunctionSucceeded","PreviousEventId":9,"LambdaFunctionSucceededEventDetails":{"Output":"null"}} statemachine | 2022-02-21 08:36:49.853: arn:aws:states:ap-northeast-1:000000000000:execution:sample-statemachine:sample-statemachine-20220221-173648 : {"Type":"TaskStateExited","PreviousEventId":10,"StateExitedEventDetails":{"Name":"Failed to execute","Output":"null"}} statemachine | 2022-02-21 08:36:49.854: arn:aws:states:ap-northeast-1:000000000000:execution:sample-statemachine:sample-statemachine-20220221-173648 : {"Type":"ExecutionSucceeded","PreviousEventId":11,"ExecutionSucceededEventDetails":{"Output":"null"}} 1つ目のログ statemachine localで意図的にエラーとなるモック実行が走ります。ここでは、FileNotFoundExceptionを起こします。 3つ目のログ ASLファイルの記載に従ってLambdaがFailedした場合、Failed to executeのステートに遷移します。 4つ目のログ MockConfigFile.jsonにFailed to executeのステートが記載されていない場合、ResourceのARNが呼ばれます。 実際に呼ばれたLambdaのCloudWatch Logsの様子です。 モック実行から渡したエラーメッセージが、ログに来ていることがわかります。 クロスアカウントでLambdaは呼べない 上手く行かず、方針を変えたポイントです。 クロスアカウントでLambdaを呼び出そうとすると、エラーになります。 aws stepfunctions start-execution --endpoint http://localhost:8083 --name sample-statemachine-`date +%Y%m%d-%H%M%S` --state-machine arn:aws:states:ap-northeast-1:000000000000:stateMachine:sample-statemachine#HybridPath 000000000000のIAMユーザから000000000001のLambdaにアクセスしようとしていました。 statemachine | 2022-02-14 07:45:16.829: arn:aws:states:ap-northeast-1:000000000000:execution:sample-statemachine:sample-statemachine-20220214-164516 : {"Type":"LambdaFunctionFailed","PreviousEventId":4,"LambdaFunctionFailedEventDetails":{"Error":"FileNotFoundException","Cause":"[ERROR] FileNotFoundException Traceback (most recent call last):??File \"/var/task/aws_lambda_powertools/tracing/tracer.py\", line 315, in decorate ????response = lambda_handler(event, context, **kwargs)??File \"/var/task/aws_lambda_powertools/metrics/metrics.py\", line 184, in decorate????response = lambda_handler(event, context)??File \"/var/task/app.py\", line 72, in lambda_handler????raise FileNotFoundException"}} statemachine | 2022-02-14 07:45:17.479: arn:aws:states:ap-northeast-1:000000000000:execution:sample-statemachine:sample-statemachine-20220214-164516 : {"Type":"LambdaFunctionFailed","PreviousEventId":9,"LambdaFunctionFailedEventDetails":{"Error":"Lambda.ResourceNotFoundException","Cause":"Function not found: arn:aws:lambda:ap-northeast-1:000000000000:function:stg-sample-failed-state-function (Service: AWSLambda; Status Code: 404; Error Code: ResourceNotFoundException; Request ID: 12a08bcc-acce-45d3-986f-a2049ca6eb30; Proxy: null)"}} statemachine | 2022-02-14 07:45:17.482: arn:aws:states:ap-northeast-1:000000000000:execution:sample-statemachine:sample-statemachine-20220214-164516 : {"Type":"ExecutionFailed","PreviousEventId":10,"ExecutionFailedEventDetails":{"Error":"Lambda.ResourceNotFoundException","Cause":"Function not found: arn:aws:lambda:ap-northeast-1:000000000000:function:stg-sample-failed-state-function (Service: AWSLambda; Status Code: 404; Error Code: ResourceNotFoundException; Request ID: 12a08bcc-acce-45d3-986f-a2049ca6eb30; Proxy: null)"}} 残念ながら、AWS_ACCOUNT_IDで設定していたアカウントIDのリソースにしかアクセスできませんでした。 また、aws-stepfunctions-local-credentials.txtのAWS_ACCOUNT_IDをセットしなかった場合、エラーメッセージのARNはAWS_ACCESS_KEY_IDに設定した、IAMユーザのアカウントIDに変わりました(驚)。 "Cause":"Function not found: arn:aws:lambda:ap-northeast-1:000000000000:function:stg-sample-failed-state-function ... " どうしてもクロスアカウントでLambdaを呼びたい 弊社のシステムにモックテストを追加するにあたっては、実際のASL定義から離れるため実施していませんが、下記のようにクロスアカウント先のLambdaを呼ぶ手もあります。 SNSを利用する Lambdaを実行するステートの代わりにSNSを設定し、StepFunctions localからSNSを呼ぶようにASLファイルを指定します。 SNSからクロスアカウント先のLambdaに通知をします。 LambdaからLambdaをinvokeする 呼び元のアカウントに、InvokeするLambdaを作成します。 Lambdaを実行するステートの代わりに、invokeするLambdaを設定します。 おわりに 既存の実際に本番稼働しているシステムに対して、Step Functions Localでのモックテストを追加してみました。 Step FunctionsがAWSの多くのサービスに対応したことで、今後は様々なシーンで利用機会が増えそうです。 その際に今回のモック機能を導入することで開発が楽になり、この記事がその導入の一助になれば嬉しいです。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

aws Lightsail WordPressインスタンス と Route53 で Webページ を配信する

最終形 Lightsail WordPressインスタンスを生成する こちらのチュートリアルに従ってインスタンスをつくっていきます。ステップ5まで実施し、ステップ6以降は別の方式で進めます。 独自ドメインの使用と https 通信の実現 これまでの作業で、WordPressインスタンスにアタッチした静的 IP アドレスを用いて Webページを pull できるようになりました。 この状態では以下の課題が残ってしまっています。 独自ドメインの利用 (Must) https 通信を行う (Must) TLS証明書を取得する (Must) TLS証明書を有効期限内に自動更新する (できたら) CDN を使う (できたら) Must要件のみ解決するには、WordPressプラグイン (Really Simple SSL) + Certbot + Route53 の組み合わせで完全に無料で実現できます。実際にこの組み合わせで構築し、半年間運用しましたが全く問題なく運用することができました。 しかしながら、TLS証明書は利用開始後3か月経過するごとに証明書の有効期限を迎えるので証明書の更新が必要となり、更新を怠ると http通信にダウングレードされてしまいます。Certbot を用いた方式は aws の責任共有モデルで言うところのユーザ責任での運用となり、自動更新の仕組みを作ったとしても、更新の前後では確認作業が必須になってしまいそうです。 証明書の更新を自動で安全に行うには、aws の CertificateManager を使用するのがよさそうです。CertificateManager を使用するには、aws の ELB または CloudFront を使用しなければなりません。CloudFront の利用を検討していたところ、Lightsail には ディストリビューション というサービスがあって、CloudFront と同じことをやってくれそうです。しかも WordPress に最適化されたキャッシュ機能が選択できるので、これを採用してみようと思います。 Lightsail ディストリビューションを生成する こちらの一次情報に従ってディストリビューションを作成します。 TLS証明書を作成する こちらの一次情報に従ってTLS証明書を作成します。 ディストリビューションでカスタムドメインを有効にする こちらの一次情報に従って設定します。 DNS で ドメインまたはサブドメインを ディストリビューション にポイントする Aレコードのエイリアスを使用しました。 ディストリビューションと連携が可能になるように WordPressインスタンス を設定する ここまでの作業でカスタムドメインを使用して Webページが pull できるようになっています。しかし WordPress のテーマによっては画面レイアウトが崩れてしまっていて、カスタムドメインを使用して WordPress の管理画面にログインすると、ここの画面のレイアウトもおかしくなっています。 こちらの一次情報に従って設定を行い、サービスを再起動するとレイアウトは正常に戻ります。 おまけ WordPress のバックアップ All-in-One WP Migration というプラグインがおすすめです。 2段階認証 Google Authenticator がおすすめです。バックアップコードは生成できないので、2段階認証を中断するには wp-content/plugins/google-authenticator フォルダをリネームするなどして対応できます。 ユーザ名、パスワードがわからなくなったら WordPress のログイン画面では、パスワードがわからなくなったらメールでリセットする仕組みになっています。しかし aws Lightsail インスタンスからメールを出すには一手間かかるので、最終手段として MySQLデータベース上のパスワードを更新する手順を持っておくと安心だと思います。 こちらに一次情報がありますが、ちょっと理解するのが難しい内容でしたので、以下に手順を残しておきます。 MySQL DB名、ユーザ名、パスワード取得 wp-config.php から取得する MySQL DB接続 mysql -u (ユーザ名) -p DB一覧取得 show databases; ユーザDB切替 use (DB名); table一覧取得 show tables; ユーザ情報取得 (***_ は wp-config.php で設定されているプレフィクスです) select * from ***_users; パスワード変更 update ***_users set user_pass = MD5('NewPasswd') where ID = 'hoge'; 成果物 unremoted.com 組織 同上
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ELB暖機申請まとめ

はじめに ELBの暖機申請を実施する時に何をサポートに伝えればいいんだっけ?を自分の備忘も兼ねてまとめておく。 本題 ELBの暖機申請はAWSサポートから起票します。 内容に不備・不明点があればAWSサポートから質問が来ますので一発で申請を完璧にする必要はありません。 条件が整えば、申請した日時にAWS側でELBの暖機運転(Pre-warming)を実施してくれます。 サポート起票 AWSサポートを起票します。 Case type: Technical Service: Elastic Load Balancing(ELB) Category: ロードバランサー関連 Severity: General guidance タイムスタンプ(UTC)- optional: 空白のまま エラーコードの説明 - optional: 空白のまま Subject: ELB暖気申請 Description: 暖機申請の内容を記載する 申請フォーマット 記載する必要がある情報は以下 この内容は上で起票しているサポートケースのDescriptionに記載します。 リージョン ap-northeast-1(東京リージョン) etc... 暖機対象のELB ELB名、もしくはELBのARN 予測されるピーク時のリクエスト数(requests/sec) 20000req/sec etc... 予想されるピーク時の1リクエストあたりの平均リクエストサイズ+レスポンスサイズ(bytes), または想定スループット(bit/秒) 1リクエストあたり平均300byte,レスポンスの平均100KByte etc... 暖気運転が必要となる期間 yyyy-mm-dd-hh-mm ~ yyyy-mm-dd-hh-mm HTTPSの利用有無と割合 http 0% : https: 100% etc... バックエンドインスタンスでのKeep-aliveの設定可否 ELBhogeのバックエンドインスタンスにてKeep-aliveの利用あり etc... ELBで利用するAZの数 ap-northeast-1b/ap-northeast-1d etc... イベント当日までのバックエンドインスタンスの増加の有無 ELBhogeは1b,1dそれぞれに2台ずつインスタンスを追加します etc... トラフィックパターン(トラフィックの傾向とともに予想される最大・最少アクセスの時間) キャンペーン開始後(AM9時頃)20000req/secのアクセスが予想されます。1時間程でトラフィックは落ち着く見込みですが、キャンペーン期間中はトラフィックの増加が見込まれる予定です。 etc... ユースケース ECサイトの期間限定キャンペーンに伴うトラフィックの急激な増加を見込んでいるため。 さいごに 申請が通るとAWSより暖機設定完了の連絡がきます。 お疲れ様でした。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

aws S3 + CloudFront + Certificate Manager + Route53 で静的Webページを配信する

最終形 これからやってみること S3 + CloudFront + Route53 の組み合わせで静的 Webページ を配信するのは、aws のベストプラクティスの中でも「横綱」と言われています。私個人の Webページ をこのスタイルで配信してみましたので、その手順をご紹介します。 何がうれしいのか S3 と CloudFront はともに極めて高い可用性を持つサービスであるため、安心してWebページの配信を任せられる すべてマネージドサービスなので運用、保守はすべて aws で対応してもらえる Certificate Manager により面倒な SSL/TLS証明書 の取得と更新を自動で対応してもらえる 個人の Webページ であれば月額数十円で運用できる 前提条件 S3、CloudFront の操作が可能な aws アカウントを所持している 独自ドメインを所持し Route53 などの「権威DNS」でホストしている 話は少しズレますが、私は以前 (2017年)、レンタルサーバからWebページを配信しておりまして、DNS もレンタルサーバの機能を使っていました。当時はこの DNS を用いて S3 + CloudFront によるWeb配信にチャレンジしたのですが、レンタルサーバの機能では必要な設定ができませんでした (S3 をエンドポイントにするところまでは対応可能だったが Certificate Manager の設定で必要な DNS 検証ができなかった)。 そこでレンタルサーバ運営会社で取得したドメインを aws へ移管し、Route53 によるDNS管理をはじめるようになりました。 Route53 はいわゆる「権威DNS」なのでドメイン管理で必要な設定はすべて実施できます。SLA は100%と言われており、繰り返し起こるドメイン乗っ取りの恐怖から解放され、しかも月額 0.5USD ほどで運用できてしまうので、aws らしい、とても高価値なサービスだと思っています。 公式手順 この公式手順の中にある「OAIによってアクセスが制限されているオリジンとして REST API エンドポイントを使用する」方式で実装を進めました。つまり、S3 のパブリックアクセスを行うことなく CloudFront に対してのみアクセスを可能とする、とてもセキュアなデータアクセス方式を採用しています。 動作確認 代替ドメイン名 (tms.demoru.net) で Webページが表示できれば OK https://tms.demoru.net だけでなく、http://tms.demoru.net でアクセスすると https://tms.demoru.net にリダイレクトされるので確認しておきましょう。 成果物 tms.demoru.net 組織 unremoted.com おまけ ドメインが expired したらどうなるのか 今回 tmstmp.com で配信していたページを tms.demoru.net に移したのは tmstmp.com が 2022年2月15日でドメインの有効期限を迎えるので、このドメインを打ち切りにしようとしたためでした。 さて、com ドメインが expired したらどうなるのか? aws からはメールで以下の「重要な日付」が通知されています。 2022年2月15日:ドメインは一時停止され、インターネットで利用できなくなります 2022年2月15日-2022年3月30日:標準料金で登録を更新できます。 2022年3月31日:ドメインがシステムから削除されます。 2022年3月31日-2022年4月30日:ドメインの登録を復元できます。ドメイン登録を復元するための価格は、トップレベルドメイン(TLD)によって異なります。詳細については、AWSRoute53の料金をご覧ください。 2022年5月5日:レジストリによっては、この日付以降、誰でもこのドメインを登録できる場合があります。 なかなか経験できないイベントなので、どのタイミングで利用できなくなるのか確認してみました。事前の予想は、国際標準時の 2/16 0:00 または太平洋時の 2/16 0:00 以降に expires すると考えていました。日本時間で言うと 2/16 9:00 または 2/16 17:00 以降ということになります。 結果は、2/16 の 23時過ぎにブラウザからの閲覧ができなくなりました。aws より 23:04 に「Registration for tmstmp.com has expired」というメールが来ていましたので、このタイミングで expires したものと思われます。このメールにはドメインの利用を継続するためのリンクと、カスタマーサポートへ問い合わせるためのリンクが添付されていました。 あらためて、ありがとう、さようなら tmstmp.com さくらインターネットのレンタルサーバでホームページ配信やメールサービスを行ったり、aws へ移管後は S3 からのホームページ配信や、SES を用いたメール配信、EC2 を用いたサービスの ELBエンドポイントをポイントしたり、Google Workspace の独自ドメイン利用、各種証明書の取得や更新のための DNS 検証など様々なシーンで役に立ってくれました。 Route53 のホストゾーンと、CloudFront のディストリビューション、静的ページを配置していたバケットは削除しておきます。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

sls deployでThe stack service name 〜〜 is not valid. と出た時の対処法

概要 sls createして作ったサービスをデプロイしようとした時、 コマンドsls deployでThe stack service name 〜〜 is not valid.というエラーが出たので、解決方法を書きます。 エラー The stack service name "sls_go_project-dev" is not valid. A service name should only contain alphanumeric (case sensitive) and hyphens. It should start with an alphabetic character and shouldn't exceed 128 characters. エラー文を読むとサービス名の制約が書かれていました。 * サービス名はアルファベットとハイフンだけである。 * アルファベットで始まり、128文字を超えないこと。 serverless.ymlの設定を見直しました。 原因 serverless.ymlのservice:以降にアンダーバーを入れていたことが原因でした。 sls createでディレクトリやその内部のファイルを一括で作成するはアラートは出ないのですが、deploy前にサービス名は変更しないといけなかったようです。 sls createした時は下記のようにエラーは出ませんでした。(sls_go_projectというのが今回指定したプロジェクト名でした。) $ sls create -u https://github.com/serverless/serverless-golang/ -p sls_go_project ✔ Project successfully created in "sls_go_project" 解決策 serverless.ymlのservice:名のアンダーバーをハイフンに書き換えるとsls deployできました。 $ sls deploy Deploying sls-go-project to stage dev (ap-northeast-1) ✔ Service deployed to stack sls-go-project-dev (113s) functions: hello: sls-go-project-dev-hello (4.3 MB) 1 deprecation found: run 'serverless doctor' for more details
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS公式資料で挑むSCS認定(5)-IAMサービス

[前回] AWS公式資料で挑むSCS認定(4)-サービス勉強順 はじめに 前回は、SCS認定対象となるサービス群の勉強順を決めました。 早速、AWSセキュリティの中核で、超重要なIAMです。 IAMの登場人物 押さえておくべき概念と用語 IAM ID(アイデンティティ) IAMユーザー 特定のユーザーにアクセス権限付与できる IAMグループ 複数IAMユーザーを束ねて同じアクセス権限を付与でき便利 IAMロール 一時アクセス権をIAMユーザー・アプリ・サービスに付与する AWSではロールをスイカ(?)帽子マークで表していた 自己解釈: 一般人でもこの帽子かぶせたら一時的に秘密基地に入れる、出たら即外されまた一般人 ※特記事項: この帽子は、アプリやEC2インスタンスにもかぶせられる IAMリソース IAMユーザーが使用・操作できるすべてのエンティティ、例 Amazon EC2 インスタンス VPC エンドポイント Amazon S3 バケット パーミッション(権限の実態もオブジェクトなので、リソースの一種か) アクション リソースへの操作、例 CreateUser RunInstances CreateBucket 認証 認証方法 パスワード IAMユーザーに付与 AWS Management Consoleへのログインに利用 アクセスキー IAMユーザーに付与 アプリAPIのアクセス認証で使用 一人二つまで 一時認証トークン(AWS STS) IAMロールが使う これを使って権限移譲できる 多要素認証(MFA) 特権ユーザーに設定 認証強化のため 認可 IAMユーザーがIAMリソースに対し、どんな権限を持ち、どんなアクションできるか。 ポリシーにIDとリソースの関連付けを記述することで、アクセス許可を定義。 ポリシーの種類です。定義主体がIDかリソースかなどによって、 IDベースポリシー 管理ポリシー 複数IAMユーザー、グループ、ロールに関連付け可能(最大10個) AWS管理ポリシー(AWSにより事前定義) カスタマー管理ポリシー インラインポリシー 単一IAMユーザー、グループ、ロールに直接埋め込む リソースベースポリシー その他ポリシー パーミッションバウンダリー AWS IAMアクセス許可の境界 IAMユーザーとロールの範囲を限定し、権限の昇格を防ぐ AWS Organizationsサービスコントロールポリシー (SCP) 組織のアクセス許可の管理に使用できる組織ポリシーの一種 アクセスコントロールポリシー (ACL) リソースへのアクセス可否設定リスト Amazon S3のバケットのACL Amazon VPCのサブネットのACL プリンシパル AWSを使う人やアプリ。 AWSサービスに接続・使用するクライアント側のことか。 IAMエンティティ 認証に使用されるリソースオブジェクト全般。 IAMユーザー、IAMロール、アプリも含まれる。 Amazonリソースネーム (ARN) AWSリソースを一意に識別するための表記。 ARN形式例: arn:partition:service:region:account-id:resource-id arn:partition:service:region:account-id:resource-type/resource-id arn:partition:service:region:account-id:resource-type:resource-id 勉強資料 AWS Black Belt オンラインセミナー資料を使って勉強しました。 わからない概念は、随時AWSユーザーガイドで検索し調べる、といった感じです。 他にも、先人たちが資料やノウハウを無償提供していました、感謝感謝。 AWS Black Belt オンラインセミナーのIAM資料 ベストプラクティスで学ぶAWSの認証・認可~ Part1 ベストプラクティスで学ぶAWSの認証・認可~ Part2 重要と思われる内容のメモ書き: アクセス可否の決定ロジック すべてのアクセスはデフォルトで拒否(暗黙的Deny) 最小権限の原則か アクセス権限に“Allow”条件があった場合、アクセス許可 ただし、アクセス権限に1つでも“Deny”の条件があった場合、アクセス拒否(明示的Deny) IAMアーキテクチャ図 下記ブログ記事のアーキテクチャ図がわかりやすかったので共有します。 IAM全体像を一枚にまとめられるなんて、名人には脱帽です。 引用元: ざっくり絵で理解するAWSのIAM用語「ユーザ、グループ、ロール、ポリシー」 手元において常時眺めてみたいので、ブックマークに入れておきました。 おわりに IAMサービスが提供するアクセス制御機能について勉強しました。 AWSセキュリティの土台、ということもあり、奥深いですね。 次回は、VPCの勉強に移ります。お楽しみに。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS公式資料で挑むSCS認定(5)-IAM

[前回] AWS公式資料で挑むSCS認定(4)-サービス勉強順 はじめに 前回は、SCS認定対象となるサービス群の勉強順を決めました。 早速、AWSセキュリティの中核で、超重要なIAMです。 IAMの登場人物 押さえておくべき概念と用語 IAMアイデンティティ(ID) IAMユーザー 特定のユーザーにアクセス権限付与できる IAMグループ 複数ユーザーを束ねて同じアクセス権限を付与でき便利 IAMロール 一時アクセス権をユーザー・アプリ・サービスに付与する AWSではロールをスイカ(?)帽子マークで表していた 自己解釈: 一般人でもこの帽子かぶせたら一時的に秘密基地に入れる、出たら即外されまた一般人 ※特記事項: この帽子は、アプリやEC2インスタンスにもかぶせられる IAMリソース ユーザーが使用・操作できるすべてのエンティティ、例 Amazon EC2 インスタンス VPC エンドポイント Amazon S3 バケット パーミッション(権限の実態もオブジェクトなので、リソースの一種か) アクション リソースへの操作、例 CreateUser RunInstances CreateBucket 認証 認証方法 パスワード ユーザーに付与 AWS Management Consoleへのログインに利用 アクセスキー ユーザーに付与 アプリAPIのアクセス認証で使用 1アカウントにつき二つまで 一時認証トークン 有効期限付きのアクセスキーID/シークレットアクセスキー/セキュリティトークンで構成 AWS Security Token Service(AWS STS)により動的生成 IAMロールが使う これを使って権限委任できる 多要素認証(MFA) 特権ユーザーに設定 認証強化のため 認可 ユーザーがリソースに対し、どんな権限を持ち、どんなアクションできるか。 ポリシーにIDとリソースの関連付けを記述することで、アクセス許可を定義。 ポリシーの種類です。定義主体がIDかリソースかなどによって、 IDベースポリシー 管理ポリシー 複数IAMユーザー、グループ、ロールに関連付け可能(最大10個) AWS管理ポリシー(AWSにより事前定義) カスタマー管理ポリシー インラインポリシー 単一IAMユーザー、グループ、ロールに直接埋め込む リソースベースポリシー その他ポリシー パーミッションバウンダリー AWS IAMアクセス許可の境界 IAMユーザーとロールの範囲を限定し、権限の昇格を防ぐ AWS Organizationsサービスコントロールポリシー (SCP) 組織のアクセス許可の管理に使用できる組織ポリシーの一種 アクセスコントロールポリシー (ACL) リソースへのアクセス可否設定リスト Amazon S3のバケットのACL Amazon VPCのサブネットのACL プリンシパル AWSリソースに対しアクションをリクエストできるユーザーまたはアプリケーション。 プリンシパルは、AWSアカウントのルートユーザーまたはIAM エンティティとして認証される必要がある。 IAMエンティティ 認証に使用されるリソースオブジェクト全般。 IAMユーザー、IAMロール、アプリも含まれる。 Amazonリソースネーム (ARN) AWSリソースを一意に識別するための表記。 ARN形式例: arn:partition:service:region:account-id:resource-id arn:partition:service:region:account-id:resource-type/resource-id arn:partition:service:region:account-id:resource-type:resource-id 勉強資料 AWS Black Belt オンラインセミナー資料を使って勉強しました。 わからない概念は、随時AWSユーザーガイドで検索し調べる、といった感じです。 他にも、先人たちが資料やノウハウを無償提供していました、感謝感謝。 AWS Black Belt オンラインセミナーのIAM資料 ベストプラクティスで学ぶAWSの認証・認可~ Part1 ベストプラクティスで学ぶAWSの認証・認可~ Part2 重要と思われる内容のメモ書き: アクセス可否の決定ロジック すべてのアクセスはデフォルトで拒否(暗黙的Deny) 最小権限の原則か アクセス権限に“Allow”条件があった場合、アクセス許可 ただし、アクセス権限に1つでも“Deny”の条件があった場合、アクセス拒否(明示的Deny) IAMアーキテクチャ図 下記ブログ記事のアーキテクチャ図がわかりやすかったので共有します。 IAM全体像を一枚にまとめられるなんて、名人には脱帽です。 引用元: ざっくり絵で理解するAWSのIAM用語「ユーザ、グループ、ロール、ポリシー」 手元において常時眺めてみたいので、ブックマークに入れておきました。 おわりに IAMサービスが提供するアクセス制御機能について勉強しました。 AWSセキュリティの土台、ということもあり、奥深いですね。 次回は、VPCの勉強に移ります。お楽しみに。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AdminRespondToAuthChallenge operation: Invalid attributes given, name is missing

Amazon Cognito のユーザープールの設定で name などのカスタム属性を必須にしている場合、AWS CLIではそれも指定しなければならないのでその指定方法。 name がないと言われた An error occurred (InvalidParameterException) when calling the AdminRespondToAuthChallenge operation: Invalid attributes given, name is missing うん、確かにそう書いてあるよね。 NEW_PASSWORD_REQUIRED : NEW_PASSWORD , any other required attributes, USERNAME . respond-to-auth-challenge — AWS CLI 2.4.20 Command Reference でも、 NEW_PASSWORD="${new_password}",NAME=${name},USERNAME=${username} って指定しても同じ結果ですし。 というわけで正しい指定方法は userAttributes.name=${name} でしたよということでメモとして残しておこう。 $ aws cognito-idp admin-respond-to-auth-challenge \ --user-pool-id ${user_pool_id} \ --client-id ${app_client_id} \ --challenge-name NEW_PASSWORD_REQUIRED \ --challenge-responses NEW_PASSWORD="${new_password}",userAttributes.name=${name},USERNAME=${username} \ --session "${session}"
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む