

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

# `AWSSupport-SetupK8sApiProxyForEKS`
<a name="automation-awssupport-setupk8sapiproxyforeks"></a>

 **Description** 

**AWSSupport-SetupK8sApiProxyForEKS** 自動化 Runbook 提供建立 函數的方法，該 AWS Lambda 函數可做為對 Amazon Elastic Kubernetes Service 叢集端點進行控制平面 API 呼叫的代理。它可作為 Runbook 的建置區塊，需要進行控制平面 API 呼叫，以自動化任務並疑難排解 Amazon EKS 叢集的問題。

**重要**  
此自動化建立的所有資源都會加上標籤，以便輕鬆找到。使用的標籤為：  
 `AWSSupport-SetupK8sApiProxyForEKS`：true 

**注意**  
自動化是協助程式 Runbook，無法做為獨立 Runbook 執行。它被調用為 Runbook 的子自動化，需要控制平面 API 呼叫 Amazon EKS 叢集。
請務必在使用後執行`Cleanup`操作，以避免產生不必要的成本。

**文件類型**

 自動化

**擁有者**

Amazon

**平台**

Linux

**參數**
+ AutomationAssumeRole

  類型：字串

  描述：（選用） 允許 Systems Manager Automation 代表您執行動作的 (IAM) 角色的 AWS Identity and Access Management Amazon Resource Name (ARN)。如果未指定角色，Systems Manager Automation 會使用啟動此 Runbook 之使用者的許可。
+ ClusterName

  類型：字串

  描述：（必要） Amazon Elastic Kubernetes Service 叢集的名稱。
+ 作業

  類型：字串

  描述：（必要） 要執行的操作： 在帳戶中`Setup`佈建 Lambda 函數， `Cleanup`會取消佈建在設定階段中建立的資源。

  允許的值： `Setup` \$1 `Cleanup`

  預設：設定
+ LambdaRoleArn

  類型：字串

  描述：（選用） 允許函數 AWS Lambda 存取所需 AWS 服務和資源的 IAM 角色 ARN。如果未指定角色，此 Systems Manager Automation 會在您的帳戶中為 Lambda 建立一個 `Automation-K8sProxy-Role-<ExecutionId>` IAM 角色，其名稱包含 受管政策： `AWSLambdaBasicExecutionRole`和 `AWSLambdaVPCAccessExecutionRole`。

 **如何運作？** 

 Runbook 會執行下列步驟：
+ 驗證自動化是否以子執行的形式執行。做為獨立 Runbook 調用時， Runbook 將無法運作，因為它不會自行執行任何有意義的工作。
+ 檢查指定叢集之代理 Lambda 函數的現有 CloudFormation 堆疊。
  + 如果堆疊存在，則會重複使用現有的基礎設施，而不是重新建立它。
  + 使用標籤來維護參考計數器，以確保如果相同叢集的另一個 Runbook 重複使用基礎設施，則 Runbook 不會將其刪除。
+ 執行為調用指定的操作類型 (`Setup`/`Cleanup`)：
  + **設定：**建立或描述現有的資源。

    **清除：**如果任何其他 Runbook 未使用基礎設施，則移除佈建的資源。

 **所需的 IAM 許可** 

`AutomationAssumeRole` 參數需要下列` LambdaRoleArn`未傳遞的許可：
+  `cloudformation:CreateStack` 
+  `cloudformation:DescribeStacks` 
+  `cloudformation:DeleteStack` 
+  `cloudformation:UpdateStack` 
+  `ec2:CreateNetworkInterface` 
+  `ec2:DescribeNetworkInterfaces` 
+  `ec2:DescribeRouteTables` 
+  `ec2:DescribeSecurityGroups` 
+  `ec2:DescribeSubnets` 
+  `ec2:DescribeVpcs` 
+  `ec2:DeleteNetworkInterface` 
+  `eks:DescribeCluster` 
+  `lambda:CreateFunction` 
+  `lambda:DeleteFunction` 
+  `lambda:ListTags` 
+  `lambda:GetFunction` 
+  `lambda:ListTags` 
+  `lambda:TagResource` 
+  `lambda:UntagResource` 
+  `lambda:UpdateFunctionCode` 
+  `logs:CreateLogGroup` 
+  `logs:PutRetentionPolicy` 
+  `logs:TagResource` 
+  `logs:UntagResource` 
+  `logs:DescribeLogGroups` 
+  `logs:DescribeLogStreams` 
+  `logs:ListTagsForResource` 
+  `iam:CreateRole` 
+  `iam:AttachRolePolicy` 
+  `iam:DetachRolePolicy` 
+  `iam:PassRole` 
+  `iam:GetRole` 
+  `iam:DeleteRole` 
+  `iam:TagRole` 
+  `iam:UntagRole` 
+  `tag:GetResources` 
+  `tag:TagResources` 

提供 `LambdaRoleArn` 時，自動化不需要建立角色，而且可以排除下列許可：
+  `iam:CreateRole` 
+  `iam:DeleteRole` 
+  `iam:TagRole` 
+  `iam:UntagRole` 
+  `iam:AttachRolePolicy` 
+  `iam:DetachRolePolicy` 

以下是範例政策，示範`LambdaRoleArn`未傳遞 ` AutomationAssumeRole` 時所需的許可：

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

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Action": [
                "tag:GetResources",
                "tag:TagResources",
                "ec2:CreateNetworkInterface",
                "ec2:DescribeNetworkInterfaces",
                "ec2:DescribeRouteTables",
                "ec2:DescribeSecurityGroups",
                "ec2:DescribeSubnets",
                "ec2:DescribeVpcs",
                "ec2:DeleteNetworkInterface",
                "eks:DescribeCluster",
                "iam:GetRole",
                "cloudformation:DescribeStacks",
                "logs:DescribeLogGroups",
                "logs:DescribeLogStreams",
                "lambda:GetFunction",
                "lambda:ListTags",
                "logs:ListTagsForResource"
            ],
            "Resource": "*",
            "Effect": "Allow",
            "Sid": "AllowActionsWithoutConditions"
        },
        {
            "Condition": {
                "StringEquals": {
                    "aws:RequestTag/AWSSupport-SetupK8sApiProxyForEKS": "true"
                }
            },
            "Action": "iam:CreateRole",
            "Resource": [
                "arn:aws:iam::111122223333:role/Automation-K8sProxy*"
            ],
            "Effect": "Allow",
            "Sid": "AllowCreateRoleWithRequiredTag"
        },
        {
            "Condition": {
                "StringEquals": {
                    "aws:ResourceTag/AWSSupport-SetupK8sApiProxyForEKS": "true"
                }
            },
            "Action": [
                "iam:DeleteRole",
                "iam:TagRole",
                "iam:UntagRole"
            ],
            "Resource": [
                "arn:aws:iam::111122223333:role/Automation-K8sProxy*"
            ],
            "Effect": "Allow",
            "Sid": "IAMActions"
        },
        {
            "Condition": {
                "StringEquals": {
                    "aws:ResourceTag/AWSSupport-SetupK8sApiProxyForEKS": "true"
                },
                "StringLike": {
                    "iam:PolicyARN": [
                        "arn:aws:iam::111122223333:policy/service-role/AWSLambdaBasicExecutionRole",
                        "arn:aws:iam::111122223333:policy/service-role/AWSLambdaVPCAccessExecutionRole"
                    ]
                }
            },
            "Action": [
                "iam:AttachRolePolicy",
                "iam:DetachRolePolicy"
            ],
            "Resource": [
                "arn:aws:iam::111122223333:role/Automation-K8sProxy*"
            ],
            "Effect": "Allow",
            "Sid": "AttachRolePolicy"
        },
        {
            "Condition": {
                "StringEquals": {
                    "aws:ResourceTag/AWSSupport-SetupK8sApiProxyForEKS": "true"
                }
            },
            "Action": [
                "lambda:CreateFunction",
                "lambda:DeleteFunction",
                "lambda:TagResource",
                "lambda:UntagResource",
                "lambda:UpdateFunctionCode"
            ],
            "Resource": "arn:aws:lambda:us-east-1:111122223333:function:Automation-K8sProxy*",
            "Effect": "Allow",
            "Sid": "LambdaActions"
        },
        {
            "Condition": {
                "StringEquals": {
                    "aws:ResourceTag/AWSSupport-SetupK8sApiProxyForEKS": "true"
                }
            },
            "Action": [
                "cloudformation:CreateStack",
                "cloudformation:DeleteStack",
                "cloudformation:UpdateStack"
            ],
            "Resource": "arn:aws:cloudformation:us-east-1:111122223333:stack/AWSSupport-SetupK8sApiProxyForEKS*",
            "Effect": "Allow",
            "Sid": "CloudFormationActions"
        },
        {
            "Condition": {
                "StringEquals": {
                    "aws:ResourceTag/AWSSupport-SetupK8sApiProxyForEKS": "true"
                }
            },
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents",
                "logs:PutRetentionPolicy",
                "logs:TagResource",
                "logs:UntagResource"
            ],
            "Resource": [
                "arn:aws:logs:us-east-1:111122223333:log-group:/aws/lambda/Automation-K8sProxy*",
                "arn:aws:logs:us-east-1:111122223333:log-group:/aws/lambda/Automation-K8sProxy*:*"
            ],
            "Effect": "Allow",
            "Sid": "LogsActions"
        },
        {
            "Condition": {
                "StringLikeIfExists": {
                    "iam:PassedToService": "lambda.amazonaws.com"
                }
            },
            "Action": [
                "iam:PassRole"
            ],
            "Resource": [
                "arn:aws:iam::111122223333:role/Automation-K8sProxy-Role*"
            ],
            "Effect": "Allow",
            "Sid": "PassRoleToLambda"
        }
    ]
}
```

------

 如果傳遞 `LambdaRoleArn` ，請確保其已為公有叢集連接 [ AWSLambdaBasicExecutionRole ](https://console.aws.amazon.com/iam/home?region=us-east-1#/policies/details/arn%3Aaws%3Aiam%3A%3Aaws%3Apolicy%2Fservice-role%2FAWSLambdaBasicExecutionRole) 政策，並為私有叢集連接 [ AWSLambdaVPCAccessExecutionRole](https://console.aws.amazon.com/iam/home?region=us-east-1#/policies/details/arn%3Aaws%3Aiam%3A%3Aaws%3Apolicy%2Fservice-role%2FAWSLambdaVPCAccessExecutionRole)。

 **建立的資源** 

`Setup` 操作期間會建立下列資源：

1. AWS Lambda 函數

1. IAM 角色：如果未提供，則為 Lambda 執行角色。

1. CloudWatch Log Group (Lambda Logs)

 *Lambda 函數和執行角色會保留，直到執行`Cleanup`操作為止。Lambda 日誌群組將保留 30 天或直到手動刪除為止。*

 **指示** 

Runbook 是一種協助程式公用程式，旨在從其他 Runbook 中作為子自動化執行。它有助於建立基礎設施，讓父系 Runbook 進行 Amazon EKS K8s 控制平面 API 呼叫。若要使用 Runbook，您可以從父系自動化的內容中遵循下列步驟。

1. **設定階段**：從 Runbook 使用` aws:executeAutomation`動作操作調用自動化，該操作想要在操作設為 的情況下進行 Amazon EKS K8s 控制平面 API 呼叫`Setup`。

   輸入參數的範例：

   ```
      {
        "AutomationAssumeRole": "<role-arn>",
        "ClusterName": "<eks-cluster-name>",
        "Operation": "Setup"
      }
   ```

   `aws:executeAutomation` 步驟的輸出將包含代理 Lambda 函數的 ARN。

1. **使用 Lambda Proxy**：使用 `boto3`` Lambda.Client.invoke(...)`與 API 呼叫路徑和承載字符的清單，在`aws:executeScript`動作內叫用 Lambda 函數。Lambda 函數將傳遞承載字符作為授權標頭的一部分，以對指定的路徑執行 HTTP `GET`呼叫。

   Lambda 調用事件的範例：

   ```
      {
          "ApiCalls": ["/api/v1/pods/", ...],
          "BearerToken": "..."
      }
   ```
**注意**  
承載字符必須產生為父系自動化指令碼的一部分。您需要確保執行父系 Runbook 的委託人具有指定 Amazon EKS 叢集的唯讀許可。

1. **清除階段**：從 Runbook 使用` aws:executeAutomation`動作操作調用自動化，該操作想要在操作設為 的情況下進行 Amazon EKS K8s 控制平面 API 呼叫`Cleanup`。

   輸入參數的範例：

   ```
      {
        "AutomationAssumeRole": "<role-arn>",
        "ClusterName": "<eks-cluster-name>",
        "Operation": "Cleanup"
      }
   ```

 **自動化步驟** 

1.  **ValidateExecution** 
   + 確認自動化不是以獨立執行的方式執行。

1.  **CheckForExistingStack** 
   + 檢查 CloudFormation 堆疊是否已為指定的叢集名稱佈建。
   + 傳回堆疊存在狀態，以及刪除是否安全。

1.  **BranchOnIsStackExists** 
   + 根據堆疊存在進行分支的決策步驟。
   + 更新現有堆疊名稱或繼續操作分支的路由。

1.  **UpdateStackName** 
   + 使用現有堆疊的名稱更新`StackName`變數。
   + 只有在堆疊已存在時才執行。

1.  **BranchOnOperation** 
   + 根據 `Operation` 參數 (`Setup` /) 路由自動化`Cleanup`。
   + 對於 `Setup`：建立新堆疊或描述現有資源的路由。
   + 對於 `Cleanup`：如果可安全刪除，則繼續刪除堆疊。

1.  **GetClusterNetworkConfig** 
   + 描述 Amazon EKS 叢集以取得 VPC 組態。
   + 擷取端點、VPC ID、子網路 IDs、安全群組 ID 和 CA 資料。

1.  **ProvisionResources** 
   + 建立具有必要資源的 CloudFormation 堆疊。
   + 使用必要的聯網組態佈建 Lambda 函數。
   + 標記所有資源以進行追蹤和管理。

1.  **DescribeStackResources** 
   + 擷取已建立/現有堆疊的相關資訊。
   + 取得佈建 Lambda 函數的 ARN。

1.  **BranchOnIsLambdaDeploymentRequired** 
   + 判斷是否需要 Lambda 程式碼部署。
   + 僅繼續部署新建立的堆疊。

1.  **DeployLambdaFunctionCode** 
   + 使用部署套件部署 Lambda 函數程式碼。
   + 使用代理實作更新函數。

1.  **AssertLambdaAvailable** 
   + 驗證 Lambda 函數程式碼更新是否成功。
   + 等待函數處於 `Successful` 狀態。

1.  **PerformStackCleanup** 
   + 刪除 CloudFormation 堆疊和相關聯的資源。
   + 在`Cleanup`操作期間或` Setup`操作失敗時執行。

 **輸出** 

*LambdaFunctionArn*：代理 Lambda 函數的 ARN

**參考**

Systems Manager Automation
+ [執行自動化](https://docs.aws.amazon.com//systems-manager/latest/userguide/automation-working-executing.html)
+ [設定自動化](https://docs.aws.amazon.com//systems-manager/latest/userguide/automation-setup.html)
+ [支援自動化工作流程](https://aws.amazon.com/premiumsupport/technology/saw/)