

# Amazon EC2 の Linux コンテナで gMSA を使用する
<a name="linux-gmsa"></a>

Amazon ECS は、*グループ管理サービスアカウント* (gMSA) と呼ばれる特殊なサービスアカウントを使用して、EC2 上の Linux コンテナの Active Directory 認証をサポートします。

Linux Core アプリケーションなどの .NET ベースのネットワークアプリケーションは、Active Directory を使用して、ユーザーとサービス間の認証と認可の管理を円滑化することができます。この機能は、Active Directory と統合され、ドメインに参加しているサーバー上で実行されるアプリケーションを設計することで利用できます。しかし、Linux コンテナはドメインに参加できないため、gMSA を使用して実行する Linux コンテナを設定する必要があります。

gMSA で実行される Linux コンテナは、コンテナのホスト Amazon EC2 インスタンスで実行される `credentials-fetcher` デーモンに依存します。つまり、デーモンは Active Directory ドメインコントローラーからも認証情報を取得し、これらの gMSA 認証情報をコンテナインスタンスに転送します。サービスアカウントの詳細については、Microsoft Learn Web サイトの「[Windows コンテナ向け gMSAs の作成](https://learn.microsoft.com/en-us/virtualization/windowscontainers/manage-containers/manage-serviceaccounts)」を参照してください。

## 考慮事項
<a name="linux-gmsa-considerations"></a>

Linux コンテナ向け gMSA を使用する前に、次の点を考慮してください。
+ コンテナが EC2 で実行されている場合は、Windows コンテナおよびLinux コンテナ向け gMSA を使用できます。Fargate で Linux コンテナに gMSA を使用する方法については、[Fargate で Linux コンテナに gMSA を使用する](fargate-linux-gmsa.md) を参照してください。
+ 前提条件を完全に満たすには、ドメインに参加している Windows コンピュータが必要になる場合があります。例えば、PowerShell を使用して Active Directory で gMSA を作成するには、ドメインに参加している Windows コンピュータが必要になる場合があります。RSAT Active Director PowerShell ツールは Windows でのみ使用できます。詳細については、「[Active Directory 管理ツールのインストール](https://docs.aws.amazon.com/directoryservice/latest/admin-guide/ms_ad_install_ad_tools.html)」を参照してください。
+ **ドメインレス gMSA**か**各インスタンスを単一のドメインに結合する**を選択しました。ドメインレス gMSA を使用すると、コンテナインスタンスはドメインに参加せず、インスタンス上の他のアプリケーションは認証情報を使用してドメインにアクセスできなくなり、異なるドメインに参加するタスクを同じインスタンス上で実行できます。

  次に、CredSpec のデータ ストレージを選択し、必要に応じて、ドメインレス gMSA の Active Directory ユーザー認証情報を選択します。

  Amazon ECS は Active Directory の認証情報仕様ファイル (CredSpec) を使用します。このファイルは、gMSA アカウントコンテキストをコンテナに伝達するために使用される gMSA メタデータを含む認証情報仕様ファイルを使用します。CredSpec ファイルを生成し、コンテナインスタンスのオペレーティングシステムに応じて、次の表にある CredSpec ストレージオプションのいずれかに保存します。ドメインレス方式を使用するには、CredSpec ファイル内のオプションのセクションで、コンテナインスタンスのオペレーティングシステムに固有の、次の表の *domainless user credentials* ストレージオプションのいずれかの認証情報を指定できます。    
<a name="gmsa-table"></a>[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/linux-gmsa.html)

## 前提条件
<a name="linux-gmsa-prerequisites"></a>

gMSA を使用する前に、Amazon ECS の Linux コンテナ機能のために必ず以下を完了してください。
+ コンテナがアクセスするリソースを含む Active Directory ドメインを設定します。Amazon ECS は以下の設定をサポートしています。
  + Directory Service Active Directory。Directory Service は、Amazon EC2 でホストされる AWS マネージド Active Directory です。詳細については、「*AWS Directory Service 管理ガイド*」の「[AWS Managed Microsoft AD の開始方法](https://docs.aws.amazon.com/directoryservice/latest/admin-guide/ms_ad_getting_started.html)」を参照してください。
  + オンプレミスの Active Directory。Amazon ECS Linux コンテナインスタンスがドメインに参加できることを確認する必要があります。詳細については、「[AWS Direct Connect](https://docs.aws.amazon.com/whitepapers/latest/aws-vpc-connectivity-options/aws-direct-connect.html)」を参照してください。
+ Active Directory に既存の gMSA アカウントがあります。詳細については、「[Amazon EC2 の Linux コンテナで gMSA を使用する](#linux-gmsa)」を参照してください。
+ Amazon ECS Linux コンテナインスタンスに `credentials-fetcher` デーモンをインストールして実行しています。また、Active Directory で認証するための初期資格情報セットを `credentials-fetcher` デーモンに追加しました。
**注記**  
`credentials-fetcher` デーモンは、Amazon Linux 2023 および Fedora 37 以降でのみ使用できます。デーモン は Amazon Linux 2 では使用できません。詳細については、GitHub の「[aws/credentials-fetcher](https://github.com/aws/credentials-fetcher)」を参照してください。
+ Active Directory で認証するための `credentials-fetcher` デーモンの認定情報を設定します。認証情報は、gMSA アカウントにアクセスできる Active Directory セキュリティグループのメンバーである必要があります。[インスタンスをドメインに参加させるか、ドメインレス gMSA を使用するかを決定します。](#linux-gmsa-initial-creds) には複数のオプションがあります。
+ 必須の IAM アクセス権限を追加しました。必要な権限は、初期認証情報と認証情報の仕様の保存に選択した方法によって異なります。
  + 初期認証情報に*ドメインレス gMSA* を使用する場合は、タスク実行ロールに AWS Secrets Manager の IAM アクセス許可が必要です。
  + 認証情報の仕様を SSM Parameter Store に保存する場合は、タスク実行ロールで Amazon EC2 Systems Manager Parameter Store に対する IAM 許可が必要です。
  + 認証情報の仕様を Amazon S3 で保存する場合は、タスク実行ロールで Amazon Simple Storage Service の IAM 許可が必要です。

## Amazon ECS での gMSA 対応の Linux コンテナの設定
<a name="linux-gmsa-setup"></a>
<a name="linux-gmsa-setup-infra"></a>
**インフラストラクチャを準備する**  
次のステップは、考慮事項と 1 回実行される設定です。これらのステップを完了したら、コンテナインスタンスの作成を自動化して、この設定を再利用できます。

初期認証情報の提供方法を決定し、再利用可能な EC2 起動テンプレートで EC2 ユーザーデータを設定して、`credentials-fetcher` デーモンをインストールします。

1. <a name="linux-gmsa-initial-creds"></a>

**インスタンスをドメインに参加させるか、ドメインレス gMSA を使用するかを決定します。**
   + <a name="linux-gmsa-initial-join"></a>

**EC2 インスタンスを Active Directory ドメインに参加させる**

     
     + <a name="linux-gmsa-initial-join-userdata"></a>

**ユーザーデータを使用してインスタンスを参加させる**

       Active Directory ドメインを EC2 起動テンプレートの EC2 ユーザーデータに参加させるステップを追加します。複数の Amazon EC2 Auto Scaling グループが同じ起動テンプレートを使用できます。

       Fedora ドキュメントの「[Active Directory または FreeIPA ドメインへの参加](https://docs.fedoraproject.org/en-US/quick-docs/join-active-directory-freeipa/)」のこれらのステップを使用できます。
   + <a name="linux-gmsa-initial-domainless"></a>

**ドメインレス gMSA 用に Active Directory ユーザーを作成する**

     `credentials-fetcher` デーモンには、*ドメインレス gMSA* と呼ばれる機能があります。この機能にはドメインが必要ですが、EC2 インスタンスをドメインに参加させる必要はありません。ドメインレス gMSA を使用すると、コンテナインスタンスはドメインに参加せず、インスタンス上の他のアプリケーションは認証情報を使用してドメインにアクセスできなくなり、異なるドメインに参加するタスクを同じインスタンス上で実行できます。代わりに、CredSpec ファイルの AWS Secrets Manager にシークレットの名前を指定します。シークレットには、ユーザー名、パスワード、ログイン先のドメインが含まれている必要があります。

     この機能はサポートされており、Linux および Windows コンテナで使用できます。

     この機能は *gMSA support for non-domain-joined container hosts* 機能に似ています。Windows の機能の詳細については、Microsoft Learn ウェブサイトの「[gMSA アーキテクチャと改善](https://learn.microsoft.com/en-us/virtualization/windowscontainers/manage-containers/manage-serviceaccounts#gmsa-architecture-and-improvements)」を参照してください。

     1. Active Directory ドメインでユーザーを作成します。Active Directory のユーザーは、タスクで使用する gMSA サービスアカウントにアクセスするための許可を持っている必要があります。

     1. Active Directory でユーザーを作成した後、AWS Secrets Manager でシークレットを作成します。詳細については、「[AWS Secrets Manager シークレットを作成する](https://docs.aws.amazon.com/secretsmanager/latest/userguide/create_secret.html)」を参照してください。

     1. ユーザーのユーザー名、パスワード、ドメインを、それぞれ `username`、`password`、`domainName` と呼ばれる JSON キーと値のペアに入力します。

        ```
        {"username":"username","password":"passw0rd", "domainName":"example.com"}
        ```

     1. サービスアカウントの CredSpec ファイルに構成を追加します。追加の `HostAccountConfig` には、Secrets Manager のシークレットの Amazon リソースネーム (ARN) が含まれています。

        Windows では、`PluginGUID` は次のスニペットの例の GUID と一致する必要があります。Linux では、`PluginGUID` は無視されます。`MySecret` の例を、シークレットの Amazon リソースネーム (ARN) に置き換えます。

        ```
            "ActiveDirectoryConfig": {
                "HostAccountConfig": {
                    "PortableCcgVersion": "1",
                    "PluginGUID": "{859E1386-BDB4-49E8-85C7-3070B13920E1}",
                    "PluginInput": {
                        "CredentialArn": "arn:aws:secretsmanager:aws-region:111122223333:secret:MySecret"
                    }
                }
        ```

     1. *ドメインレス gMSA* 機能には、タスク実行ロールの追加のアクセス許可が必要です。ステップ [(オプション) ドメインレス gMSA シークレット](#linux-gmsa-domainless-secret) に従います。

1. <a name="linux-gmsa-install"></a>

**インスタンスを設定し、`credentials-fetcher` デーモンをインストールする**

   EC2 起動テンプレートでユーザーデータスクリプトを使用して `credentials-fetcher` デーモンをインストールできます。次の例は、2 種類のユーザーデータ (`cloud-config` YAML または bash スクリプト) を示しています。これらの例は、Amazon Linux 2023 (AL2023) についてのものです。`MyCluster` を、これらのインスタンスが参加する Amazon ECS クラスターの名前に置き換えます。
   + <a name="linux-gmsa-install-yaml"></a>

**`cloud-config` YAML**

     ```
     Content-Type: text/cloud-config
     package_reboot_if_required: true
     packages:
       # prerequisites
       - dotnet
       - realmd
       - oddjob
       - oddjob-mkhomedir
       - sssd
       - adcli
       - krb5-workstation
       - samba-common-tools
       # https://github.com/aws/credentials-fetcher gMSA credentials management for containers
       - credentials-fetcher
     write_files:
     # configure the ECS Agent to join your cluster.
     # replace MyCluster with the name of your cluster.
     - path: /etc/ecs/ecs.config
       owner: root:root
       permissions: '0644'
       content: |
         ECS_CLUSTER=MyCluster
         ECS_GMSA_SUPPORTED=true
     runcmd:
     # start the credentials-fetcher daemon and if it succeeded, make it start after every reboot
     - "systemctl start credentials-fetcher"
     - "systemctl is-active credentials-fetcher && systemctl enable credentials-fetcher"
     ```
   + <a name="linux-gmsa-install-userdata"></a>

**bash スクリプト**

     bash スクリプトに慣れていて、`/etc/ecs/ecs.config` に書き込む変数が複数ある場合は、次の `heredoc` 形式を使用します。この形式は **cat** で始まる行と `EOF` の間のすべてを設定ファイルに書き込みます。

     ```
     #!/usr/bin/env bash
     set -euxo pipefail
     
     # prerequisites
     timeout 30 dnf install -y dotnet realmd oddjob oddjob-mkhomedir sssd adcli krb5-workstation samba-common-tools
     # install https://github.com/aws/credentials-fetcher gMSA credentials management for containers
     timeout 30 dnf install -y credentials-fetcher
     
     # start credentials-fetcher
     systemctl start credentials-fetcher
     systemctl is-active credentials-fetcher && systemctl enable credentials-fetcher
     
     cat <<'EOF' >> /etc/ecs/ecs.config
     ECS_CLUSTER=MyCluster
     ECS_GMSA_SUPPORTED=true
     EOF
     ```

   `/etc/ecs/ecs.config` で設定できる `credentials-fetcher` デーモンのオプションの設定変数があります。YAML ブロック内のユーザーデータに変数を設定するか、`heredoc`前の例と同様に変数を設定することをお勧めします。これにより、1 つのファイルを複数回編集した場合に発生する、部分的な構成に関する問題を回避できます。ECS エージェントの設定の詳細については、GitHub の「[Amazon ECS コンテナエージェント](https://github.com/aws/amazon-ecs-agent/blob/master/README.md#environment-variables)」を参照してください。
   + オプションで、`credentials-fetcher` デーモン設定を変更してソケットを別の場所に移動する場合は、この変数 `CREDENTIALS_FETCHER_HOST` を使用できます。

**許可とシークレットの設定**  
各アプリケーションおよび各タスク定義のために、次のステップを 1 回実行します。最小特権を認めるというベストプラクティスに従い、ポリシーで使用されるアクセス許可を絞り込むことをお勧めします。これにより、各タスクは必要なシークレットのみを読み取れます。

1. <a name="linux-gmsa-domainless-secret"></a>

**(オプション) ドメインレス gMSA シークレット**

   インスタンスがドメインに参加していないドメインレス方式を使用する場合は、次のステップに従います。

   次の権限をインラインポリシーとしてタスク実行 IAM ロールに追加する必要があります。これにより、`credentials-fetcher` デーモンが Secrets Manager シークレットにアクセスできるようになります。`MySecret` の例を、`Resource` リスト内のシークレットの Amazon リソースネーム (ARN) に置き換えます。

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": [
                   "secretsmanager:GetSecretValue"
               ],
               "Resource": "arn:aws:secretsmanager:us-east-1:123456789012:secret:my-secret-AbCdEf"
           }
       ]
   }
   ```

------
**注記**  
独自の KMS キーを使用してシークレットを暗号化する場合は、必要な許可をこのロールに追加し、このロールを AWS KMS キーポリシーに追加する必要があります。

1. 

**SSM Parameter Store または S3 を使用して CredSpec を保存するかどうかを決定する**

   Amazon ECS では、タスク定義の `credentialSpecs` フィールドでファイルパスを参照する次の方法がサポートされています。

   インスタンスを単一のドメインに参加させる場合は、文字列内の ARN の先頭にプレフィックス `credentialspec:` を使用します。ドメインレス gMSA を使用する場合は、次に `credentialspecdomainless:` を使用します。

   CredSpec の詳細については、「[認証情報仕様ファイル](#linux-gmsa-credentialspec)」を参照してください。
   + <a name="linux-gmsa-credspec-s3"></a>

**Amazon S3 バケット**

     認証情報の仕様を Amazon S3 バケットに追加します。次に、タスク定義の `credentialSpecs` フィールドで Amazon S3 バケットの Amazon リソースネーム (ARN) を参照します。

     ```
     {
         "family": "",
         "executionRoleArn": "",
         "containerDefinitions": [
             {
                 "name": "",
                 ...
                 "credentialSpecs": [
                     "credentialspecdomainless:arn:aws:s3:::${BucketName}/${ObjectName}"
                 ],
                 ...
             }
         ],
         ...
     }
     ```

     タスクに S3 バケットへのアクセスを許可するには、次のアクセス許可をインラインポリシーとして Amazon ECS タスク実行 IAM ロールに追加します。

------
#### [ JSON ]

****  

     ```
     {
         "Version":"2012-10-17",		 	 	 
         "Statement": [
             {
                 "Sid": "VisualEditor",
                 "Effect": "Allow",
                 "Action": [
                     "s3:Get*",
                     "s3:List*"
                 ],
                 "Resource": [
                     "arn:aws:s3:::amzn-s3-demo-bucket",
                     "arn:aws:s3:::amzn-s3-demo-bucket/{object}"
                 ]
             }
         ]
     }
     ```

------
   + <a name="linux-gmsa-credspec-ssm"></a>

**SSM パラメータストアパラメータ**

     SSM Parameter Store パラメータに認証情報仕様を追加します。タスク定義の `credentialSpecs` フィールドで SSM パラメータストアパラメータの Amazon リソースネーム (ARN) を参照します。

     ```
     {
         "family": "",
         "executionRoleArn": "",
         "containerDefinitions": [
             {
                 "name": "",
                 ...
                 "credentialSpecs": [
                     "credentialspecdomainless:arn:aws:ssm:aws-region:111122223333:parameter/parameter_name"
                 ],
                 ...
             }
         ],
         ...
     }
     ```

     タスクに SSM Parameter Store パラメータへのアクセスを許可するには、次のアクセス許可をインラインポリシーとして Amazon ECS タスク実行 IAM ロールに追加します。

------
#### [ JSON ]

****  

     ```
     {
         "Version":"2012-10-17",		 	 	 
         "Statement": [
             {
                 "Effect": "Allow",
                 "Action": [
                     "ssm:GetParameters"
                 ],
                 "Resource": "arn:aws:ssm:us-east-1:123456789012:parameter/my-parameter"
             }
         ]
     }
     ```

------

## 認証情報仕様ファイル
<a name="linux-gmsa-credentialspec"></a>

Amazon ECS は Active Directory の認証情報仕様ファイル (*CredSpec*) を使用します。このファイルには、gMSA アカウントコンテキストを Linux コンテナに伝達するために使用される gMSA メタデータが含まれています。CredSpec を生成し、タスク定義の `credentialSpecs` フィールドで参照します。CredSpec ファイルにはシークレットは含まれていません。

次は、CredSpec ファイルの例です。

```
{
    "CmsPlugins": [
        "ActiveDirectory"
    ],
    "DomainJoinConfig": {
        "Sid": "S-1-5-21-2554468230-2647958158-2204241789",
        "MachineAccountName": "WebApp01",
        "Guid": "8665abd4-e947-4dd0-9a51-f8254943c90b",
        "DnsTreeName": "example.com",
        "DnsName": "example.com",
        "NetBiosName": "example"
    },
    "ActiveDirectoryConfig": {
        "GroupManagedServiceAccounts": [
            {
                "Name": "WebApp01",
                "Scope": "example.com"
            }
        ],
        "HostAccountConfig": {
            "PortableCcgVersion": "1",
            "PluginGUID": "{859E1386-BDB4-49E8-85C7-3070B13920E1}",
            "PluginInput": {
                "CredentialArn": "arn:aws:secretsmanager:aws-region:111122223333:secret:MySecret"
            }
        }
    }
}
```
<a name="linux-gmsa-credentialspec-create"></a>
**「CredSpec」の作成**  
CredSpec を作成するには、ドメインに参加している Windows コンピューター上の CredSpec PowerShell モジュールを使用します。Microsoft Learn Web サイトの「[認証情報の仕様を作成する](https://learn.microsoft.com/en-us/virtualization/windowscontainers/manage-containers/manage-serviceaccounts#create-a-credential-spec)」のステップに従います。