使用从 AWS IAM 身份中心更新 AWS CLI 证书 PowerShell - AWS Prescriptive Guidance

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

使用从 AWS IAM 身份中心更新 AWS CLI 证书 PowerShell

创建者:Chad Miles (AWS) 和 Andy Bowen (AWS)

环境:生产

技术:安全、身份、合规; CloudNative

工作负载:开源

AWS 服务:适用于 AWS 的工具 PowerShell;AWS IAM 身份中心

Summary

如果您想将 AWS IAM Identity Center(AWS 单点登录的后续版本)凭证与 AWS 命令行界面(AWS CLI)、AWS Cloud Development Kit(AWS CDK)或 AWS CDK 一起使用,则通常必须将凭证从 IAM Identity Center 控制台复制并粘贴到命令行界面中。此过程可能需要相当长的时间,并且必须为每个需要访问权限的账户重复此过程。

一种常见的解决方案是使用 AWS CLI aws sso configure 命令。此命令在您的 AWS CLI 或 AWS SDK 中添加启用 IAM Identity Center 的配置文件。但是,此解决方案的缺点是,您必须为以这种方式配置的每个 AWS CLI 配置文件或账户运行 aws sso login 命令。

作为替代解决方案,此模式描述了如何使用名为 Profiles 的 AWS CLI 和 AWS 工具 PowerShell 来同时存储和刷新来自单个 IAM Identity Center 实例的多个账户的证书。该脚本还将 IAM Identity Center 会话数据存储在内存中,以便在无需再次登录 IAM Identity Center 即可刷新凭证。

先决条件和限制

先决条件

  • PowerShell,已安装并配置。有关更多信息,请参阅安装 PowerShell(微软文档)。

  • 已安装并配置 PowerShell的 AWS 工具。出于性能考虑,我们强烈建议您安装名AWS.Tools为的 AWS 工具的 PowerShell模块化版本。每个 Amazon Web Service 都由其自己的小模块提供支持。在 PowerShell 提示符中,输入以下命令以安装此模式所需的模块:AWS.Tools.InstallerSSO、和SSOIDC

    Install-Module AWS.Tools.Installer Install-AWSToolsModule SSO, SSOOIDC

    有关更多信息,请参阅在 Windows 上安装 AWS.Tools在 Linux 或 macOS 上安装 AWS.Tools

  • AWS CLI 或 AWS 开发工具包必须事先通过以下任一操作配置有效凭证:

    • 使用 AWS CLI aws configure 命令。有关更多信息,请参阅快速配置(AWS CLI 文档)。

    • 将 AWS CLI 或 AWS CDK 配置为通过 IAM 角色获得临时访问权限。有关更多信息,请参阅获取用于 CLI 访问的 IAM 角色凭证(IAM Identity Center 文档)。

限制

  • 此脚本不可在管线或全自动解决方案中使用。部署此脚本时,必须手动授权来自 IAM Identity Center 的访问权限。然后,脚本会自动继续。

产品版本

架构

您可以使用此模式中的脚本同时刷新多个 IAM Identity Center 凭证,也可以创建凭证文件以用于 AWS CLI、AWS SDK 或 AWS CDK。

使用 PowerShell 脚本更新 AWS CLI、AWS CDK 或 AWS 软件开发工具包中的证书。

工具

Amazon Web Services

  • AWS 命令行界面(AWS CLI)是一种开源工具,它可帮助您通过命令行 Shell 中的命令与 Amazon Web Services 交互。

  • AWS IAM Identity Center 可帮助您集中管理对所有 Amazon Web Services account 和云应用程序的单点登录(SSO)访问权限。

  • AWS 工具 PowerShell是一组 PowerShell 模块,可帮助您通过 PowerShell 命令行编写对 AWS 资源的操作的脚本。

其他工具

  • PowerShell是一款在 Windows、Linux 和 macOS 上运行的微软自动化和配置管理程序。

最佳实践

为每个 IAM Identity Center 实例保留一份此脚本的副本。不支持将一个脚本用于多个实例。

操作说明

任务描述所需技能

自定义 SSO 脚本。

  1. 复制其他信息部分中的 SSO 脚本。

  2. Param 部分中,针对您的 AWS 环境,定义以下变量的值:

    • DefaultRoleName – 默认情况下要使用的 IAM 角色或权限集。

    • Region – 部署了 IAM Identity Center 的 AWS 区域。有关区域及其代码的完整列表,请参阅区域端点

    • StartUrl – 用于访问 IAM Identity Center 登录页面的 URL。使用与脚本中示例值相同的格式。

    • EnvironmentName – 用于引用此脚本副本的简称,当您在同一个会话中运行多个脚本副本时将会用到。

  3. 在第 10 行(读作 # Add your Account Information)下方,编辑哈希表中的以下值以反映您的环境:

    • Profile – 用于存储临时凭证的 AWS CLI 配置文件名称。

    • AccountId – 您要为其检索凭证的 Amazon Web Services account 的 ID。

    • RoleName – 您要使用的 IAM Identity Center 角色或权限集的名称。如果您要使用在 Param 部分中定义的相同角色,您可以把它当作 $DefaultRoleName

    哈希表中的每一行都必须以逗号结尾,最后一行除外。

云管理员

运行 SSO 脚本。

建议您使用以下命令在 PowerShell shell 中运行您的自定义脚本。

./Set-AwsCliSsoCredentials.ps1

或者,您可以通过输入以下命令从其他 Shell 运行脚本。

pwsh Set-AwsCliSsoCredentials.ps1
云管理员

故障排除

问题解决方案

No Access 错误

您正在使用的 IAM 角色无权访问您在 RoleName 参数中定义的角色或权限集。更新您正在使用的角色的权限,或者在脚本中定义其他角色或权限集。

相关资源

其他信息

SSO 脚本

在以下脚本中,用您自己的信息替换尖括号(<>)中的占位符,然后删除尖括号。

Set-AwsCliSsoCredentials.ps1 Param( $DefaultRoleName = '<AWSAdministratorAccess>', $Region = '<us-west-2>', $StartUrl = "<https://d-12345abcde.awsapps.com/start/>", $EnvironmentName = "<CompanyName>" ) Try {$SsoAwsAccounts = (Get-Variable -name "$($EnvironmentName)SsoAwsAccounts" -Scope Global -ErrorAction 'SilentlyContinue').Value.Clone()} Catch {$SsoAwsAccounts = $False} if (-not $SsoAwsAccounts) { $SsoAwsAccounts = @( # Add your account information in the list of hash tables below, expand as necessary, and do not forget the commas @{Profile = "<Account1>" ; AccountId = "<012345678901 >"; RoleName = $DefaultRoleName }, @{Profile = "<Account2>" ; AccountId = "<123456789012>"; RoleName = "<AWSReadOnlyAccess>" } )} $ErrorActionPreference = "Stop" if (-not (Test-Path ~\.aws)) { New-Item ~\.aws -type Directory } if (-not (Test-Path ~\.aws\credentials)) { New-Item ~\.aws\credentials -type File } $CredentialFile = Resolve-Path ~\.aws\credentials $PsuedoCreds = @{AccessKey = 'AKAEXAMPLE123ACCESS';SecretKey='PsuedoS3cret4cceSSKey123PsuedoS3cretKey'} # Pseudo Creds, do not edit. Try {$SSOTokenExpire = (Get-Variable -Scope Global -Name "$($EnvironmentName)SSOTokenExpire" -ErrorAction 'SilentlyContinue').Value} Catch {$SSOTokenExpire = $False} Try {$SSOToken = (Get-Variable -Scope Global -Name "$($EnvironmentName)SSOToken" -ErrorAction 'SilentlyContinue').Value } Catch {$SSOToken = $False} if ( $SSOTokenExpire -lt (Get-Date) ) { $SSOToken = $Null $Client = Register-SSOOIDCClient -ClientName cli-sso-client -ClientType public -Region $Region @PsuedoCreds $Device = $Client | Start-SSOOIDCDeviceAuthorization -StartUrl $StartUrl -Region $Region @PsuedoCreds Write-Host "A Browser window should open. Please login there and click ALLOW." -NoNewline Start-Process $Device.VerificationUriComplete While (-Not $SSOToken){ Try {$SSOToken = $Client | New-SSOOIDCToken -DeviceCode $Device.DeviceCode -GrantType "urn:ietf:params:oauth:grant-type:device_code" -Region $Region @PsuedoCreds} Catch {If ($_.Exception.Message -notlike "*AuthorizationPendingException*"){Write-Error $_.Exception} ; Start-Sleep 1} } $SSOTokenExpire = (Get-Date).AddSeconds($SSOToken.ExpiresIn) Set-Variable -Name "$($EnvironmentName)SSOToken" -Value $SSOToken -Scope Global Set-Variable -Name "$($EnvironmentName)SSOTokenExpire" -Value $SSOTokenExpire -Scope Global } $CredsTime = $SSOTokenExpire - (Get-Date) $CredsTimeText = ('{0:D2}:{1:D2}:{2:D2} left on SSO Token' -f $CredsTime.Hours, $CredsTime.Minutes, $CredsTime.Seconds).TrimStart("0 :") for ($i = 0; $i -lt $SsoAwsAccounts.Count; $i++) { if (([DateTimeOffset]::FromUnixTimeSeconds($SsoAwsAccounts[$i].CredsExpiration / 1000)).DateTime -lt (Get-Date).ToUniversalTime()) { Write-host "`r `rRegistering Profile $($SsoAwsAccounts[$i].Profile)" -NoNewline $TempCreds = $SSOToken | Get-SSORoleCredential -AccountId $SsoAwsAccounts[$i].AccountId -RoleName $SsoAwsAccounts[$i].RoleName -Region $Region @PsuedoCreds [PSCustomObject]@{AccessKey = $TempCreds.AccessKeyId; SecretKey = $TempCreds.SecretAccessKey; SessionToken = $TempCreds.SessionToken } | Set-AWSCredential -StoreAs $SsoAwsAccounts[$i].Profile -ProfileLocation $CredentialFile $SsoAwsAccounts[$i].CredsExpiration = $TempCreds.Expiration } } Set-Variable -name "$($EnvironmentName)SsoAwsAccounts" -Value $SsoAwsAccounts.Clone() -Scope Global Write-Host "`r$($SsoAwsAccounts.Profile) Profiles registered, $CredsTimeText"