APC 技術ブログ

株式会社エーピーコミュニケーションズの技術ブログです。

株式会社 エーピーコミュニケーションズの技術ブログです。

AWS アカウントに Google Workspace ユーザーでシングルサインオンしてみた。(part1)

はじめに

こんにちは。エーピーコミュニケーションズ クラウド事業部の髙野です。

今回は、以下の記事で紹介している Microsoft Entra ID 上のユーザーを AWS 環境に同期する手順の Google Workspace 版ということで、 Google Workspace ユーザーを IAM Identity Center ユーザーとしてAWS 環境に同期するための手順を紹介します。

なお、今回は少しボリュームがあるので本記事を含め3つの記事に分けて投稿します。

techblog.ap-com.co.jp

IAM Identity Center に関しては以下の記事を参照してください。

techblog.ap-com.co.jp

本記事で紹介している手順は以下を参考に記載しております。

docs.aws.amazon.com

前提条件

  • AWS アカウントで IAM Identity Center が有効になっていること。
  • Google Workspace 特権管理者権限を持つアカウントにサインインできること。
  • すべての Google Workspace ユーザーにおいて、[名]、[姓]、[ユーザー名]、[表示名] の値が指定されていること。
  • 各 Google Workspace ユーザーには、E メールアドレスや電話番号などのデータ属性ごとに 1 つの値のみが割り当てられていること。

目次

  1. AWS のカスタムユーザー属性を作成する★
  2. ID プロバイダーのメタデータをダウンロードする★
  3. Google Workspace で Amazon Web Services アプリをセットアップする★
  4. IAM Identity Center の ID ソースを変更し、Google Workspace を SAML ID プロバイダーとして設定する★
  5. Google Workspace でアプリを有効にする
  6. IAM Identity Center の自動プロビジョニングを設定する
  7. Google Workspace で自動プロビジョニングを設定する
  8. IAM Identity Center グループを作成する
  9. Google Workspace ユーザーをIAM Identity Center グループに追加する
  10. IAM Identity Center グループにアカウントへのアクセス権を付与する
  11. Google Workspace ユーザーの AWS リソースへのアクセスを確認する

手順

1.AWS のカスタムユーザー属性を作成する

1-1.特権管理者権限を持つアカウントを使用して [Google管理コンソール] にサインインします。

1-2.左側のナビゲーションパネルで、[ディレクトリ]、[ユーザー] の順に選択します。

1-3.[ユーザー] リストの上部にある [その他のオプション] を選択し、[カスタム属性を管理します] を選択します。

1-4.ページの右上にある [カスタム属性を追加] を選択します。

1-5.[カスタムフィールドを追加] ウィンドウで、以下のフィールドに入力します。

  • [カテゴリ] : Amazon
  • [説明] : Amazon Custom Attributes
  • [カスタムフィールド] : Role、テキスト、ユーザーと管理者に表示、複数の値

[保存] を選択します。

2.ID プロバイダーのメタデータをダウンロードする

2-1.[Google管理コンソール] の左側のナビゲーションパネルで、[セキュリティ] を展開し、[認証]、[SAML アプリケーションによる SSO] を選択します。

※コンソールのレイアウトによっては、[さらに表示] を選択してナビゲーションパネルの [セキュリティ] セクションを表示する必要がある場合があります。

2-2.[IdP メタデータ] で [メタデータをダウンロード] を選択します。

[GoogleIDPMetadata.xml] ファイルはデフォルトのダウンロードフォルダに保存されます。

[Google管理コンソール] は、このあとの手順でも操作を行うため、開いたままにしておいてください。

3.Google Workspace で Amazon Web Services アプリをセットアップする

3-1.Google管理コンソールの左側のナビゲーション パネルで、[アプリ]を展開し、[ウェブアプリとモバイルアプリ]を選択します。

3-2.[アプリを追加]を選択し、 [アプリを検索]を選択します。

3-3.検索ボックスに「 Amazon Web Services 」と入力し、 リストからAmazon Web Servicesを選択します。

3-4.[続行]を選択します。

※Google ID プロバイダの詳細ページには、メタデータをダウンロードするか、SSO URL、エンティティ ID、および証明書をコピーするオプションがあります。手順 2 で IdP メタデータをダウンロードしたため、これらの項目のいずれも実行する必要はありません。

3-5.[サービス プロバイダの詳細]ページで、AWS のACS URLとエンティティ ID の値がデフォルトで設定されていることを確認し、[続行]を選択します。

3-6.[属性のマッピング]ページの [属性]で、次のフィールドをGoogle ディレクトリ属性の下に追加します。

※Amazon、Role は、手順 1で作成したカスタム属性です。

3-7.完了を選択してください

4.IAM Identity Center の ID ソースを変更し、Google Workspace を SAML ID プロバイダーとして設定する

4-1.管理者権限を持つロール又はユーザーで IAM Identity Center コンソールにサインインします。

4-2.左側のナビゲーションペインで[設定]を選択します。

4-3.[設定]ページで、[アクション]を選択し、[アイデンティティソースを変更]を選択します。

4-4.[アイデンティティソースを選択]で、[外部 ID プロバイダー]を選択し、[次へ]を選択します。

4-5.[外部アイデンティティプロバイダーを設定]ページが開きます。このページを完了するには、IAM Identity Center を Google Workspace で SAML アプリとして設定し、Google管理コンソールから情報を取得する必要があります。次の手順を実行します。

4-5-1.Google管理コンソールの左側のナビゲーションパネルで、[アプリ]を展開し、[ウェブアプリとモバイルアプリ]を選択します。

4-5-2.[アプリを追加]を選択し、[カスタム SAML アプリの追加]を選択します。

4-5-3.[アプリの詳細] ウィンドウで、以下のフィールドに入力します。

  • [アプリ名] : AWS access portal

  • [説明] : Google Workspace チュートリアル用の AWS アクセスポータル

[続行] を選択します。

4-5-4.[Google ID プロバイダの詳細]ページで 、[続行]を選択します。

4-5-5.[サービス プロバイダの詳細]ページで、 ACSのURLとエンティティ IDの値を入力します。 IAM Identity Center コンソールに戻って、次の値を確認します。

  • IAM Identity Center コンソールの「サービス プロバイダーのメタデータ」で、「IAM Identity Center Assertion Consumer Service (ACS) URL」 をコピーします。 Google管理コンソールに戻り、URL を[ACSのURL]フィールドに貼り付けます。

  • IAM Identity Center コンソールの[サービス プロバイダーのメタデータ]で、「IAM Identity Center 発行者 URL 」をコピーします。 Google管理コンソールに戻り、URL を[エンティティ ID]フィールドに貼り付けます。

4-5-6.Google管理コンソール-サービス プロバイダの詳細ページで、 [名前 ID]の下のフィールドに次のように入力します。

  • [名前 ID 形式] : EMAIL

  • [説明] : Basic Information > Primary email

[続行]を選択します。

4-5-7.[属性マッピング]ページ の[属性]で[マッピングを追加]を選択し、 Google Directoryの属性で次のフィールドを設定します。

※Amazon、Role は、手順 1で作成したカスタム属性です。

4-5-8.完了を選択してください

4-6.IAM Identity Center コンソールに戻り、「外部アイデンティティプロバイダーを設定」ページに移動します。[アイデンティティプロバイダーのメタデータ]の[IdP SAML メタデータ]で[ファイルを選択]を選択し、手順 2 でダウンロードしたGoogleIDPMetadata.xmlファイルをアップロードします。

[次へ]を選択します。

4-7.[変更の確認]ページで情報を確認し、表示されたスペースに「承諾」と入力し、[アイデンティティソースを変更]を選択します。

まとめ

これで、Google Workspace ユーザーを IAM Identity Center ユーザーとしてAWS 環境に同期する準備が整いました。

次回は実際にユーザーの同期を実施したいと思います。

techblog.ap-com.co.jp

お知らせ

弊社はAWSアドバンスドティアサービスパートナー認定を受けております。また以下のようにAWSの活用を支援するサービスも行っているので、何かご相談したいことがあればお気軽にご連絡ください。

www.ap-com.co.jp

一緒に働いていただける仲間も募集中です!
今年もまだまだ組織規模拡大中なので、ご興味持っていただけましたらぜひお声がけください。

www.ap-com.co.jp

本記事の投稿者: sk07103
AWSをメインにインフラ系のご支援を担当しています。

Amazon ConnectをActive Directoryと連携する

こんにちは、クラウド事業部の山路です。

今回はAmazon ConnectとActive Directoryを連携し、Amazon ConnectへのログインにActive Directory上のユーザーを利用する方法を紹介します。

背景

Amazon Connectは複数のユーザー管理方法を提供しています。

  • Amazon Connect内でユーザーを管理
  • 既存のディレクトリとの連携
  • SAML 2.0ベースの認証

docs.aws.amazon.com

今回は多くの企業で使われているであろうActive Directoryの例を取り上げます。

Active Directoryと連携する場合、AD ConnectorというAWSのサービスを利用する必要があります。AD ConnectorはAWS Directory Serviceに含まれるディレクトリサービスの一つで、オンプレミス等に構築されたADサーバーにディレクトリ要求をリダイレクトする「ディレクトリゲートウェイ」です。これにより、既存のADに保存された認証情報を使ってAmazon Connectへのログインを実現します。

https://docs.aws.amazon.com/ja_jp/connect/latest/adminguide/images/network-path-authentication.png

AWS公式ドキュメントより

検証

ここから構築と検証を行います。大まかな流れは以下の通りです。

  • VPC等の用意
  • ADサーバーの用意
  • ADサーバー側の設定変更 (AD Connectorが接続するために必要)
  • AD Connectorの作成
  • Amazon Connectインスタンスの作成
  • Amazon Connectでユーザーの登録

docs.aws.amazon.com

事前準備

AD Connectorを作成するには、異なるAZに配置された最低2つのサブネットが必要になります。またVPCはADサーバーと疎通可能でなければなりません。ADサーバーとの通信には、以下のポートを使用しますので、ADサーバーへのインバウンド方向に対してFW等の疎通許可設定が必要です。

  • TCP/UDP 53 (DNS)
  • TCP/UDP 88 (Kerberos認証)
  • TCP/UDP 389 (LDAP)

今回はAD Connectorと同一のVPC上にADサーバーを立てるため、特に考慮は不要です。

また今回はAWS上にWindowsサーバーを用意し、Active Directoryのインストールは完了した状態から始めます。

  • OS: WIndows Server 2019
  • インスタンスサイズ: t3.xlarge
  • その他: 日本語化は完了済み

Active Directoryの設定

まずはActive Directoryの設定変更を行います。AD ConnectorがADに接続するには、必要な権限を持った サービスアカウント というユーザーが必要になります。ADサーバー内で初めから存在するDomain Admins というグループに作成したユーザーでも可能ですが、ここは必要最小限の権限を持つ新しいグループを作成することが推奨されます。

ここではドキュメントに従い Connectors というグループを作成、その中に必要なユーザーを作成します。

まずはグループ作成のため、 Active Directory ユーザーとコンピューター を開き、 新規作成 からグループを選択します。

ここでは以下のような設定でグループを作成します。

  • グループ名: Connectors
  • グループのスコープ: グローバル
  • グループの種類: セキュリティ

次にグループの権限を変更するため、 操作制御の委任 を選択します。

「次へ」の選択を進め、 ユーザーまたはグループ の項目で、作成した Connectors を追加します。

委任するタスク の項目で 委任するカスタムタスクを作成する を選択します。

Active Directoryオブジェクトの種類 で以下を選択します。

  • フォルダー内の次のオブジェクトのみ:
    • コンピューターオブジェクト
    • ユーザーオブジェクト
  • 選択されたオブジェクトをこのフォルダーに作成する
  • 選択されたオブジェクトをこのフォルダーから削除する

アクセス許可 で以下を選択します。 * 全般 * プロパティ固有 * アクセス許可: * 読み取り

グループの作成を完了します。

続いてユーザーの作成を行います。この時 を入力しないとAmazon Connect上での登録時にエラーが発生するため、必ず入力してください。

作成したユーザーは Connectors グループに所属させます。

なお今回はサービスアカウント用の test01 と、Amazon Connectでの登録用に test02 を作成しています。

AD Connectorの作成

次にAD Connectorの作成です。AD Connectorの作成はAWSマネジメントコンソールから行います。

Directory Serviceの画面に移動し、 ディレクトリのセットアップ を選択します

作成画面に移動します。ディレクトリタイプは AD Connector を選択します

ディレクトリのサイズは、今回は検証のため スモール を選択します。

VPCとサブネットを選択します。今回はADサーバーを作成したのと同じVPCを選択します。またサブネットは個別に選択しない場合、自動的に選択されます。

ADとの接続に使う情報を入力します。今回 DNS IPアドレス はADサーバーのプライベートアドレスを、 サービスアカウントのユーザー名test01 を指定します。

確認して作成ボタンを選択し、完了するまでしばらく待ちます。

Amazon Connectの作成

次にAmazon Connectの作成を行います。Amazon Connectは現時点ではインスタンス作成後の認証方式の変更は対応していないため、新規にインスタンスを作成します。

AWSマネジメントコンソールからAmazon Connectのメニュー画面に移動し、インスタンスの追加を選択します。

作成画面に遷移するとID管理を選択するので、ここで 既存のディレクトリへのリンク を選択し、先ほど作成したAD Connectorと紐づくディレクトリを選択します。またアクセスURLもここで指定します。

以降の設定は特に変更せずとも進むため、ここでは割愛します。

Amazon Connectでユーザーの追加

さいごにAmazon Connectでユーザーを追加します。

インスタンス作成が完了したら、マネジメントコンソールからインスタンスを選択し、 Emergency access からインスタンスにログインします。

ログインしたらユーザー管理の画面に移動します。

この時点ではユーザーは登録されていません。ユーザーの追加を選択します。

ユーザーの追加画面に移動すると、ADに追加した test01 test02 ユーザーが確認できるはずです。

まずは test01 を追加するため、 test01 にチェックボックスを選択し、 Security Profile / Routing Profileを指定します。その後 Save を選択します。

特にエラーも発生しなければ、以下のように test01 が追加されたのを確認できるはずです。なお、同様の手順で test02 も追加できます。

最後に、追加したユーザーでログインできるか確認します。一度ログアウトした後に test01 とパスワードを入力し、サインインを選択します。

ログインに成功し、画面右上に test01 と書かれていれば完了です。

さいごに

弊社はAWSアドバンスドティアサービスパートナー認定を受けております。また以下のようにAWSの活用を支援するサービスも行っているので、何かご相談したいことがあればお気軽にご連絡ください。

www.ap-com.co.jp

AWS Control Tower の Account Factory で作成した AWS アカウントに Microsoft Entra ID (旧 Azure AD) ユーザーでシングルサインオンする!(ユーザー同期編②)

はじめに

こんにちは。クラウド事業部の早房です。
本記事では、Microsoft Entra ID 上のユーザーを IAM Identity Center ユーザーとして AWS 環境に同期するための方法をご紹介します。

IAM Identity Center ユーザーとは?

【AWS】【初心者】IAM Identity Center とは?IAM Identity Center ユーザーって何者? - APC 技術ブログ

なお、ユーザー同期編はボリュームがあるので本記事も含め 3 つの記事に分けて投稿予定です(本記事は2つ目)

※前回記事は以下

techblog.ap-com.co.jp

1. 目次

  1. 目次
  2. 全体の作業フローと本記事での作業箇所の確認
  3. 前提条件
  4. 作業完了条件
  5. 作業手順
  6. 参考情報

2. 全体の作業フローと本記事での作業箇所の確認

①AWS Control Tower のランディングゾーンセットアップ
②Microsoft Entra ID → AWS へのユーザー同期
③Account Factory での AWS アカウント作成
④作成したAWSアカウントへのアクセス権の設定
といったフローで作業を進めていきます。

本投稿の作業範囲は「Microsoft Entra ID → AWS へのユーザー同期 」です。

3. 前提条件

AWS Control Tower の Account Factory で作成した AWS アカウントに Microsoft Entra ID (旧 Azure AD) ユーザーでシングルサインオンしてみた。(ユーザー同期編①) に記載の手順を実施済みであること。

4. 作業完了条件

AWS IAM Ideneity Center 上でSCIM エンドポイントおよびアクセストークンの取得ができること

5. 作業手順

5-1. アイデンティティソースの変更 (AWS)

  1. AWS IAM Identity Center のコンソール画面から設定を選択します。

  2. アイデンティティソースタブ内の「アクション」から「アイデンティティソースを変更」をクリックします。

  3. 「外部 ID プロバイダー」を選択し、「次へ」をクリックします。

  4. アイデンティティプロバイダーのメタデータ内の「ファイルを選択」から Azure Portal 上でダウンロードしたフェデレーション メタデータ XML を選択し、「次へ」をクリックします。

  5. アイデンティティソースが外部 ID プロバイダー、サービスプロバイダーのメタデータがただし選択されていることを確認し、「承諾」を入力し、「アイデンティティソースを変更」をクリックします。

  6. アイデンティティソースが正常に変更されたことを確認します。

  7. 左ペインより「設定」を開き、自動プロビジョニングを有効にします。

  8. 自動プロビジョニングが有効になったことを確認し、「トークンを表示」をクリックします。

  9. SCIM エンドポイントおよび表示されたアクセストークンを控えておきます。

  10. サインアウト等はせず、続いて「IAM Identity Center - Microsoft Entra ID - IAM Identity Centerユーザー同期_3」を実施します。

6. 参考情報

まとめ

これで AWS IAM Identity Center 上からSCIM エンドポイントおよびアクセストークンの取得ができました。
少々短いですがキリが良いので今回はここまで。次回は取得した情報を Azure 側に投入して、実際にユーザー同期を実施します。

おわりに

弊社はAWSアドバンスドティアサービスパートナー認定を受けております。
また以下のようにAWSの活用を支援するサービスも行っているので、何かご相談したいことがあればお気軽にご連絡ください。

www.ap-com.co.jp

また、一緒に働いていただける仲間も募集中です!
今年もまだまだ組織規模拡大中なので、ご興味持っていただけましたらぜひお声がけください。

www.ap-com.co.jp

本記事の投稿者: hybs_yuuuu

https://www.credly.com/users/hybs_yuuuu/badges

Amazon Q in Connect機能でAmazon ConnectとAmazon Qを連携する

こんにちは、エーピーコミュニケーションズ クラウド事業部の山路です。

今回はAWS re:Invent 2023で公開されたAmazon ConnectとAmazon Qの連携を試してみます。

aws.amazon.com

背景

Amazon QはAWSの生成系AIアシスタントとして発表されたものです。弊社ブログでも以前取り上げたことがあります。

techblog.ap-com.co.jp

Amazon Qは複数のAWSサービスと連携もしており、その一つがAmazon Connectです。Amazon Q in Connectという名称のサービスは、もともとAmazon Connect Wisdomという機械学習を利用したサービスをアップデートしたものであり、顧客との通話やチャットの内容から、エージェントに対して推奨の回答などを提案することができます。

Amazon Q in Connectの特徴は大きく3つあります。

  • リアルタイムでレコメンデーションを提供: 顧客との通話内容を分析し、リアルタイムでレスポンスとアクションを提案します。また関連文書へのリンクも提供します。
  • エージェントからの質問に対応: Amazon ConnectのエージェントはWorkspaceのチャット欄からAmazon Qに質問することができます。
  • 複数のデータ元に対応: Amazon QはAmazon S3のほか、Salesforce / Zendesk / ServiceNow / Microsoft Sharepoint Onlineをデータ元として指定できます。

なお、Amazon Q in COnnectは3月1日まで無料で利用できます。また現在Amazon Qはプレビュー版であり、英語のみ対応しています。

検証

ここからAmazon Q in Connectの検証です。

docs.aws.amazon.com

Amazon Qが参照するデータの用意

まずはAmazon Qが利用するデータを用意します。今回は弊社ホームページ (英語) のhtmlファイルをいくつか用意し、Amazon S3に配置しました。

Amazon QとAmazon Connectの統合

次にAmazon ConnectとAmazon Qとの統合を有効にします。ここではAmazon Connectは作成済みであることを想定しています。なお、Amazon Q in Connectを利用するには、Amazon Connect Contact Lensを有効にする必要があります。

まず作業対象のAmazon Connectインスタンスの左メニューから Amazon Q を選択し、遷移後のページにある ドメインを追加 ボタンを選択します。

次にドメインの追加を行います。ここではドメイン名を適当に設定し、新しいドメインを作成します。

ドメインを作成したら、次に統合の追加を行います。

統合を追加 のページに遷移すると、まずはデータソースを指定します。ここで先ほど作成したAmazon S3バケットを指定します。

また統合の追加をする際、リソースの暗号化 (と復号) のためにAWS KMSキーが必要となります。事前に作成することも可能ですが、ここでは AWS KMSキーを作成 ボタンを選択して新規作成を行います。

AWS KMSキーを作成する時は以下のように指定します。

  • キーのタイプ: 対称
  • キーの使用法: 暗号化および復号化

今回はチャットからAmazon Qに質問するのも試すため、以下の用にポリシーを修正します。

{
   "Version": "2012-10-17",
   "Id": "key-consolepolicy-3",
   "Statement": [
       {
           "Sid": "Enable IAM User Permissions",
           "Effect": "Allow",
           "Principal": {
               "AWS": "arn:aws:iam::<AWS Account ID>:root"
           },
           "Action": "kms:*",
           "Resource": "*"
       },
       {
           "Effect": "Allow",
           "Principal": {
               "Service": "connect.amazonaws.com"
           },
           "Action": [
               "kms:Decrypt",
               "kms:GenerateDataKey*",
               "kms:DescribeKey"
           ],
           "Resource": "*"
       }
   ]
}

AWS KMSキーを作成後はAmazon Qの統合追加画面に戻ってKMSキーを追加します。

最後に設定を確認して統合を追加します。

動作確認

ここからAmazon Q in Connectの機能を試します。なお今回はAmazon Connectインスタンス作成時に追加されるユーザーをエージェントとして使用しますが、Amazon Qの機能を利用するにはSecurity Profileの エージェントアプリケーション にAmazon Qへのアクセス権限が必要です。

docs.aws.amazon.com

Amazon ConnectにログインしてエージェントWorkspaceを開くと、右側にAmazon Qのメニューが表示されます。

まずはチャット機能から。 Search Amazon Q に質問内容を入力してEnterを押すと、Amazon Qに質問が送信され、しばらくすると回答が返ってきます。例えば会社の住所を聞いてみると、こんな感じです。

The address of AP Communications Co., Ltd. is [Main Office] Kanda Tokuriki Bldg., 3F. 2-chme-9-12 Kajich. Chiyoda City, Tky, 101-0044. Phone: 03-5297-8011 / Fax: 03-5297-8253.

もう少し抽象的な質問もしてみます。主要なサービスは何ですか?と聞いてみると、こんな感じに返ってきました。

The main services offered by AP Communications, Inc. include Network Automation, System integration service for Microsoft Azure, Cloud migration service for Microsoft Azure, and VDI/DaaS solution.

またAmazon Qからの回答にはリファレンスも表示されており、クリックすると該当のページが表示されます。

次に会話中のリアルタイム分析とレコメンデーション機能を使います。この機能を使うには、あらかじめ以下のブロックを含むフローを設定する必要があります。

  • Amazon Q Connect: 作成したAmazon QのドメインARNを指定
  • 記録と分析動作を設定:
    • 分析: 音声分析を有効にする (リアルタイム及び通話後の分析)

※参考:

今回使用したフローは以下のようなものです。

頑張って英語で会社の住所を聞いてみると、それっぽいものを検出し、Amazon Qが回答を表示している様子を確認できました。

さいごに

今回はAmazon Q in Connectの紹介でした。まだ日本語には対応していないですが、将来的には使われる可能性も十分あるのかな、と感じました。ただ、実際にこれを利用するエージェントから見ると、複数のインターフェイスから情報を集めることができるので、慣れないと混乱しそうな気もしました。トレーニングも含めてどう導入を進めるか考えるのも重要かもしれません。

最後に、弊社はAWSアドバンスドティアサービスパートナー認定を受けております。また以下のようにAWSの活用を支援するサービスも行っているので、何かご相談したいことがあればお気軽にご連絡ください。

www.ap-com.co.jp

Docker on CloudShell

はじめに

こんにちは、クラウド事業部の梅本です。 遅ればせながら、CloudShell で Docker が動くようになったとのこと。

aws.amazon.com

実際に CloudShell を起動して色々試していきたいと思います。

CloudShell で Docker

早速 CloudShell を起動して動作を確認してみます。

※実行は 2024/02/09 時点

# バージョンは 24.0.5
$ docker version
Client:
 Version:           24.0.5
 API version:       1.43
 Go version:        go1.20.10
 Git commit:        ced0996
 Built:             Tue Nov 14 00:00:00 2023
 OS/Arch:           linux/amd64
 Context:           default

Server:
 Engine:
  Version:          24.0.5
  API version:      1.43 (minimum version 1.12)
  Go version:       go1.20.10
  Git commit:       a61e2b4
  Built:            Tue Nov 14 00:00:00 2023
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.7.11
  GitCommit:        64b8a811b07ba6288238eefc14d898ee0b5b99ba
 runc:
  Version:          1.1.11
  GitCommit:        4bccb38cc9cf198d52bebf2b3a90cd14e7af8c06
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

# docker プロセスの確認(root で稼働)
# node コマンドで実行しているコードの中で、dockerd を子プロセスとして実行している模様
# 以下の結果は docker 関連のみ表示
$ ps aux --forest
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
cloudsh+       1  0.2  1.1 619636 43272 ?        Ssl  16:06   0:00 node /var/lib/amazon/cloudshell/on-container-launch.js
cloudsh+      16  0.0  0.0   4228  2972 ?        Ss   16:06   0:00 /bin/sh -c sudo dockerd | sudo tee /var/log/docker-daemon.log
root          18  0.0  0.1  14588  7444 ?        S    16:06   0:00  \_ sudo dockerd
root          26  0.1  1.8 1537604 73796 ?       Sl   16:06   0:00  |   \_ dockerd
root          51  0.3  1.1 1288804 45540 ?       Ssl  16:06   0:00  |       \_ containerd --config /var/run/docker/containerd/containerd.toml
root          19  0.0  0.1  14588  7412 ?        S    16:06   0:00  \_ sudo tee /var/log/docker-daemon.log
root          24  0.0  0.0   4928  1348 ?        S    16:06   0:00      \_ /usr/bin/coreutils --coreutils-prog-shebang=tee /usr/bin/tee /var/log/docker-daemon.log

# docker グループにも参加
$ id
uid=1000(cloudshell-user) gid=996(cloudshell-user) groups=996(cloudshell-user),997(docker)

# 起動したばかりなので、コンテナもイメージも無し
$ docker ps -a
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

$ docker images
REPOSITORY   TAG       IMAGE ID   CREATED   SIZE

環境は一通り確認できたので、python のコンテナイメージに ansible をインストールして実行してみます。 以下、Dockerfile です。

FROM python:3.12.1-slim
RUN pip install --no-cache-dir ansible-core

早速ビルドして実行してみます。

# Build
$ docker build -t myansible:0.1 .
[+] Building 23.9s (6/6) FINISHED                                                                                                                                        docker:default
 => [internal] load .dockerignore                                                                                                                                                  0.0s
 => => transferring context: 2B                                                                                                                                                    0.0s
 => [internal] load build definition from Dockerfile                                                                                                                               0.0s
 => => transferring dockerfile: 160B                                                                                                                                               0.0s
 => [internal] load metadata for docker.io/library/python:3.12.1-slim                                                                                                              2.4s
 => [1/2] FROM docker.io/library/python:3.12.1-slim@sha256:a64ac5be6928c6a94f00b16e09cdf3ba3edd44452d10ffa4516a58004873573e                                                        9.9s
...
 => [2/2] RUN pip install --no-cache-dir ansible-core                                                                                                                             10.5s
 => exporting to image                                                                                                                                                             1.1s 
 => => exporting layers                                                                                                                                                            1.1s 
 => => writing image sha256:d15c060d7d0bb8b3cd914906714050795bc6282c590f7e2a55b4da80104883fa                                                                                       0.0s 
 => => naming to docker.io/library/myansible:0.1                                                                                                                                   0.0s 

$ docker images                                                                                                                                      
REPOSITORY   TAG       IMAGE ID       CREATED         SIZE                                                                                                                              
myansible    0.1       d15c060d7d0b   5 minutes ago   177MB


# Run
$ docker run --rm myansible:0.1 ansible --version
ansible [core 2.16.3]
  config file = None
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python3.12/site-packages/ansible
  ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/local/bin/ansible
  python version = 3.12.1 (main, Feb  1 2024, 04:33:21) [GCC 12.2.0] (/usr/local/bin/python)
  jinja version = 3.1.3
  libyaml = True

# ansible コマンドは実行しても失敗することを確認
$ docker run --rm myansible:0.1 ansible -i "127.0.0.1," all -m ping
127.0.0.1 | FAILED! => {
    "msg": "Unable to execute ssh command line on a controller due to: [Errno 2] No such file or directory: b'ssh'"
}

build/run もスムーズにできました。今回 push は行いませんが、ECR への push スムーズにできそうです。

コンテナへのアクセスも確認してみます。 nginx のコンテナを起動してアクセスしてみます。

$ docker run -d -p 8080:80 nginx:1.25.3

$ docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED         STATUS         PORTS                                   NAMES
ea654a87ba09   nginx:1.25.3   "/docker-entrypoint._"   7 seconds ago   Up 3 seconds   0.0.0.0:8080->80/tcp, :::8080->80/tcp   lucid_bhaskara

$ curl -I localhost:8080
HTTP/1.1 200 OK
Server: nginx/1.25.3
Date: Thu, 08 Feb 2024 16:41:55 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Tue, 24 Oct 2023 13:46:47 GMT
Connection: keep-alive
ETag: "6537cac7-267"
Accept-Ranges: bytes

無事にポート指定してアクセスできました。

最後に気になるディスク関連を確認します。

# 永続化されるホームディレクトリは 1GB
$ df -hT ~
Filesystem     Type  Size  Used Avail Use% Mounted on
/dev/loop0     ext4  974M  7.9M  899M   1% /home/cloudshell-user

# docker のディレクトリはホームディレクトリとは異なりエフェメラルな領域
# / ディレクトリと一緒
$ df -hT /
Filesystem     Type     Size  Used Avail Use% Mounted on
overlay        overlay   16G  5.6G  9.2G  38% /

$ df -hT /var/lib/docker
Filesystem     Type     Size  Used Avail Use% Mounted on
overlay        overlay   16G  5.6G  9.2G  38% /

# docker pull して ディスクの使用量を確認
# 確認のため大きいサイズのイメージを pull
$ docker pull python:3.9.18-bullseye

$ df -hT ~
Filesystem     Type  Size  Used Avail Use% Mounted on
/dev/loop0     ext4  974M  7.9M  899M   1% /home/cloudshell-user

$ df -hT /var/lib/docker
Filesystem     Type     Size  Used Avail Use% Mounted on
overlay        overlay   16G   11G  4.3G  72% /

/var/lib/docker がエフェメラルの領域にあるため、CloudShell への再アクセスや再起動の際にコンテナイメージや起動中のコンテナは削除されてしまうので注意しましょう。 必要以上にディスクを使用しているようにも見えますが・・・謎です。

CloudShell のスペックも高いわけではないので、利用の際は考慮しましょう。

仕様やトラブルシューティングの参考リンクを貼っておきます。

docs.aws.amazon.com

docs.aws.amazon.com

まとめ

CloudShell で docker が実行できるようになり、コンテナをよく触っている身としては非常にありがたいです。記事作成時の環境を CloudShell にすることで、「記事の内容をすぐに試したい!」ってことも楽になりますね。コンテナを使って各種ツールを起動できることから、利用用途は増えそうなので今後も利用していきたいと思います!


APCはAWSアドバンスドティアサービスパートナー認定を受けております。

AWSアドバンスドティアサービスパートナー

その中で私達クラウド事業部はAWSなどのクラウド技術を活用したSI/SESのご支援をしております。

www.ap-com.co.jp

また、AWSの運用自動化ツールも展開しております。

www.ap-com.co.jp

本記事の投稿者: 梅本
コンテナや k8s をメインにインフラ系のご支援を担当しています。
AWS は現在学び直し中! 普段は QiitaZenn に k8s を中心とした記事を投稿しております。よろしければ。

【アップデート】Amazon Connectでスキル習熟度によるルーティングを実現

こんにちは、エーピーコミュニケーションズ クラウド事業部の山路です。

今回は昨年12月にアップデートされたAmazon ConnectのAgent Proficiencyの紹介です。

aws.amazon.com

背景

Amazon Connectのアップデートにより、エージェント毎にスキルの習熟度を設定し、その値に基づくルーティングを実現できるようになりました。

これにより、例えば特定の要件に対する問い合わせ対応を、スキルレベルの高いエージェントに優先して回すことができます。またルーティング設定には時間指定も出来るため、該当のエージェント以外にも段階的に着信を飛ばすことが可能です。

これまでエージェントごとに異なるルーティングを実現したい場合、Queue単位でルーティングを分けるといった方法がとられていたかと思いますが、エージェントレベルの細かい単位での振り分けも可能になった、という認識です。

検証

ユーザーへの権限付与

まずは既存のAgent proficiencyの設定を確認します。

Agent proficiencyを画面上で確認するには、ユーザーに対する権限付与が必要です。なお本機能アップデート後にインスタンスを作成した場合、初期ユーザーには初めから権限が付与されています。

docs.aws.amazon.com

ここでは test-user に対して、画面上で権限付与を行いました。

Predefined variablesの設定

Agent proficiencyでは Predefined variables (事前定義された属性) という設定を利用します。デフォルトでは connect:Language connect:Subtype という属性が設定されていますが、ここでは新規に作成します。

Agent proficiecnyは、ユーザーごとに設定したPredefined variablesの項目をもとに、ルーティングを制御します。そのため、Predefined variablesを作成後、ユーザーごとにその値とレベルを設定します。

今回は以下のCloudFormationファイルを使用して各リソースを作成しました。こちらにはPredefined variablesのほか、検証で使うユーザーなども定義しています。

agent-proficiency.yaml

AWSTemplateFormatVersion: "2010-09-09"
Description: Amazon Connect Agent proficiency test
Parameters:
  PJPrefix:
    Type: String
    Default: "connect-test-20240201"
  HoursOfOperationId:
    Type: String
  InstanceId:
    Type: String
  Password:
    Type: String

Resources:
  Queue01:
    Type: AWS::Connect::Queue
    Properties:
      HoursOfOperationArn: !Sub "arn:aws:connect:${AWS::Region}:${AWS::AccountId}:instance/${InstanceId}/operating-hours/${HoursOfOperationId}"
      InstanceArn: !Sub "arn:aws:connect:${AWS::Region}:${AWS::AccountId}:instance/${InstanceId}"
      Name: !Sub ${PJPrefix}-queue01
  RoutingProfile01:
    Type: AWS::Connect::RoutingProfile
    Properties:
      DefaultOutboundQueueArn: !GetAtt Queue01.QueueArn 
      Description: "routing profile for flow01"
      InstanceArn: !Sub "arn:aws:connect:${AWS::Region}:${AWS::AccountId}:instance/${InstanceId}"
      MediaConcurrencies: 
        - Channel: CHAT
          Concurrency: 1
        - Channel: TASK
          Concurrency: 1
        - Channel: VOICE
          Concurrency: 1
      QueueConfigs:
        - Delay: 0
          Priority: 1
          QueueReference: 
            Channel: VOICE
            QueueArn: !GetAtt Queue01.QueueArn 
      Name: !Sub "${PJPrefix}-routing-profile01"
  SecurityProfile:
    Type: AWS::Connect::SecurityProfile
    Properties:
      InstanceArn: !Sub "arn:aws:connect:${AWS::Region}:${AWS::AccountId}:instance/${InstanceId}"
      SecurityProfileName: !Sub "${PJPrefix}-security-profile-for-agent"
      Permissions:
        - BasicAgentAccess
        - OutboundCallAccess
  User01:
    Type: AWS::Connect::User
    Properties:
      IdentityInfo:
        FirstName: 'newcomer'
        LastName: 'newcomer'
        Email: 'example@email.com'
      InstanceArn: !Sub "arn:aws:connect:${AWS::Region}:${AWS::AccountId}:instance/${InstanceId}"
      Password: !Ref Password
      PhoneConfig:
        PhoneType: SOFT_PHONE
      RoutingProfileArn: !GetAtt RoutingProfile01.RoutingProfileArn
      SecurityProfileArns: 
        - !GetAtt SecurityProfile.SecurityProfileArn
      Username: "user-newcomer"
      UserProficiencies: 
        - AttributeName: "Skill"
          AttributeValue: "customer support"
          Level: 1
        - AttributeName: "Skill"
          AttributeValue: "technical support"
          Level: 1
  User02:
    Type: AWS::Connect::User
    Properties:
      IdentityInfo:
        FirstName: 'veteran'
        LastName: 'veteran'
        Email: 'example@email.com'
      InstanceArn: !Sub "arn:aws:connect:${AWS::Region}:${AWS::AccountId}:instance/${InstanceId}"
      Password: !Ref Password
      PhoneConfig:
        PhoneType: SOFT_PHONE
      RoutingProfileArn: !GetAtt RoutingProfile01.RoutingProfileArn
      SecurityProfileArns: 
        - !GetAtt SecurityProfile.SecurityProfileArn
      Username: "user-veteran"
      UserProficiencies: 
        - AttributeName: "Skill"
          AttributeValue: "customer support"
          Level: 5
        - AttributeName: "Skill"
          AttributeValue: "technical support"
          Level: 5
  PredefinedAttributes:
    Type: AWS::Connect::PredefinedAttribute
    Properties:
      InstanceArn: !Sub "arn:aws:connect:${AWS::Region}:${AWS::AccountId}:instance/${InstanceId}"
      Name: "Skill"
      Values: 
        StringList: 
          - "customer support"
          - "technical support"

docs.aws.amazon.com

フローの作成

続いてフローの作成です。ここでは以下のようなシナリオに基づいたテスト用フローを作成しました。

  • 同じQueueの中には、スキルレベルの異なる2人のエージェント (スキルレベルの高い user-veteran 、スキルレベルの低い user-newcomer) が属する。
  • 最初にスキルレベルの高いエージェントに優先してルーティングをし、出られない場合はスキルレベルの低いエージェントも対応可能にする。

フローの全体図は以下の通りです。

このうちAgent proficiencyは ルーティング条件の設定 (Set routing criteria) というブロックを利用します。このブロックはPredefined variablesのキーと値、条件に合致するレベルを設定します。またこのルーティングの有効期限も設定できます。

ここでは、CloudFormationで作成した Skill というPredefined variablesに含まれる customer support technical support という2つの値について、それぞれレベル3以上のエージェントに優先してルーティングするよう設定しました。

docs.aws.amazon.com

なお、今回のフローをContact flow languageで表現したものは以下になります。

Contact Flow

{
  "Version": "2019-10-30",
  "StartAction": "voice",
  "Metadata": {
    "entryPointPosition": {
      "x": 40,
      "y": 40
    },
    "ActionMetadata": {
      "voice": {
        "position": {
          "x": 141.6,
          "y": 41.6
        },
        "isFriendlyName": true,
        "overrideConsoleVoice": true
      },
      "workqueue": {
        "position": {
          "x": 140,
          "y": 253.6
        },
        "isFriendlyName": true,
        "parameters": {
          "QueueId": {
            "displayName": "connect-test-20240201-queue01"
          }
        },
        "queue": {
          "text": "connect-test-20240201-queue01"
        }
      },
      "queue": {
        "position": {
          "x": 670.4,
          "y": 36
        },
        "isFriendlyName": true
      },
      "routing-condition": {
        "position": {
          "x": 392,
          "y": 36.8
        },
        "isFriendlyName": true,
        "parameters": {
          "RoutingCriteria": {
            "Steps": [
              {
                "Expiry": {
                  "DurationInSeconds": {
                    "unit": 1
                  }
                }
              }
            ]
          }
        }
      },
      "prompt": {
        "position": {
          "x": 392.8,
          "y": 255.2
        },
        "isFriendlyName": true
      },
      "disconnect": {
        "position": {
          "x": 710.4,
          "y": 327.2
        },
        "isFriendlyName": true
      }
    },
    "Annotations": []
  },
  "Actions": [
    {
      "Parameters": {
        "TextToSpeechEngine": "Neural",
        "TextToSpeechStyle": "None",
        "TextToSpeechVoice": "Kazuha"
      },
      "Identifier": "voice",
      "Type": "UpdateContactTextToSpeechVoice",
      "Transitions": {
        "NextAction": "workqueue"
      }
    },
    {
      "Parameters": {
        "QueueId": "arn:aws:connect:ap-northeast-1:<AWS Account>:instance/<Instance ID>/queue/<Queue ID>"
      },
      "Identifier": "workqueue",
      "Type": "UpdateContactTargetQueue",
      "Transitions": {
        "NextAction": "routing-condition",
        "Errors": [
          {
            "NextAction": "disconnect",
            "ErrorType": "NoMatchingError"
          }
        ]
      }
    },
    {
      "Parameters": {},
      "Identifier": "queue",
      "Type": "TransferContactToQueue",
      "Transitions": {
        "NextAction": "disconnect",
        "Errors": [
          {
            "NextAction": "disconnect",
            "ErrorType": "QueueAtCapacity"
          },
          {
            "NextAction": "disconnect",
            "ErrorType": "NoMatchingError"
          }
        ]
      }
    },
    {
      "Parameters": {
        "RoutingCriteria": {
          "Steps": [
            {
              "Expression": {
                "AndExpression": [
                  {
                    "AttributeCondition": {
                      "Name": "Skill",
                      "Value": "customer support",
                      "ProficiencyLevel": 3,
                      "ComparisonOperator": "NumberGreaterOrEqualTo"
                    }
                  },
                  {
                    "AttributeCondition": {
                      "Name": "Skill",
                      "Value": "technical support",
                      "ProficiencyLevel": 3,
                      "ComparisonOperator": "NumberGreaterOrEqualTo"
                    }
                  }
                ]
              },
              "Expiry": {
                "DurationInSeconds": 10
              }
            }
          ]
        }
      },
      "Identifier": "routing-condition",
      "Type": "UpdateContactRoutingCriteria",
      "Transitions": {
        "NextAction": "prompt",
        "Errors": [
          {
            "NextAction": "disconnect",
            "ErrorType": "NoMatchingError"
          }
        ]
      }
    },
    {
      "Parameters": {
        "Text": "こちらはagent proficiencyのテスト用フローです。"
      },
      "Identifier": "prompt",
      "Type": "MessageParticipant",
      "Transitions": {
        "NextAction": "queue",
        "Errors": [
          {
            "NextAction": "disconnect",
            "ErrorType": "NoMatchingError"
          }
        ]
      }
    },
    {
      "Parameters": {},
      "Identifier": "disconnect",
      "Type": "DisconnectParticipant",
      "Transitions": {}
    }
  ]
}

動作確認

ここで動作確認をします。

まずは2人のエージェントがどちらも Available の場合です。

インスタンス宛に電話をすると、まずはスキルレベルの高い veteran が着信を受け取ります。

エージェントはデフォルトで20秒以内に応答しないと別のエージェントに着信が飛びます。ここでは約20秒経つと newcomer に切り替わりました。

次に veteran がOfflineの場合です。

ここではルーティング設定の通り、10秒ほど経過してから newcomer に着信する様子を確認しました。

さいごに

Agent proficiencyにより、これまで実装が難しかったルーティングも設定できるようになったのではないかと思います。今回はスキルレベルの高い人を優先しましたが、例えば新人エージェントを識別するようなPredefined variableを設定すれば、新人教育のため優先して着信を飛ばすことも出来そうです。

最後に、弊社はAWSアドバンスドティアサービスパートナー認定を受けております。また以下のようにAWSの活用を支援するサービスも行っているので、何かご相談したいことがあればお気軽にご連絡ください。

www.ap-com.co.jp

BLEAとは?AWSのセキュリティベースラインを自動で構築

はじめに

こんにちは、エーピーコミュニケーションズ クラウド事業部の髙野です。
最近業務でCDKを使うことがあり、CDKを触っていく中でBaseline Environment on AWS(BLEA)の存在を知りました。

このBLEAがAWSのシステムにおけるセキュリティのベースラインを素早く構築できる点で非常に便利だと思ったので紹介したいと思います。

目次

  • CDKとは
  • BLEAとは
  • BLEAのいいところ
  • さいごに

CDKとは

BLEAの話に入る前にCDKについて軽く説明をしておきます。

CDKはコードでクラウドインフラストラクチャを定義しプロビジョニングするためのフレームワークで、いわゆるIaCと呼ばれるものを実現するためのやつです。

そしてBLEAもこのCDKを使用して実装されています。

BLEAとは

BLEAはAWSが開発しているOSSで、AWSのセキュリティのベストプラクティスを実装した環境を迅速に構築するためのテンプレート群です。GitHubで公開されています。

BLEAの公開GitHubは以下になります。

github.com

前述のとおりテンプレートはCDKで実装されており、システムの利用用途に合わせたカスタマイズを少ないコード量で容易に行えるようにデザインされています。

数回のコマンドで以下のようなアーキテクチャを構築できます。

Standalone版 引用:AWS 環境にセキュアなベースラインを提供するテンプレート「Baseline Environment on AWS」のご紹介 | Amazon Web Services ブログ

BLEAのいいところ

基本的なセキュリティを効率的に実装できる

AWSは AWS Well-ArchitectedAWS Security Reference Architecture (AWS SRA) といったセキュリティのベストプラクティスをドキュメントとして提供しています。しかしこれらを見て0から設計をおこない、手動で構築していくのはなかなか骨が折れますし、作業ミスも起こりやすいです。

BLEAのテンプレートを使用して自動構築することで、基本的なセキュリティを確保できます。下記がBLEAを使用したときにセットアップされる機能です。

  • CloudTrailによるAPIのロギング
  • AWS Configによる構成変更の記録
  • GuardDutyによる異常なふるまいの検知
  • SecurityHubによるベストプラクティスからの逸脱検知 (AWS Foundational Security Best Practice, CIS benchmark)
  • デフォルトセキュリティグループの閉塞(逸脱した場合自動修復)
  • AWS Healthイベントの通知
  • セキュリティに影響する変更操作の通知(一部)
  • セキュリティイベントを通知するSNSトピック (SecurityAlarmTopic) の作成
  • 上記SNSトピックを経由した、メールの送信とSlackのセキュリティチャネルへの通知

マルチアカウント環境にも対応

AWSのベストプラクティスのひとつにマルチアカウントという考え方がありますが、いざ自社のAWS環境をマルチアカウント化させようとすると、設計が複雑でなかなか取り掛かりにくいという状況もあるかと思います。

しかしBLEAではAWS Control Towerを利用したテンプレートも提供されており、マルチアカウント環境に対しても以下のようなアーキテクチャでセキュアなベースラインを確立できます。

マルチアカウント版 引用:AWS 環境にセキュアなベースラインを提供するテンプレート「Baseline Environment on AWS」のご紹介 | Amazon Web Services ブログ

READMEがわかりやすい

本記事の冒頭でも記載しましたが、BLEAのテンプレートはGitHub で公開されており、環境へのデプロイ手順や各テンプレートの詳細な説明などもGitHubのREADMEにまとまっております。

そしてこのREADMEは日本語版も用意されており、個人的にはかなり読みやすく、CDKをほとんど触ったことのないときの私でも内容を理解することができました。

AWS公式ブログでもBLEAをCDKを使い始めるための学習用リソースとして紹介しているので、これからCDKを勉強してみようと思っている方も一読してみるといいかもしれません。

さいごに

AWSのセキュリティを0から設計するのはかなりの重労働なので、「いつかやろう」「落ち着いたらやろう」で後回しにしてしまっている方もいるのではないでしょうか。

BLEAを採用することでその負担は一定軽くなるかと思います。CDKを使用しているということで、多少の学習コストはかかりますが検討する価値はあると思います。

より詳細にBLEAを知りたい方は以下のAWSブログを参照してください。

aws.amazon.com

お知らせ

弊社はAWSアドバンスドティアサービスパートナー認定を受けております。また以下のようにAWSの活用を支援するサービスも行っているので、何かご相談したいことがあればお気軽にご連絡ください。

www.ap-com.co.jp

また、一緒に働いていただける仲間も募集中です!
今年もまだまだ組織規模拡大中なので、ご興味持っていただけましたらぜひお声がけください。

www.ap-com.co.jp

本記事の投稿者: sk07103
AWSをメインにインフラ系のご支援を担当しています。

【さらば、コンソール作業、、】~AWS運用自動化ツール:IAMユーザ削除編~

はじめに

こんにちは、クラウド事業部の清水(雄)です。

昨年サービス開発したAWS運用自動化ツール(Chatops)の基本設計と実装手順を記載させて頂きます。
今回はSlackでコマンド叩けば「IAMユーザ削除」が可能なツールが対象です。
手順に記載している各種テンプレートやソースは以下アンケートにお答え頂けるとダウンロードできる仕様となります。
よろしかったらお試しください。

www.ap-com.co.jp

目次

基本設計

IAMユーザ削除ツール

本ツールの概要

本ツールは、IAMユーザの削除を、AWSマネジメントコンソースにアクセスせず実現するツールです。 本ツールはSlackから特定のコマンドを実行することで利用できるため、開発者が自らIAMユーザを削除することができます。

本ツールの利用イメージ

本ツールは、Slackから特定のコマンドを実行することで、IAMユーザを削除します。 「IAMユーザー名」が必須の入力項目となります。

# Slackコンソールから実行するコマンド例
/deleteiamuser <IAMユーザー名>

本ツールのインストール方法

本ツールを導入する手順は、同梱する 環境構築手順書 ファイルに記載します。

本ツール利用時の注意点

  • 削除前に対象のIAMユーザ名が正しいことを確認してくだい

本ツール利用時に発生する金額コスト

IAMUser削除ツール: 環境構築手順

前提条件

本ツールを利用するためには、以下の前提を満たす必要があります。

  • AWSアカウントを所有している
  • Slackを利用している

環境構成図

本ツールの構成図は以下の通りです。

環境構築手順

0. 環境構築準備

  • AWSマネジメントコンソールにログインしてください。
  • 画面左下の CloudShell を選択し、AWS Cloud Shellを起動してください。
  • AWS Cloud Shell画面右上の Actions を選択し、 Upload files を選択してください。
  • slack-iam-user-delete.zip を選択し、ファイルをアップロードしてください。
  • アップロード完了後、以下のコマンドを実行し、Zipファイルを解凍してください。
$ unzip slack-iam-user-delete.zip

1. Lambda関数の作成

AWS Cloud Shell環境にアクセスし、以下のコマンドを実行してください。

# 作業ディレクトリに移動
$ cd <解凍したフォルダ名>

# 一時的に使用するAmazon S3バケットを作成します
$ BUCKET_NAME_1=`date "+%Y%m%d-%H%M%S"`
$ BUCKET_NAME_2=`date "+%Y%m%d-%H%M%S"`
$ aws s3api create-bucket --bucket ${BUCKET_NAME_1} \
    --create-bucket-configuration LocationConstraint=ap-northeast-1
$ aws s3api create-bucket --bucket ${BUCKET_NAME_2} \
    --create-bucket-configuration LocationConstraint=ap-northeast-1

# 1つ目のLambda関数を作成します
$ STACK_NAME_1=iam-user-delete-request-lambda-01
$ aws cloudformation package --s3-bucket ${BUCKET_NAME_1} \
    --template-file template/slack-iam-user-deleteslack-iam-user-delete-request-handler.yaml \
    --output-template-file template/slack-iam-user-delete-request-handler-packaged.yaml
$ aws cloudformation deploy --stack-name ${STACK_NAME_1} \
    --template-file template/slack-iam-user-delete-request-handler-packaged.yaml \
    --capabilities CAPABILITY_IAM

# 2つ目のLambda関数を作成します
$ STACK_NAME_2=iam-user-delete-excute-lambda-01
$ aws cloudformation package --s3-bucket ${BUCKET_NAME_2} \
    --template-file template/slack-iam-user-delete-excute-handler.yaml \
    --output-template-file template/slack-iam-user-delete-excute-handler-packaged.yaml
$ aws cloudformation deploy --stack-name ${STACK_NAME_2} \
    --template-file template/slack-iam-user-delete-excute-handler-packaged.yaml \
    --capabilities CAPABILITY_IAM

次の工程で利用するため、以下のコマンドを実行し、Lambda関数のARNをシェル変数に設定してください。

$ FUNC_ARN=$(aws lambda get-function \
    --function-name slack-iam-user-delete-request-handler \
    --query "Configuration.FunctionArn" \
    --output text)
$ echo $FUNC_ARN

2. API Gatewayの作成

AWS Cloud Shell環境にアクセスし、以下のコマンドを実行してください。

# API Gatewayを作成します
$ STACK_NAME_3=iam-user-delete-excute-apigw-01
$ aws cloudformation deploy --stack-name ${STACK_NAME_3} \
    --template-file template/slack-iam-user-delete-request-apigw.yaml \
    --parameter-overrides FunctionArn=${FUNC_ARN} \
    --capabilities CAPABILITY_IAM

次の工程で利用するため、以下のコマンドを実行し、API GatewayのURLを取得してください。

# 作成したAPI GatewayからURL情報を生成します
$ REST_API_ID=$(aws apigateway get-rest-apis \
    --query 'items[?name==`slack-iam-user-delete-apigw`].id' \
    --output text)
$ API_URL=https://${REST_API_ID}.execute-api.ap-northeast-1.amazonaws.com/v1

# シェル変数に格納されたAPI GatewayのURLを表示します
$ echo $API_URL

3. Slackの設定、Slack Signing Secretの取得

作成したAWS API GatewayにSlackからアクセスできるよう、Slack App画面から設定を行います。また後段で使用するため、合わせて Signing Secret の値を取得します。

なお、本項で添付する画面キャプチャの内容は、Slackの更新などによって変更される場合があります。その場合は、利用者の判断のもと、作業内容を適宜修正したうえで実施してください。

  • From scratchを選択してください

  • App nameを入力して下さい (例: deleteIAMUser)。
  • 本ツールを利用可能とするSlackワークスペースを選択してください

  • Slack Appが作成されてら、画面左メニュー Slach Commands を選択してください

  • 必要な項目を以下のように入力してください
    • Command
    • Request URL
    • Short Description
    • Usage Hint
    • Escape channels, users, and links sent to your app
  • 入力後、画面右下の Save を選択してください。

  • Slashコマンドの作成を完了したら、画面左メニューの Basic Information を選択してください。

  • 画面中程の App Credentials にある Signing Secret に移動し、 Show を選択してください。

  • 設定中の Signing Secret が表示されるので、値を確認し、必要に応じてメモに記録してください。ただし秘匿情報となるた め、使用後は速やかにメモを削除してください。

4. Secrets Managerへの登録

API Gatewayへのアクセスをセキュアにするため、前段で取得したSigning SecretをAWS Secrets Managerに登録します。

AWS Cloud Shell環境にアクセスし、以下のコマンドを実行してください。

# Secrets Managerにリソースを作成します
$ cat <<EOF > secret.json
{
    "key": "<取得したSlack Signing Secretを設定してください>"
}
EOF

$ aws secretsmanager delete-secret \
  --region ap-northeast-1 \
  --name slack_for_Iam_User_delete_auth \
  --secret-string file://secret.json

$ rm secret.json


# 想定通りSecrets Managerにリソースが作成されたかを確認します。エラーが返されなければリソースは作成されています
$ aws secretsmanager describe-secret \
    --secret-id slack_for_Iam_User_delete_auth

5. 動作確認

  • Slack上の任意のチャンネルから、/deleteiamuser コマンドを入力してください。その時、項番3で設定したコマンドやUsage Hintが表示されるかを確認してください。
  • 次に、実際にSlackからIAMユーザの削除を実行してください。正しいコマンドを実行した場合、Slackから以下のようなレスポンスが返されます。

<IAMユーザ名>

おわりに

将来的にはテンプレ一つでChatOps環境構築できるようにしたいなと思ってます
Slack APIは可能性を感じる要素なので、今後生成系AI(AmazonQとかBedrockなど)関連でも取り入れていければ面白そうですね

お知らせ

APCはAWSアドバンスドティアサービスパートナー認定を受けております。

その中で私達クラウド事業部はAWSなどのクラウド技術を活用したSI/SESのご支援をしております。

https://www.ap-com.co.jp/service/utilize-aws/

また、一緒に働いていただける仲間も募集中です!
今年もまだまだ組織規模拡大中なので、ご興味持っていただけましたらぜひお声がけください。

www.ap-com.co.jp

本記事の投稿者: y-shimizu
AWSをメインにインフラ系のご支援を担当しています。 https://www.credly.com/users/giiiiiyu777/badges

Amazon EKS upgrade insightsでクラスター更新前に非推奨APIを検知する

こんにちは、エーピーコミュニケーションズ クラウド事業部の山路です。

今回は昨年12月にアップデートされたEKS upgrade insightsを紹介します。

aws.amazon.com

背景

Kubernetesは現在4か月に新しいバージョンをリリースしており、自分たちのプロジェクトで管理するKubernetesクラスターも定期的なバージョン更新が必要です。特にAmazon EKSのようなクラウドプロバイダーが提供するKubernetesサービスは、ある期間までに一定以上のバージョンに更新していないと、プロバイダー側で強制的にバージョンを更新します。AWSではクラスターのバージョンを延長サポートするようなサービスも開始していますが、定期的な更新をしないことが運用するサービス自体のSLA、コストなどに影響してしまいます。

さて、クラスターの更新を行う上で面倒なことの一つが、クラスター上で稼働するリソースのAPIバージョンも併せて更新する必要がある場合です。Kubernetesクラスターのバージョンによっては特定のリソースのAPIバージョンを合わせる必要があり、それができていない場合は該当するリソースが利用できなくなります。これまではクラスター上のリソースのAPIバージョンを一つずつ確認し、利用するAPIバージョンが廃止されていないかチェックする必要がありました。

今回Amazon EKSに追加されたUpgrade insightsは、クラスター上のリソースのAPIバージョンをチェックし、アップグレードするうえで問題になる場合はユーザーに分かるよう表示してくれます。またUpgrade insightsを利用するうえで必要な事前作業などがないため、EKSを利用するユーザーは無条件で利用可能です。

なお、詳細は以下ドキュメントをご確認ください。

docs.aws.amazon.com

AWSブログでも本機能は紹介されています。

aws.amazon.com

検証

今回はAmazon EKS ver 1.25の上にHPAリソースを作成します。ただしHPAのAPIバージョンは autoscaling/v2beta2 という少し古いものを利用し、Upgrade insightsがそれを検知するか確認しました。

# Amazon EKSのバージョン
$ kubectl version
Client Version: version.Info{Major:"1", Minor:"22", GitVersion:"v1.22.0", GitCommit:"c2b5237ccd9c0f1d600d3072634ca66cefdf272f", GitTreeState:"clean", BuildDate:"2021-08-04T18:03:20Z", GoVersion:"go1.16.6", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"25+", GitVersion:"v1.25.16-eks-8cb36c9", GitCommit:"3a3ea80e673d7867f47bdfbccd4ece7cb5f4a83a", GitTreeState:"clean", BuildDate:"2023-11-22T21:53:22Z", GoVersion:"go1.20.10", Compiler:"gc", Platform:"linux/amd64"}
WARNING: version difference between client (1.22) and server (1.25) exceeds the supported minor version skew of +/-1

# metrics-serverの作成
$ kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/download/v0.6.4/components.yaml

# テスト用のDeployment / HPAの作成
$ kubectl apply -f sample-hpa.yaml

$ kubectl get pods
NAME                    READY   STATUS    RESTARTS   AGE
sample-6c6899cc-xk5xd   1/1     Running   0          67s

$ kubectl get hpa
NAME     REFERENCE           TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
sample   Deployment/sample   0%/50%    1         3         1          72s

※使用した sample-hpa.yaml はここをクリック

apiVersion: apps/v1
kind: Deployment
metadata:
  name: sample
spec:
  replicas: 1
  selector:
    matchLabels:
      app: sample-app
  template:
    metadata:
      labels:
        app: sample-app
    spec:
      containers:
        - image: nginx
          name: sample-pod
          resources:
            requests:
              #memory: "64Mi"
              cpu: "250m"
            limits:
              #memory: "128Mi"
              cpu: "500m"
---
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
  name: sample
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: sample
  minReplicas: 1
  maxReplicas: 3
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 50

上記リソースを作成後、Amazon EKSのメニューから Upgrade insights を確認すると、エラーが発生することを確認できます。

該当する項目を選択すると Deprecated APIs removed in Kubernetes v1.26 とあるように、Kubernetesをv1.26に更新するうえで削除されるAPIがあることを表示しています。

画面下部には具体的にエラーを発生させるAPIと、それを利用するリソースが表示されます。その中にはHPAのAPIも含まれています。

HPA APIをクリックすると、廃止するAPIの詳細などが表示されます。

さらにリソースのほうを選択すると、リソースの情報ページに遷移します。

なお、AWS CLIからも上記情報は確認できます。具体的には list-insights describe-insight などのコマンドを利用します。

クラスターに対するUpgrade insightsのリストを表示

$ aws eks list-insights --cluster-name eks-cluster --region ap-northeast-1
{
    "insights": [
        {
            "id": "40163eec-bc6d-4927-b740-4d9e8bdc5ae1",
            "name": "Deprecated APIs removed in Kubernetes v1.26",
            "category": "UPGRADE_READINESS",
            "kubernetesVersion": "1.26",
            "lastRefreshTime": "2024-01-03T15:10:10+09:00",
            "lastTransitionTime": "2024-01-03T15:10:09+09:00",
            "description": "Checks for usage of deprecated APIs that are scheduled for removal in Kubernetes v1.26. Upgrading your cluster before migrating to the updated APIs supported by v1.26 could cause application impact.",
            "insightStatus": {
                "status": "ERROR",
                "reason": "Deprecated API usage detected within last 30 days and your cluster is on Kubernetes v1.25."
            }
        },
        {
            "id": "d1836d3e-736e-4535-9533-c04d961d1c7b",
            "name": "Deprecated APIs removed in Kubernetes v1.29",
            "category": "UPGRADE_READINESS",
            "kubernetesVersion": "1.29",
            "lastRefreshTime": "2024-01-03T15:10:10+09:00",
            "lastTransitionTime": "2024-01-03T15:10:09+09:00",
            "description": "Checks for usage of deprecated APIs that are scheduled for removal in Kubernetes v1.29. Upgrading your cluster before migrating to the updated APIs supported by v1.29 could cause application impact.",
            "insightStatus": {
                "status": "PASSING",
                "reason": "No deprecated API usage detected within the last 30 days."
            }
        },
        {
            "id": "4e88e2db-fb41-4d87-85ee-fe76dd0f92ab",
            "name": "Deprecated APIs removed in Kubernetes v1.27",
            "category": "UPGRADE_READINESS",
            "kubernetesVersion": "1.27",
            "lastRefreshTime": "2024-01-03T15:10:10+09:00",
            "lastTransitionTime": "2024-01-03T15:10:09+09:00",
            "description": "Checks for usage of deprecated APIs that are scheduled for removal in Kubernetes v1.27. Upgrading your cluster before migrating to the updated APIs supported by v1.27 could cause application impact.",
            "insightStatus": {
                "status": "PASSING",
                "reason": "No deprecated API usage detected within the last 30 days."
            }
        }
    ]
}

エラーを検知したinsightsの詳細を確認する

$ aws eks describe-insight --region ap-northeast-1 --id 40163eec-bc6d-4927-b740-4d9e8bdc5ae1 --cluster-name eks-cluster
{
    "insight": {
        "id": "40163eec-bc6d-4927-b740-4d9e8bdc5ae1",
        "name": "Deprecated APIs removed in Kubernetes v1.26",
        "category": "UPGRADE_READINESS",
        "kubernetesVersion": "1.26",
        "lastRefreshTime": "2024-01-03T15:10:10+09:00",
        "lastTransitionTime": "2024-01-03T15:10:09+09:00",
        "description": "Checks for usage of deprecated APIs that are scheduled for removal in Kubernetes v1.26. Upgrading your cluster before migrating to the updated APIs supported by v1.26 could cause application impact.",
        "insightStatus": {
            "status": "ERROR",
            "reason": "Deprecated API usage detected within last 30 days and your cluster is on Kubernetes v1.25."
        },
        "recommendation": "Update manifests and API clients to use newer Kubernetes APIs if applicable before upgrading to Kubernetes v1.26.",
        "additionalInfo": {
            "EKS update cluster documentation": "https://docs.aws.amazon.com/eks/latest/userguide/update-cluster.html",
            "Kubernetes v1.26 deprecation guide": "https://kubernetes.io/docs/reference/using-api/deprecation-guide/#v1-26"
        },
        "resources": [
            {
                "insightStatus": {
                    "status": "ERROR"
                },
                "kubernetesResourceUri": "/apis/autoscaling/v2beta2/namespaces/default/horizontalpodautoscalers/sample"
            }
        ],
        "categorySpecificSummary": {
            "deprecationDetails": [
                {
                    "usage": "/apis/flowcontrol.apiserver.k8s.io/v1beta1/flowschemas",
                    "replacedWith": "/apis/flowcontrol.apiserver.k8s.io/v1beta3/flowschemas",
                    "stopServingVersion": "1.26",
                    "startServingReplacementVersion": "1.26",
                    "clientStats": []
                },
                {
                    "usage": "/apis/flowcontrol.apiserver.k8s.io/v1beta1/prioritylevelconfigurations",
                    "replacedWith": "/apis/flowcontrol.apiserver.k8s.io/v1beta3/prioritylevelconfigurations",
                    "stopServingVersion": "1.26",
                    "startServingReplacementVersion": "1.26",
                    "clientStats": [
                        {
                            "userAgent": "eks-k8s-metrics",
                            "numberOfRequestsLast30Days": 32,
                            "lastRequestTime": "2024-01-03T14:31:01+09:00"
                        }
                    ]
                },
                {
                    "usage": "/apis/autoscaling/v2beta2/horizontalpodautoscalers",
                    "replacedWith": "/apis/autoscaling/v2/horizontalpodautoscalers",
                    "stopServingVersion": "1.26",
                    "startServingReplacementVersion": "1.23",
                    "clientStats": [
                        {
                            "userAgent": "kubectl",
                            "numberOfRequestsLast30Days": 7,
                            "lastRequestTime": "2024-01-03T13:25:44+09:00"
                        }
                    ]
                }
            ]
        }
    }
}

さいごに

弊社はAWSアドバンスドティアサービスパートナー認定を受けております。また以下のようにAWSの活用を支援するサービスも行っているので、何かご相談したいことがあればお気軽にご連絡ください。

www.ap-com.co.jp

AWS Control Tower の Account Factory で作成した AWS アカウントに Microsoft Entra ID (旧 Azure AD) ユーザーでシングルサインオンする!(ユーザー同期編①)

はじめに

こんにちは。クラウド事業部の早房です。
今回は、前回に引き続き AWS Control Tower の Account Factory で作成した AWS アカウントに Microsoft Entra ID のユーザーを用いてシングルサインオンをするまでに必要な作業について紹介します。
※前回記事は以下。

techblog.ap-com.co.jp

本記事ではユーザー同期編ということで、Microsoft Entra ID 上のユーザーを IAM Identity Center ユーザーとして AWS 環境に同期するための方法をご紹介します。

IAM Identity Center ユーザーとは?

【AWS】【初心者】IAM Identity Center とは?IAM Identity Center ユーザーって何者? - APC 技術ブログ

なお、ユーザー同期編はボリュームがあるので本記事も含め 3 つの記事に分けて投稿しようかと思います。

1. 目次

  1. 目次
  2. 全体の作業フローと本記事での作業箇所の確認
  3. 前提条件
  4. 作業完了条件
  5. 作業手順
  6. 参考情報

2. 全体の作業フローと本記事での作業箇所の確認

①AWS Control Tower のランディングゾーンセットアップ
②Microsoft Entra ID → AWS へのユーザー同期
③Account Factory での AWS アカウント作成
④作成したAWSアカウントへのアクセス権の設定
といったフローで作業を進めていきます。

本投稿の作業範囲は「Microsoft Entra ID → AWS へのユーザー同期 」です。

3. 前提条件

  • AWS アカウントで IAM Identity Center が有効になっていること。
  • Azure で Microsoft Entra ID を使用していること。

4. 作業完了条件

  • AWS IAM Identity Center と Microsoft Entra ID の双方で SAML 信頼関係構築のためのメタデータファイルのダウンロードができること。

5. 作業手順

5-1. メタデータファイルのダウンロード (AWS)

  1. 管理アカウントの AWS マネジメントコンソールにログイン後、検索窓に「IAM Identity Center」と入力し、IAM Identity Center のコンソール画面を表示します

  2. IAM Identity Center のダッシュボードから「アイデンティティソースを確認」をクリックします。

  3. アイデンティティソースタブ内のアクションから「アイデンティティソースを変更」をクリックします。

  4. 「外部 ID プロバイダー」を選択し、「次へ」をクリックします。

  5. 「メタデータファイルをダウンロード」をクリックし、ファイルをダウンロードします。

  6. サインアウト等はせず、次項「5-2. エンタープライズアプリケーションの設定 (Azure)」を実施します。

5-2. フェデレーション メタデータ XML のダウンロード (Azure)

  1. Azure Portal にログインし、検索窓に「Microsoft Entra ID」と入力し、Microsoft Entra ID をクリックします。

  2. 左ペインより「エンタープライズ アプリケーション」をクリックします。

  3. 「新しいアプリケーション」をクリックします。

  4. 検索窓に「AWS IAM Identity Center」と入力し、「AWS IAM Identity Center (successor to AWS Single Sign-On)」をクリックします。

  5. 「作成」をクリックします。

  6. アプリケーションの追加が正常に完了することを確認します。

  7. 左ペインより「シングル サインオン」をクリックし、「SAML」をクリックします。

  8. 「メタデータファイルをアップロードする」をクリックし、AWS IAM Identity Center でダウンロードしたメタデータファイルを選択し、「追加」をクリックします。

  9. ファイルのアップロードが正常に完了したことを確認します。

  10. 「保存」をクリックします。

  11. 構成の保存が正常に完了したことを確認します。 「シングル サインオンをテスト」が表示された場合は、「いいえ」を選択します。

  12. SAML 証明書の項目内より、「フェデレーション メタデータ XML」をダウンロードします。

  13. ファイルのダウンロードが正常に完了したことを確認します。

6. 参考情報

  • チュートリアル: Microsoft Entra SSO と AWS IAM Identity Center の統合

learn.microsoft.com

  • 外部 ID プロバイダーConnect する

docs.aws.amazon.com

まとめ

今回はMicrosoft Entra ID から AWS へのユーザー同期手順ということで、双方の環境でのメタデータダウンロードまでの手順を紹介しました。
次回は Microsoft Entra ID で取得したメタデータを使用して、AWS IAM Identity Center のアイデンティティソースを変更する様子を紹介します。

おわりに

私達クラウド事業部はAWSなどのクラウド技術を活用したSI/SESのご支援をしております。

https://www.ap-com.co.jp/service/utilize-aws/

また、一緒に働いていただける仲間も募集中です!
今年もまだまだ組織規模拡大中なので、ご興味持っていただけましたらぜひお声がけください。

www.ap-com.co.jp

本記事の投稿者: hybs_yuuuu
AWSをメインにインフラ系のご支援を担当しています。 https://www.credly.com/users/hybs_yuuuu/badges

AWS S3 のファイルを社内からのみ URL でダウンロード可能にする(パブリックアクセスブロック有効)

はじめに

こんにちは。クラウド事業部の野本です。

業務でモックサーバを作る際に、静的なファイルをふつうに URL でアクセスしてダウンロードできるようにする必要がありました。この用途に AWS の S3 を使いたいものの、バケットの設定を間違えると全世界に公開されてしまいそうで、公式ドキュメントを調べながら恐る恐る設定しました。

調べた結果、バケットポリシーで適切なアクセス制限を掛けるならパブリックアクセスブロック機能は有効のままでもいいことがわかりました。その設定方法や考え方について纏めます。

設定方法

S3 のオブジェクトを URL 直アクセスでダウンロードできるようにするには、 REST API GetObject を全員に許可するようにバケットポリシーを設定します。
リクエスト元を制限する際にポリシーが「非パブリック」と判定されるよう設定すれば、パブリックアクセスブロック機能はオンのままで構いません。

例えば特定のグローバル IP (会社のネットワークなど)からのみアクセスできるようにするなら、バケットポリシーは以下のようになります。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": ["s3:GetObject"],
            "Resource": ["arn:aws:s3:::<bucket-name>/*"],
            "Condition": {
                "IpAddress": {
                    "aws:SourceIp": ["<IP-address>/32"]
                }
            }
        }
    ]
}
  • Principal を * にして、 AWS アカウントを持っていない人でも REST API を実行できるようにします
    • 安全のため、許可する Action や Resource は必要最小限にします
  • Condition でアクセス制限を掛ける際に、ポリシーが「非パブリック」になるよう条件を調節します
    • ほとんどの場合にアスタリスクは使えません
    • 送信元 IP で制限する場合は、 CIDR を /8 以上に細かくします
    • VPC エンドポイント経由で S3 にアクセスするなら、送信元 VPC などで制限することもできます
    • 正確な条件は S3 の『「パブリック」の意味』を参照してください

設定内容を理解する

「URL でダウンロード」の裏側

今回したいことは、単純にブラウザなどで URL に直アクセスしてファイルを取得することだけです。しかしドキュメントを見ても、 S3 コンソールや REST API などを使う方法しかなく、直アクセスする感じのものが見当たりませんでした。(強いて言えば、「署名付き URL」はブラウザに入力できるようです)
オブジェクトのダウンロード - Amazon Simple Storage Service

悩んで調べ続けた結果、目的の操作は REST API の GetObject を署名なし(未認証)で実行するということだとわかりました。署名がない場合は AWS アカウントを持っていない匿名ユーザとして解釈されます。
アクセス管理の概要 - Amazon Simple Storage Service

したがって、バケットポリシーなどでオブジェクトに対して匿名ユーザのアクセスを許可すれば、 URL 直アクセスでダウンロードできることになります。実態が REST API なので、書き込みなどを許可する権限を不用意に与えないよう注意が必要です。(例えば s3:PutObject を許可するとアップロードできます)


URL でダウンロードするのは S3 バケットを静的ウェブサイトとして利用する場合に重要なので、そちらにはより詳細な設定方法が書いてあります。

ウェブサイトアクセスのアクセス許可の設定 - Amazon Simple Storage Service

バケットを静的ウェブサイトとして設定する場合、このウェブサイトを公開するときは、パブリック読み取りアクセスを許可できます。バケットをパブリックに読み取り可能にするには、バケットのパブリックアクセスブロック設定を無効にし、パブリック読み取りアクセスを許可するバケットポリシーを記述する必要があります。

バケット内のオブジェクトをパブリックに読み取り可能にするには、すべてのユーザーに s3:GetObject アクセス許可を付与するバケットポリシーを作成する必要があります。

S3 のパブリックアクセスブロック設定を編集した後で、バケットへのパブリック読み取りアクセスを許可するバケットポリシーを追加できます。パブリック読み取りアクセスを許可すると、インターネット上のだれでもバケットにアクセスできるようになります。

パブリックアクセスブロック機能との関係

前節に挙げたドキュメントには、パブリックアクセスブロックを無効にするよう書いてあります。実際、ブロックが有効のままでは、ドキュメントにあるバケットポリシーの追加ができません。

しかしパブリックアクセスブロックをよく調べてみると、一定の条件を満たせば、この機能がオンのままでも構わないようでした。
Amazon S3 ストレージへのパブリックアクセスのブロック - Amazon Simple Storage Service

4つの設定についての説明を読むと、 BlockPublicPolicyRestrictPublicBuckets のところに、「パブリックアクセスが許可されている場合」や「パブリックポリシーを持つアクセスポイントやバケットへのアクセスは」といった前置きがあります。パブリックというのは匿名アクセスやインターネットアクセスなどをそのまま指しているわけではなさそうですし、パブリックでなければブロック機能の対象外のようです。

そしてドキュメントには『「パブリック」の意味』がきちんと書いてあります。

バケットポリシーを評価する場合、 Amazon S3 はまずポリシーがパブリックであると想定します。その後、ポリシーを評価して非パブリックとしての資格があるかどうかを判断します。非パブリックと見なすには、バケットポリシーで、次のうち 1 つ以上の固定値(ワイルドカードを含まない値または AWS Identity and Access Management ポリシー変数)にのみアクセスを許可する必要があります。

  • AWS プリンシパル、ユーザー、ロール、またはサービスプリンシパル(例: aws:PrincipalOrgID
  • aws:SourceIp を使用した一連のクラスレスドメイン間ルーティング(CIDR)。 CIDR の詳細については、 RFC Editor のウェブサイトで RFC 4632 を参照してください。

つまり「パブリック」というのはバケットポリシーの評価結果を指しています。そして評価方法によると、 Principal が * (匿名ユーザ含め全員)であっても他の条件で「非パブリック」になることがあります。(ドキュメントには aws:SourceVpc での具体例が載っています)

したがって、バケットポリシーに適切な条件を書き「非パブリック」になれば、パブリックアクセスブロック機能はオンのままでも何も影響しません。

実際に試す

ネットワーク環境の用意

今回は送信元 IP によってダウンロードを制限することを試します。グローバル IP の異なる2つの環境を用意し、 https://ifconfig.io/ などにアクセスして IP を調べておきます。

以降では以下の環境を仮定して進めます。

環境 グローバル IP
会社に VPN 接続している PC 203.0.113.11
会社に VPN 接続していない PC 203.0.113.22

サンプルバケットとオブジェクトの作成

検証用のバケットを作成し、適当なファイルをアップロードしておきます。
※ 安全のため、全世界に公開されても問題ない名前や内容にします。

  • バケット(リージョンと名前以外はデフォルト)
    • 一般的な設定
      • AWS リージョン : アジアパシフィック (東京) ap-northeast-1
      • バケットタイプ : 汎用
      • バケット名 : test-public-a9688bc
    • オブジェクト所有者
      • ✅ ACL 無効 (推奨)
    • このバケットのブロックパブリックアクセス設定
      • ✅ パブリックアクセスをすべてブロック
  • オブジェクト(適当に用意したファイル)
    • 名前 : sample.html
    • タイプ : text/html
<html>
<body>
  <h2>Hello, S3!</h2>
</body>
</html>

アップロードしたオブジェクトを確認すると、概要のところに URL が書いてあります。

しかし URL に直接アクセスしても、この時点では 403 エラーになります。

バケットポリシーの設定

バケットの設定画面を開きます。パブリックアクセスブロックは全てオンにしたままにしておきます。

以下のバケットポリシーを設定します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": ["s3:GetObject"],
            "Resource": ["arn:aws:s3:::test-public-a9688bc/*"],
            "Condition": {
                "IpAddress": {
                    "aws:SourceIp": ["203.0.113.11/32"]
                }
            }
        }
    ]
}

すると、指定した IP からは URL にアクセスしてファイルをダウンロードできる(あるいはブラウザ上で見られる)ようになります。

一方で指定していない IP からアクセスすると相変わらず 403 エラーです。

パブリックアクセスブロック機能の確認

前節の状態でバケットポリシーの CIDR を 0.0.0.0/0 などに変えようとすると、ポリシーの更新自体が失敗します。これは、パブリックアクセスブロックのうち3番目の BlockPublicPolicy が、パブリックなポリシーの新規適用を拒否するからです。

また、3番目のチェックを一時的に外して 0.0.0.0/0 に変えられたとしても、今度はファイルへのアクセスができなくなります( IP 制限を緩めたはずなのに)。これは、4番目の RestrictPublicBuckets が、パブリックなポリシーを持つバケットへのクロスアカウントアクセスを拒否するからです。

4番目のチェックを外すと、晴れて 0.0.0.0/0 の条件が効き、どのグローバル IP からでもファイルへアクセスできるようになります。

このように、パブリックアクセスブロック(のうちポリシーを対象とした設定)は、「パブリック」と判定されるポリシーに対して効果を発揮します。逆に言うと、ポリシーが「非パブリック」である限りは何も追加ブロックしません。

まとめ

S3 のファイルを URL でダウンロード可能にする設定について、その背後の意味を含めて調べ、また実際に動作を試してみました。

特にパブリックアクセスブロックは、調べてみると「パブリック」の意味するものが予想と違っていて、今回のようにリクエスト元を制限する事例では有効なままでいいことに驚きました。

パブリックアクセスブロック機能はあくまで防波堤のひとつであり、ポリシーが正確ならブロックを無効化しても安全ですし、逆にポリシーに変な欠陥があればブロックを有効化していてもすり抜けることがあります。とはいえ有効化できるに越したことはないため、今後もポリシーを設定する際は上手に使っていこうと思います。

【AWS】AWS 認定資格の受験費用が改定されます

はじめに

こんにちは。クラウド事業部の早房です。
2024 年 4 月 1 日より、AWS認定資格の受験費用が改定されるようなので共有します。
aws.amazon.com

改定前と改定後の比較

日本円だと、Foundational が 11,000 円→15,000 円、Associate が 15,000 円→20,000 円、Professional と Speciality がそれぞれ 30,000円 → 40,000円 に値上げされます。

試験日を 2024 年 4 月 1 日以降に指定して試験予約をしようとしてみたところ予約時点(2024年1月23日)では従来の料金でした。
2024 年 4 月 1 日以降に予約をする場合に新料金が適用される模様。 受験予定がある場合は早めの予約をしておくと良さそうです。

また、2024 年 4 月 1 日以降に試験のスケジュールの変更を行った場合も追加料金も発生しないようです。

クレジットカードまたは現金で受験料を支払った個人は、為替レートが更新された後に試験の日程を変更した場合に追加の支払いを行う必要はありません。AWS 認定試験のスケジュールを変更できるのは 2 回までです。

おわりに

AWS認定資格の受験費用が改定される件についてご紹介させていただきましたが、バウチャーチケットや社内制度を利用して今後も資格取得を続けていきたいと思います。
落ちたときのダメージがこれまで以上に大きくなるので、入念に勉強をして試験に臨みたいです。

私達クラウド事業部はAWSなどのクラウド技術を活用したSI/SESのご支援をしております。

https://www.ap-com.co.jp/service/utilize-aws/

また、一緒に働いていただける仲間も募集中です!
今年もまだまだ組織規模拡大中なので、ご興味持っていただけましたらぜひお声がけください。

www.ap-com.co.jp

本記事の投稿者: hybs_yuuuu
AWSをメインにインフラ系のご支援を担当しています。 https://www.credly.com/users/hybs_yuuuu/badges

【合格体験記】AWS Certified Database - Specialty に合格しました。

はじめに

こんにちは!クラウド事業部の早房です。
先日 AWS Certified Database - Specialty を受験し無事に合格しました。
今回は試験を受けてみての感想、および学習方法等について記事を書きます。

出題範囲と割合について

出題範囲と割合は以下です。
一般的なデータベースの知識はそこまで問われず、あくまでもAWSで利用できるデータベース関連のサービスに関する知識が必要になります。

• 第 1 分野: ワークロード固有のデータベース設計 (採点対象コンテンツの 26%)
• 第 2 分野: デプロイと移行 (採点対象コンテンツの 20%)
• 第 3 分野: マネジメントとオペレーション (採点対象コンテンツの 18%)
• 第 4 分野: モニタリングとトラブルシューティング (採点対象コンテンツの 18%)
• 第 5 分野: データベースセキュリティ (採点対象コンテンツの 18%)
https://d1.awsstatic.com/ja_JP/training-and-certification/docs-database-specialty/AWS-Certified-Database-Specialty_Exam-Guide.pdf

勉強方法

学習時間

毎日2時間程度の学習を2週間つづけました。

使用した教材

■書籍

  • 要点整理から攻略する『AWS認定 データベース・専門知識』
    www.nri-net.com

■ Web問題集

勉強方法

  1. Cloud Lisence の問題をとりあえず2周解く
  2. 1.で間違えた問題を 1 周解く
  3. ここまでで理解できていない部分は公式ドキュメントやブログ記事を参考に調査
  4. Cloud Lisence の模擬試験、公式のサンプル問題の練習問題集を解く

あまり腹落ちしない部分は Black Belt なども参考にしてみました。
書籍は空き時間で見たりしましたが、全部は読み切れませんでした。

結果

合格 (813点)

まとめ・感想

思ったよりも難しかったです。
試験問題の内容については書けませんが、オンプレからAWSへのマイグレーションに関する知識やディザスタリカバリーに関する知識は必須かなと思いました。
要件(コスト優先/運用効率優先/RPOやRTO)によってどのオプションを選択するのがベストなのかというのも理解しておくと良いです。

余談にはなりますが、今回OnVueを利用してのオンライン受験でしたが、仕様変更されたのかチェックインプロセスの言語が全て英語でした。
また、スマホで受験環境を撮影する際にはスマホのブラウザを横向き表示できるようにしておかないとカメラが起動しないという制約もあったり・・・。
オンライン受験は便利ですが、お手洗いを含めて途中退席できないなどのルールもあるので、たまには会場で受けてみるのもよいかなと感じました。

おわりに

今年一発目の受験で無事に合格できてほっとしています。これでAWS認定資格は合計5つ取得することができました。(SAA,SAP,SCS,SOA,DBS)
次はDVAもしくは余裕があればDOP辺りの取得ができればと思います。

私達クラウド事業部はAWSなどのクラウド技術を活用したSI/SESのご支援をしております。

https://www.ap-com.co.jp/service/utilize-aws/

また、一緒に働いていただける仲間も募集中です!
今年もまだまだ組織規模拡大中なので、ご興味持っていただけましたらぜひお声がけください。

www.ap-com.co.jp

本記事の投稿者: hybs_yuuuu
AWSをメインにインフラ系のご支援を担当しています。 https://www.credly.com/users/hybs_yuuuu/badges

AWS Control Tower の Account Factory で作成した AWS アカウントに Microsoft Entra ID (旧 Azure AD) ユーザーでシングルサインオンする!(ランディングゾーンセットアップ編)

はじめに

こんにちは。クラウド事業部の早房です。
今回は、AWS Control Tower の Account Factory で作成した AWS アカウントに Microsoft Entra ID のユーザーを用いてシングルサインオンをする方法をご紹介します。
AWS とAzure の双方での作業が必要になりボリュームもそこそこあるので複数記事に分けて投稿します。
本記事では、AWS Control Tower のランディングゾーンセットアップ手順をご紹介します。

1. 目次

  1. 目次
  2. 全体の作業フローと本記事での作業箇所の確認
  3. 前提条件
  4. 作業完了条件
  5. 作業手順
  6. 参考情報

2. 全体の作業フローと本記事での作業箇所の確認

①AWS Control Tower のランディングゾーンセットアップ
②Microsoft Entra ID → AWS へのユーザー同期
③Account Factory での AWS アカウント作成
④作成したAWSアカウントへのアクセス権の設定
といったフローで作業を進めていきます。

本投稿の作業範囲は「AWS Control Tower のランディングゾーンセットアップ」です。

3. 前提条件

  • AWS アカウントの作成が完了しており、管理アカウントの管理者権限を持つユーザーでの作業が可能であること。
    ※AWS アカウントの作成方法は以下をご参照ください。
    https://aws.amazon.com/jp/register-flow/

4. 作業完了条件

  • ランディングゾーンのセットアップが正常に終了すること。
  • ランディングゾーンのセットアップ完了後、ランディングゾーンのセットアップ時に指定した OU が作成されていること。
  • ランディングゾーンのセットアップ完了後、ランディングゾーンのセットアップ時に指定したログアーカイブ用アカウント、および監査用アカウントが作成されていること。
  • ランディングゾーンのセットアップ完了後、ログアーカイブ用アカウント内にログアーカイブ用のS3バケットが作成されていること。

5. 作業手順

5-1. セットアップ開始

  1. 管理アカウントの AWS マネジメントコンソールにログイン後、検索窓に「control tower」と入力し、Control Tower をクリックします。

  2. AWS Control Tower のコンソール画面が表示されたら、「ランディングゾーンの設定」をクリックします。

5-2. 料金の確認とリージョンの選択

1. ホームリージョンの選択

AWS Control Towerによって作成される共有アカウントのリソース(IAM Identity Center/Service Catalog/S3バケット など)がプロビジョニングされるリージョンをプルダウンより選択します。

2. リージョン拒否設定

「有効になっていません」を選択します。
※リージョン拒否設定を有効にした場合、AWS Control Towerに登録されたアカウント上で、リソースのデプロイが可能なリージョンを制御することができます。

3. ガバナンスのための追加リージョンを選択

追加リージョンは選択せず、「次へ」をクリックします。

5-3. 組織単位 (OU) の設定

1. 基礎となるOU

任意の名前を入力します。
※デフォルトは「Security」

2. 追加のOU

任意の名前を入力し、「次へ」をクリックします。
※デフォルトは「Sandbox」

5-4. 共有アカウントの設定

1. 管理アカウント

組織の管理アカウントのメールアドレスが入力されていることを確認します。

2. ログアーカイブ用アカウント・監査用アカウント

AWS Control Tower のログアーカイブ用アカウント、および監査用アカウントの情報を入力します。
それぞれアカウントの新規作成を選択し、アカウント用に用意したメールアドレスを入力し、アカウント名は変更せずに「次へ」をクリックします。

※参考
https://docs.aws.amazon.com/ja_jp/controltower/latest/userguide/configure-shared-accounts.html

5-5. その他の設定

1. AWS アカウントアクセス設定

「AWS Control TowerはIAM Identity Centerを使用してAWSアカウントアクセスを設定します。」を選択します。

2. AWS CloudTrail の設定

「有効」を選択します。

3. Amazon S3 のログ設定

空白のままにします。

4. KMS 暗号化

任意の項目であるため、今回はチェックを入れずにそのまま「次へ」をクリックします。

5-6. ランディングゾーン確認とセットアップ

  1. 設定内容、セットアップ時に作成されるロール、およびガイダンスが表示されるため確認を行います。


  2. 内容に誤りがないことを確認し、チェックボックスにチェックを入れ、「ランディングゾーンの設定」をクリックします。

  3. セットアップが開始されます。セットアップは30~60分程度で完了します。

  4. ランディングゾーンの設定が完了したことを確認します。

5-7. セットアップ後の確認

5-7-1. ランディングゾーンのセットアップ時に指定した OU およびアカウントの確認

  1. AWS Control Center のコンソールを開き、ダッシュボードを選択します。

  2. 登録済み組織単位にRootおよび「2. 組織単位 (OU) の設定」で指定した OU が、登録済みアカウントに組織の管理アカウントおよび「3-2. ログアーカイブ用アカウント・監査用アカウント」で指定したアカウントが登録されていることを確認します。

5-7-2. ログアーカイブ用アカウントの S3 バケットの確認

  1. 登録済みアカウントの中にあるログアーカイブ用のアカウント名をクリックします。

  2. ログアーカイブ用のアカウントのアカウントIDをコピーします。

  3. コンソール画面右上のアカウント名をクリックし、「ロールの切り替え」をクリックします。

  4. ロールの切り替え画面が表示されるため、以下情報を入力し、「ロールの切り替え」をクリックします。
    アカウント : ログアーカイブ用のアカウントのアカウントID
    ロール : AWSControlTowerExecution
    表示名 : 任意の表示名を入力

  5. 検索窓から S3 を検索し、S3 をクリックします。

  6. aws-controltower-logs-<ログアーカイブ用のアカウントID>-<リージョン名>、aws-controltower-s3-access-logs-<ログアーカイブ用のアカウントID>-<リージョン名>が存在することを確認します。

参考情報

まとめ

今回はランディングゾーンセットアップについてご紹介させていただきました。
次回はMicrosoft Entra ID のユーザーをAWS環境に同期する手順についてご紹介します!

おわりに

私達クラウド事業部はAWSなどのクラウド技術を活用したSI/SESのご支援をしております。

https://www.ap-com.co.jp/service/utilize-aws/

また、一緒に働いていただける仲間も募集中です!
今年もまだまだ組織規模拡大中なので、ご興味持っていただけましたらぜひお声がけください。

www.ap-com.co.jp

本記事の投稿者: hybs_yuuuu
AWSをメインにインフラ系のご支援を担当しています。 https://www.credly.com/users/hybs_yuuuu/badges

Amazon EKSクラスターの延長サポート機能の紹介

こんにちは、クラウド事業部の山路です。

今回はAmazon EKSの延長サポート機能、先日公開されたコストなどの追加情報を紹介します。

まとめ

  • これまでAmazon EKSは、新バージョンがリリースされてから14か月がサポート期間であり、期限を過ぎるとAWS側で強制的に更新されました。
  • 延長サポート適用後、新バージョンリリースから14か月は「標準サポート期間」、標準サポート終了から12か月間は「延長サポート期間」となり、延長サポートが終了するとクラスターの自動更新が実施されます。
  • 2024年4月1日以降は延長サポート対象のクラスターにつき追加料金(0.50ドル/時)が発生します。

Amazon EKSの延長サポートとは

Amazon EKSは、Kubernetesに追従するように新しいバージョンをリリースします。これまで新しいAmazon EKSはリリースから14か月間はサポート期間となり利用可能でしたが、14か月が過ぎると、同バージョンでの新しいクラスターの作成はできなくなり、稼働中のクラスターもAWS側でControl Planeのバージョンアップを強制的に実施します。このため、 (EKSに限らないですが) Amazon EKSクラスターは定期的な更新作業が必要となります。

一方で、企業やプロジェクトの状況によっては、何らかの理由でクラスターを速やかに更新するのが難しい場合もあります。なお昨年公開されたAWSのブログでは、以下の2つのシナリオを想定しています。

  • Code Freezeへの対応: ビジネス上重要なタイミング (年末商戦など) のため、クラスターの更新を実施せず環境を固定したい場合。
  • Third partyとの依存関係: クラスター上に展開するThird party製品の開発が遅れたため、EKSのバージョンとの依存関係を解消するまでの時間を稼ぎたい場合。

こういったケースに対応するため、2023年10月にAmazon EKSの延長サポートがプレビューとして開始されました。

aws.amazon.com

延長サポート期間中は、AWSへの問い合わせも対応していおり、また以下のリソースに対するパッチをリリースします。Control Planeにはセキュリティパッチ、その他リソースには重要なパッチが適用されます。

  • Control Plane
  • Amazon VPC CNI アドオン
  • kube-proxy アドオン
  • CoreDNS アドオン
  • Amazon Linux / Bottlerocket 向けの EKS Optimized AMI
  • EKS Fargate ノード

延長サポート期間は、標準サポート期間終了後に自動的に推移します。ユーザー側で追加のアクションは不要です。

延長サポート期間が終了すると、クラスターはAWSによって自動的にバージョンアップされます。そのため、クラスターの自動更新まで最大26か月間はサポート期間として対象のバージョンを利用できます。

なお延長サポートはバージョン1.23以降のバージョンのみ適用対象となります。

1.23のEKSクラスターを作成すると、以下の画像のように延長サポートの表示も確認できます。

延長サポートにかかるコストと適用日時

2024年1月16日、延長サポートによって発生するコストと、適用時期が公開されました。

aws.amazon.com

2024年4月1日からは、延長サポートの適用されるクラスター当たり 0.60ドル/時のコストが発生します。通常サポート時は 0.10ドル/時 なので0.5ドル増加しており、1日で12ドル、1か月で約360ドルほど追加コストが発生します。けっこうなコストが発生するので、基本的には標準サポート期間中にクラスターを更新し、どうしても厳しいときだけ延長サポートに手を出すのがよいでしょう。

なお、利用可能なEKSのバージョンと延長サポート適用日はAWSのドキュメントにも記載があります。特にバージョン1.23 / 1.24はコスト発生前に延長サポート期間に入るため、早めのバージョンアップが必要となります。

docs.aws.amazon.com

さいごに

弊社はAWSアドバンスドティアサービスパートナー認定を受けております。また以下のようにAWSの活用を支援するサービスも行っているので、何かご相談したいことがあればお気軽にご連絡ください。

www.ap-com.co.jp