

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 設定服務帳戶的 IAM 角色
<a name="set-up-irsa"></a>

透過服務帳戶的 IAM 角色，您可以產生 IAM 角色與 Kubernetes 服務帳戶的關聯。然後，此服務帳戶可以為使用該服務帳戶的任何 Pod 中的容器提供 AWS 許可。如需詳細資訊，請參閱[服務帳戶的 IAM 角色](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html)。

服務帳戶的 IAM 角色也稱為*服務角色*。

在 Amazon Managed Service for Prometheus 中，使用服務角色可協助您取得在 Amazon Managed Service for Prometheus、Prometheus 伺服器和 Grafana 伺服器之間授權和驗證所需的角色。

**先決條件**

本頁面上的程序需要您已安裝 AWS CLI 和 EKSCTL 命令列界面。

## 自 Amazon EKS 叢集設定指標擷取作業的服務角色
<a name="set-up-irsa-ingest"></a>

若要在 Amazon EKS 叢集設定服務角色以讓 Amazon Managed Service for Prometheus 自 Prometheus 伺服器擷取指標，您必須登入具有下列許可的帳戶：
+ `iam:CreateRole`
+ `iam:CreatePolicy`
+ `iam:GetRole`
+ `iam:AttachRolePolicy`
+ `iam:GetOpenIDConnectProvider`

**設定 Amazon Managed Service for Prometheus 擷取作業的服務角色**

1. 建立名為 `createIRSA-AMPIngest.sh` 且具有下列內容的檔案。將 `<my_amazon_eks_clustername>` 替換為您的叢集名稱，並將 `<my_prometheus_namespace>` 替換為 Prometheus 命名空間。

   ```
   #!/bin/bash -e
   CLUSTER_NAME=<my_amazon_eks_clustername>
   SERVICE_ACCOUNT_NAMESPACE=<my_prometheus_namespace>
   AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query "Account" --output text)
   OIDC_PROVIDER=$(aws eks describe-cluster --name $CLUSTER_NAME --query "cluster.identity.oidc.issuer" --output text | sed -e "s/^https:\/\///")
   SERVICE_ACCOUNT_AMP_INGEST_NAME=amp-iamproxy-ingest-service-account
   SERVICE_ACCOUNT_IAM_AMP_INGEST_ROLE=amp-iamproxy-ingest-role
   SERVICE_ACCOUNT_IAM_AMP_INGEST_POLICY=AMPIngestPolicy
   #
   # Set up a trust policy designed for a specific combination of K8s service account and namespace to sign in from a Kubernetes cluster which hosts the OIDC Idp.
   #
   cat <<EOF > TrustPolicy.json
   {
     "Version": "2012-10-17",		 	 	 
     "Statement": [
       {
         "Effect": "Allow",
         "Principal": {
           "Federated": "arn:aws:iam::${AWS_ACCOUNT_ID}:oidc-provider/${OIDC_PROVIDER}"
         },
         "Action": "sts:AssumeRoleWithWebIdentity",
         "Condition": {
           "StringEquals": {
             "${OIDC_PROVIDER}:sub": "system:serviceaccount:${SERVICE_ACCOUNT_NAMESPACE}:${SERVICE_ACCOUNT_AMP_INGEST_NAME}"
           }
         }
       }
     ]
   }
   EOF
   #
   # Set up the permission policy that grants ingest (remote write) permissions for all AMP workspaces
   #
   cat <<EOF > PermissionPolicyIngest.json
   {
     "Version": "2012-10-17",		 	 	 
      "Statement": [
          {"Effect": "Allow",
           "Action": [
              "aps:RemoteWrite", 
              "aps:GetSeries", 
              "aps:GetLabels",
              "aps:GetMetricMetadata"
           ], 
           "Resource": "*"
         }
      ]
   }
   EOF
   
   function getRoleArn() {
     OUTPUT=$(aws iam get-role --role-name $1 --query 'Role.Arn' --output text 2>&1)
   
     # Check for an expected exception
     if [[ $? -eq 0 ]]; then
       echo $OUTPUT
     elif [[ -n $(grep "NoSuchEntity" <<< $OUTPUT) ]]; then
       echo ""
     else
       >&2 echo $OUTPUT
       return 1
     fi
   }
   
   #
   # Create the IAM Role for ingest with the above trust policy
   #
   SERVICE_ACCOUNT_IAM_AMP_INGEST_ROLE_ARN=$(getRoleArn $SERVICE_ACCOUNT_IAM_AMP_INGEST_ROLE)
   if [ "$SERVICE_ACCOUNT_IAM_AMP_INGEST_ROLE_ARN" = "" ]; 
   then
     #
     # Create the IAM role for service account
     #
     SERVICE_ACCOUNT_IAM_AMP_INGEST_ROLE_ARN=$(aws iam create-role \
     --role-name $SERVICE_ACCOUNT_IAM_AMP_INGEST_ROLE \
     --assume-role-policy-document file://TrustPolicy.json \
     --query "Role.Arn" --output text)
     #
     # Create an IAM permission policy
     #
     SERVICE_ACCOUNT_IAM_AMP_INGEST_ARN=$(aws iam create-policy --policy-name $SERVICE_ACCOUNT_IAM_AMP_INGEST_POLICY \
     --policy-document file://PermissionPolicyIngest.json \
     --query 'Policy.Arn' --output text)
     #
     # Attach the required IAM policies to the IAM role created above
     #
     aws iam attach-role-policy \
     --role-name $SERVICE_ACCOUNT_IAM_AMP_INGEST_ROLE \
     --policy-arn $SERVICE_ACCOUNT_IAM_AMP_INGEST_ARN  
   else
       echo "$SERVICE_ACCOUNT_IAM_AMP_INGEST_ROLE_ARN IAM role for ingest already exists"
   fi
   echo $SERVICE_ACCOUNT_IAM_AMP_INGEST_ROLE_ARN
   #
   # EKS cluster hosts an OIDC provider with a public discovery endpoint.
   # Associate this IdP with AWS IAM so that the latter can validate and accept the OIDC tokens issued by Kubernetes to service accounts.
   # Doing this with eksctl is the easier and best approach.
   #
   eksctl utils associate-iam-oidc-provider --cluster $CLUSTER_NAME --approve
   ```

1. 請輸入下列命令，賦予指令碼必要權限。

   ```
   chmod +x createIRSA-AMPIngest.sh
   ```

1. 執行指令碼。

## 設定服務帳戶的 IAM 角色，以查詢指標
<a name="set-up-irsa-query"></a>

若要設定服務帳戶的 IAM 角色 (服務角色) 以啟用從 Amazon Managed Service for Prometheus 工作區查詢指標，您必須登入具有下列許可的帳戶：
+ `iam:CreateRole`
+ `iam:CreatePolicy`
+ `iam:GetRole`
+ `iam:AttachRolePolicy`
+ `iam:GetOpenIDConnectProvider`

**設定服務角色以查詢 Amazon Managed Service for Prometheus 指標；**

1. 建立名為 `createIRSA-AMPQuery.sh` 且具有下列內容的檔案。將 `<my_amazon_eks_clustername>` 替換您的叢集名稱，並將 <my\$1prometheus\$1namespace> 替換為 Prometheus 命名空間。

   ```
   #!/bin/bash -e
   CLUSTER_NAME=<my_amazon_eks_clustername>
   SERVICE_ACCOUNT_NAMESPACE=<my_prometheus_namespace>
   AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query "Account" --output text)
   OIDC_PROVIDER=$(aws eks describe-cluster --name $CLUSTER_NAME --query "cluster.identity.oidc.issuer" --output text | sed -e "s/^https:\/\///")
   SERVICE_ACCOUNT_AMP_QUERY_NAME=amp-iamproxy-query-service-account
   SERVICE_ACCOUNT_IAM_AMP_QUERY_ROLE=amp-iamproxy-query-role
   SERVICE_ACCOUNT_IAM_AMP_QUERY_POLICY=AMPQueryPolicy
   #
   # Setup a trust policy designed for a specific combination of K8s service account and namespace to sign in from a Kubernetes cluster which hosts the OIDC Idp.
   #
   cat <<EOF > TrustPolicy.json
   {
     "Version": "2012-10-17",		 	 	 
     "Statement": [
       {
         "Effect": "Allow",
         "Principal": {
           "Federated": "arn:aws:iam::${AWS_ACCOUNT_ID}:oidc-provider/${OIDC_PROVIDER}"
         },
         "Action": "sts:AssumeRoleWithWebIdentity",
         "Condition": {
           "StringEquals": {
             "${OIDC_PROVIDER}:sub": "system:serviceaccount:${SERVICE_ACCOUNT_NAMESPACE}:${SERVICE_ACCOUNT_AMP_QUERY_NAME}"
           }
         }
       }
     ]
   }
   EOF
   #
   # Set up the permission policy that grants query permissions for all AMP workspaces
   #
   cat <<EOF > PermissionPolicyQuery.json
   {
     "Version": "2012-10-17",		 	 	 
      "Statement": [
          {"Effect": "Allow",
           "Action": [
              "aps:QueryMetrics",
              "aps:GetSeries", 
              "aps:GetLabels",
              "aps:GetMetricMetadata"
           ], 
           "Resource": "*"
         }
      ]
   }
   EOF
   
   function getRoleArn() {
     OUTPUT=$(aws iam get-role --role-name $1 --query 'Role.Arn' --output text 2>&1)
   
     # Check for an expected exception
     if [[ $? -eq 0 ]]; then
       echo $OUTPUT
     elif [[ -n $(grep "NoSuchEntity" <<< $OUTPUT) ]]; then
       echo ""
     else
       >&2 echo $OUTPUT
       return 1
     fi
   }
   
   #
   # Create the IAM Role for query with the above trust policy
   #
   SERVICE_ACCOUNT_IAM_AMP_QUERY_ROLE_ARN=$(getRoleArn $SERVICE_ACCOUNT_IAM_AMP_QUERY_ROLE)
   if [ "$SERVICE_ACCOUNT_IAM_AMP_QUERY_ROLE_ARN" = "" ]; 
   then
     #
     # Create the IAM role for service account
     #
     SERVICE_ACCOUNT_IAM_AMP_QUERY_ROLE_ARN=$(aws iam create-role \
     --role-name $SERVICE_ACCOUNT_IAM_AMP_QUERY_ROLE \
     --assume-role-policy-document file://TrustPolicy.json \
     --query "Role.Arn" --output text)
     #
     # Create an IAM permission policy
     #
     SERVICE_ACCOUNT_IAM_AMP_QUERY_ARN=$(aws iam create-policy --policy-name $SERVICE_ACCOUNT_IAM_AMP_QUERY_POLICY \
     --policy-document file://PermissionPolicyQuery.json \
     --query 'Policy.Arn' --output text)
     #
     # Attach the required IAM policies to the IAM role create above
     #
     aws iam attach-role-policy \
     --role-name $SERVICE_ACCOUNT_IAM_AMP_QUERY_ROLE \
     --policy-arn $SERVICE_ACCOUNT_IAM_AMP_QUERY_ARN  
   else
       echo "$SERVICE_ACCOUNT_IAM_AMP_QUERY_ROLE_ARN IAM role for query already exists"
   fi
   echo $SERVICE_ACCOUNT_IAM_AMP_QUERY_ROLE_ARN
   #
   # EKS cluster hosts an OIDC provider with a public discovery endpoint.
   # Associate this IdP with AWS IAM so that the latter can validate and accept the OIDC tokens issued by Kubernetes to service accounts.
   # Doing this with eksctl is the easier and best approach.
   #
   eksctl utils associate-iam-oidc-provider --cluster $CLUSTER_NAME --approve
   ```

1. 請輸入下列命令，賦予指令碼必要權限。

   ```
   chmod +x createIRSA-AMPQuery.sh
   ```

1. 執行指令碼。