如何从 AWS CloudFormation 中的 AWS::EKS::Cluster 获取 OIDC 提供商 URL?
上次更新时间:2020 年 8 月 20 日
我想要从 AWS::EKS::Cluster 获取 OpenID Connect (OIDC) 提供商 URL。然后,我想要将 AWS Identity and Access Management (IAM) 角色中的 URL 用于使用 AWS CloudFormation 的服务账户信任关系。
简短描述
AWS::EKS::Cluster 未提供返回值来获取 OIDC 提供商 URL。您必须在 AWS CloudFormation 中使用 AWS Lambda 支持的自定义资源,这样才能从现有 Amazon Elastic Kubernetes Service (Amazon EKS) 集群中获取集群 OIDC 提供商 URL。然后,您可以使用从群集返回的值来创建 IAM 角色。IAM 角色可让您与 OIDC 建立信任关系。
注意:以下解决方法使用 Python 3.7,并且适用于 Kubernetes 版本 1.14 及更高版本。
解决方法
以下示例演示如何将 Amazon EKS 集群中的服务账户与 IAM 角色相关联。IAM 角色提供对 Amazon EKS pod 的精细权限,并为 Amazon EKS 集群中的服务账户提供对 AWS API 的安全访问。然后,堆栈将创建与 Amazon EKS 集群的 OIDC 值相关联的 IAM 角色。
1.根据以下示例,创建一个名为 CustomLambdaEksOidc.template 的 AWS CloudFormation 模板:
Parameters:
EKSClusterName:
Type: String
Description: Provide the name for EKS Cluster
Resources:
ClusterName:
Type: Custom::ClusterName
Properties:
ServiceToken: !GetAtt LambdaFunction.Arn
cluster_name:
Ref: EKSClusterName
MyIAMRole:
Type: AWS::IAM::Role
DependsOn: ClusterName
Properties:
AssumeRolePolicyDocument: !Sub |
{
"Version": "2012-10-17",
"Statement":
}
LambdaIAMRole:
Type: 'AWS::IAM::Role'
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- 'sts:AssumeRole'
Path: /
Policies:
- PolicyName: root
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- 'eks:DescribeCluster'
Resource: '*'
- Effect: Allow
Action:
- 'logs:CreateLogGroup'
- 'logs:CreateLogStream'
- 'logs:PutLogEvents'
Resource: 'arn:aws:logs:*:*:*'
LambdaFunction:
Type: AWS::Lambda::Function
Properties:
Code:
ZipFile: |
import cfnresponse
import boto3
import json
def lambda_handler(event, context):
print("Received event: " + json.dumps(event, indent=2))
oidc_response = ''
responseData = {}
try:
if event == 'Delete':
print("Request Type:",event)
print("Delete Request - No Physical resources to delete")
elif event == 'Create' or event == 'Update':
print("Request Type:",event)
cluster_name = event
oidc_response_url = fetchClusterOIDC(cluster_name)
oidc_response=oidc_response_url.split("https://")
responseData = oidc_response
print("Sending response to custom resource for event type " + event)
cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData, "CustomResourcePhysicalID")
return oidc_response
except Exception as e:
print('Failed to process:', e)
responseStatus = 'FAILURE'
responseData = {'Failure': 'Something bad happened.'}
cfnresponse.send(event, context, cfnresponse.FAILED, responseData, "CustomResourcePhysicalID")
def fetchClusterOIDC(cluster_name):
print("Getting Cluster OIDC value for cluster name "+ cluster_name)
oidc = ''
client = boto3.client('eks')
try:
response = client.describe_cluster(
name=cluster_name
)
if response == 200:
print("Success response recieved for describing cluster "+ cluster_name)
oidc = (response)
print('OIDC output recieved '+ oidc + ' for Cluster Name ' + cluster_name)
return oidc
except Exception as e:
print('Failed to fetch Cluster OIDC value for cluster name ' + cluster_name, e)
Handler: index.lambda_handler
MemorySize: 1024
Role: !GetAtt LambdaIAMRole.Arn
Runtime: python3.7
Timeout: 300
Outputs:
OIDC:
Description: EKS Cluster OIDC Value
Value:
Fn::GetAtt:
- ClusterName
- oidc
2.要使用 CustomLambdaEksOidc.template 文件启动 AWS CloudFormation 堆栈,请使用 AWS CloudFormation 控制台或 AWS 命令行界面 (AWS CLI)。
要使用 AWS CLI,请运行以下命令:
aws cloudformation create-stack --stack-name lambda-eks-oidc --template-body file://CustomLambdaEksOidc.template --parameters ParameterKey=EKSClusterName,ParameterValue=demo-newsblog --capabilities CAPABILITY_NAMED_IAM --region us-east-1
注意:当您启动 AWS CloudFormation 堆栈时,请使用您的 Amazon EKS 群集名称替换 demo-newsblog。使用您的 AWS 区域替换 us-east-1。