简体   繁体   English

如何在 AWS SDK 中将 AWS SSO 临时凭证用于本地,但将实例角色用于生产?

[英]How to use AWS SSO temporary credentials in AWS SDK for local, but Instance Role for prod?

I understand how to use AWS SSO temporary credentials in my SDK, from this question and this question and this documentation .我了解如何在我的 SDK 中使用 AWS SSO 临时凭证,来自这个问题这个问题以及这个文档 It's pretty simple, really:这很简单,真的:

 import { fromSSO } from "@aws-sdk/credential-providers"; const client = new FooClient({ credentials: fromSSO({ profile: "my-sso-profile" }) });

And this code will work perfectly fine in my local computer and in my teammates' computers (so long as they are logged to AWS SSO with AWS CLI).这段代码在我的本地计算机和我队友的计算机上都可以正常运行(只要他们使用 AWS CLI 登录到 AWS SSO)。 However, it's not at all clear to me how to modify this so that it works both on our local computers with AWS SSO and on an EC2 instance with an Instance Role.但是,我一点都不清楚如何修改它,以便它既可以在我们使用 AWS SSO 的本地计算机上工作,也可以在具有实例角色的 EC2 实例上工作。 It's obvious that the EC2 instance should not have access to AWS SSO, but rather it should get its permissions from the IAM Policies attached to its associated Instance Role.很明显,EC2 实例不应该访问 AWS SSO,而是应该从附加到其关联实例角色的 IAM 策略中获得权限。 But how would my code look like, to account for both scenarios?但是我的代码会是什么样子,以解释这两种情况?

I'm taking a wild stab a this:我正在疯狂地刺伤这个:

 import { fromInstanceMetadata, fromSSO } from "@aws-sdk/credential-providers"; const isEc2Instance = "I HAVE NO IDEA WHAT TO DO HERE"; let credentials; if (isEc2Instance) { credentials = fromInstanceMetadata({ // Optional. The connection timeout (in milliseconds) to apply to any remote requests. // If not specified, a default value of `1000` (one second) is used. timeout: 1000, // Optional. The maximum number of times any HTTP connections should be retried. If not // specified, a default value of `0` will be used. maxRetries: 0, }); } else { credentials = fromSSO({ profile: "my-sso-profile" }); } const client = new FooClient({ credentials: credentials });

The code for getting the credentials from instance metadata is from here so it's probably correct.从实例元数据获取凭据的代码来自此处,因此它可能是正确的。 But as line 2 says, I have no idea how to determine whether I should be using AWS SSO or InstanceMetadata or something else (perhaps for other platforms, like what if this code is deployed in EC2 for dev env and ECS/EKS for prod env?).但正如第 2 行所说,我不知道如何确定我是否应该使用 AWS SSO 或 InstanceMetadata 或其他东西(也许对于其他平台,例如如果此代码部署在 EC2 中用于开发环境和 ECS/EKS 用于生产环境怎么办?)。

Maybe this if statement is not the right approach.也许这个 if 语句不是正确的方法。 I would gladly consider another option.我很乐意考虑另一种选择。

So, what would be the correct way to write code that gets the AWS credentials from the correct source depending on the platform where it's running?那么,编写根据运行平台从正确来源获取 AWS 凭证的代码的正确方法是什么?

And yes, since these credentials will be the same for any AWS SDK Client anywhere in the app, the code that gets the credentials should be abstracted away from this, and 5 if statements in a CredentialsHelper doesn't sound so bad, but I didn't want to overcomplicate this question.是的,由于这些凭据对于应用程序中任何位置的任何 AWS SDK 客户端都是相同的,因此获取凭据的代码应该从中抽象出来,并且 CredentialsHelper 中的 5 if 语句听起来还不错,但我没有' 想让这个问题过于复杂。

The code is JavaScript and I'm looking for something that works in Node.js, but I think the logic would be the same in any language.代码是 JavaScript,我正在寻找适用于 Node.js 的代码,但我认为任何语言的逻辑都是相同的。

You need to have DefaultAWSCredentialsProviderChain added in your code.您需要在代码中添加DefaultAWSCredentialsProviderChain This will take your credentials in local and will take instance credentials when deployed in EC2 using EKS .这将在本地获取您的凭据,并在使用EKS部署在EC2中时获取实例凭据。
Moreover, add this snippet to your code:此外,将此代码段添加到您的代码中:

private def getProvider(awsConfig: AWSConfig): Either[Throwable, AWSCredentialsProvider] = {
    def isDefault(key: String): Boolean = key == "default"
    def isIam(key: String): Boolean = key == "iam"
    def isEnv(key: String): Boolean = key == "env"

    ((awsConfig.accessKey, awsConfig.secretKey) match {
      case (a, s) if isDefault(a) && isDefault(s) =>
        new DefaultAWSCredentialsProviderChain().asRight
      case (a, s) if isDefault(a) || isDefault(s) =>
        "accessKey and secretKey must both be set to 'default' or neither".asLeft
      case (a, s) if isIam(a) && isIam(s) =>
        InstanceProfileCredentialsProvider.getInstance().asRight
      case (a, s) if isIam(a) && isIam(s) =>
        "accessKey and secretKey must both be set to 'iam' or neither".asLeft
      case (a, s) if isEnv(a) && isEnv(s) =>
        new EnvironmentVariableCredentialsProvider().asRight
      case (a, s) if isEnv(a) || isEnv(s) =>
        "accessKey and secretKey must both be set to 'env' or neither".asLeft
      case _ =>
        new AWSStaticCredentialsProvider(
          new BasicAWSCredentials(awsConfig.accessKey, awsConfig.secretKey)
        ).asRight
    }).leftMap(new IllegalArgumentException(_))
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM