scala - 使用 scala 时的 lambda 的 AWS 凭证不起作用

标签 scala amazon-web-services amazon-s3 aws-lambda aws-sdk

尝试使用使用 DefaultCredentialProvider 提供的凭证时,AWS lambda 函数不起作用。

我需要将凭据传递给 S3 才能运行。

代码

def initializeAwsCredentials():AWSCredentials = {
    var credentials: AWSCredentials  = null
    try {
      credentials = new ProfileCredentialsProvider().getCredentials
    } catch {
      case e: Exception => {
        throw new AmazonClientException(
          "Cannot load the credentials from the credential profiles file. " +
            "Please make sure that your credentials file is at the correct " +
            "location (~/.aws/credentials), and is in valid format.",
          e);
      }

    }
    return credentials
  }

 def buildS3API(credentials: AWSCredentials): AmazonS3 = {
  new AmazonS3Client(credentials)
}

// inside handle request
val credentials = initializeAwsCredentials()
println("Credetials have been retrieved successfully")

println("Build S3 API using the constructor provided")
val s3 = buildS3API(credentials)
s3.setRegion(region)
println("S3 API is now available")

错误
{
  "errorMessage": "Cannot load the credentials from the credential profiles file. Please make sure that your credentials file is at the correct location (~/.aws/credentials), and is in valid format.",
  "errorType": "com.amazonaws.AmazonClientException",
  "stackTrace": [
    "example.Main$.initializeAwsCredentials(Hello.scala:52)",
    "example.Main$.handleRequest(Hello.scala:125)",
    "example.Main.handleRequest(Hello.scala)",
    "sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)",
    "sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)",
    "sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)",
    "java.lang.reflect.Method.invoke(Method.java:498)"
  ],
  "cause": {
    "errorMessage": "java.lang.NullPointerException",
    "errorType": "java.lang.NullPointerException",
    "stackTrace": [
      "com.amazonaws.auth.profile.ProfilesConfigFile.<init>(ProfilesConfigFile.java:143)",
      "com.amazonaws.auth.profile.ProfilesConfigFile.<init>(ProfilesConfigFile.java:132)",
      "com.amazonaws.auth.profile.ProfilesConfigFile.<init>(ProfilesConfigFile.java:99)",
      "com.amazonaws.auth.profile.ProfileCredentialsProvider.getCredentials(ProfileCredentialsProvider.java:135)",
      "example.Main$.initializeAwsCredentials(Hello.scala:45)",
      "example.Main$.handleRequest(Hello.scala:125)",
      "example.Main.handleRequest(Hello.scala)",
      "sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)",
      "sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)",
      "sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)",
      "java.lang.reflect.Method.invoke(Method.java:498)"
    ]
  }
}

更新

使用 InstanceProfileCredentialsProvider 而是抛出错误:
val provider: InstanceProfileCredentialsProvider = new InstanceProfileCredentialsProvider()
credentials = provider.getCredentials()

给我错误:
"cause": {
    "errorMessage": "Unable to load credentials from Amazon EC2 metadata service",
    "errorType": "com.amazonaws.AmazonClientException",
    "stackTrace": [
      "com.amazonaws.auth.InstanceProfileCredentialsProvider.handleError(InstanceProfileCredentialsProvider.java:244)",
      "com.amazonaws.auth.InstanceProfileCredentialsProvider.loadCredentials(InstanceProfileCredentialsProvider.java:225)",
      "com.amazonaws.auth.InstanceProfileCredentialsProvider.getCredentials(InstanceProfileCredentialsProvider.java:124)",
      "example.Main$.initializeAwsCredentials(Hello.scala:46)",
      "example.Main$.handleRequest(Hello.scala:126)",
      "example.Main.handleRequest(Hello.scala)",
      "sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)",
      "sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)",
      "sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)",
      "java.lang.reflect.Method.invoke(Method.java:498)"
    ],
    "cause": {
      "errorMessage": "Connection refused (Connection refused)",
      "errorType": "java.net.ConnectException",
      "stackTrace": [
        "java.net.PlainSocketImpl.socketConnect(Native Method)",
        "java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)",
        "java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)",
        "java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)",
        "java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)",
        "java.net.Socket.connect(Socket.java:589)",
        "sun.net.NetworkClient.doConnect(NetworkClient.java:175)",
        "sun.net.www.http.HttpClient.openServer(HttpClient.java:463)",
        "sun.net.www.http.HttpClient.openServer(HttpClient.java:558)",
        "sun.net.www.http.HttpClient.<init>(HttpClient.java:242)",
        "sun.net.www.http.HttpClient.New(HttpClient.java:339)",
        "sun.net.www.http.HttpClient.New(HttpClient.java:357)",
        "sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:1202)",
        "sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1138)",
        "sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:1032)",
        "sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:966)",
        "com.amazonaws.internal.EC2MetadataClient.readResource(EC2MetadataClient.java:90)",
        "com.amazonaws.internal.EC2MetadataClient.getDefaultCredentials(EC2MetadataClient.java:55)",
        "com.amazonaws.auth.InstanceProfileCredentialsProvider.loadCredentials(InstanceProfileCredentialsProvider.java:186)",
        "com.amazonaws.auth.InstanceProfileCredentialsProvider.getCredentials(InstanceProfileCredentialsProvider.java:124)",
        "example.Main$.initializeAwsCredentials(Hello.scala:46)",
        "example.Main$.handleRequest(Hello.scala:126)",
        "example.Main.handleRequest(Hello.scala)",
        "sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)",
        "sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)",
        "sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)",
        "java.lang.reflect.Method.invoke(Method.java:498)"
      ]
    }
  }
}

使用 lambda 时将以下配置为环境变量也会失败:
Lambda was unable to configure your environment variables because the 
environment variables you have provided contains reserved keys that are 
currently not supported for modification. Reserved keys used in this 
request: AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY

最佳答案

在适用于 Java 的 AWS 开发工具包的最新版本 ( 1.11.4xx ) 中,几乎所有服务都具有可用于快速创建客户端的“客户端构建器”。

val snsClient = AmazonSNSClientBuilder.defaultClient()
val s3Client = AmazonS3ClientBuilder.defaultClient()
val dynamoDbClient = AmazonDynamoDBAsyncClientBuilder.defaultClient()
val sesClient = AmazonSimpleEmailServiceAsyncClientBuilder.defaultClient()
// ...

在 Lambda 中 defaultClient()效果非常好,因为它将创建一个将使用适当提供程序的客户端。此提供程序使用具有 lambda 执行角色中定义的权限的凭据。

在本地环境中,defaultClient也很有效,因为它会获取主机凭据。这是有效的,因为 defaultClient用于 default credentials provider chain寻找
  • 环境变量
  • Java 系统属性
  • 凭据配置文件
  • ECS 容器凭证
  • 实例配置文件凭证

  • 这种方法也很简洁,但您也可以使用客户端构建器使用特定凭据“设置/配置”来创建客户端。

    适用于 Java 的 AWS 开发工具包 v2

    如果您想使用 Java SDK 的新版本 ( >=2.1 ),有 create可用于获取客户端的方法(尽管我仅将其用于试验新 SDK)
    val s3Client = S3AsyncClient.create()
    val dynamoDbClient = DynamoDbAsyncClient.create()
    // ...
    

    关于scala - 使用 scala 时的 lambda 的 AWS 凭证不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47763573/

    相关文章:

    amazon-web-services - terraform aws - 如何将默认路由添加到 vpc 默认路由表?

    amazon-web-services - 如何通过cloudformation在非默认vpc上创建自动伸缩组?

    java - AWS Java 开发工具包 : check if an object exists with a specific version in an S3 bucket

    python-3.x - 通过 EC2 进行 S3 身份验证,无需在代码或存储中传递 AWS 访问 key 和 key

    amazon-s3 - 将s3数据迁移到谷歌云存储

    regex - 如何将一个字符串与另一个之间有空格的字符串进行比较

    scala - 如何设置 IntelliJ Idea Scala 项目以识别本地 Ivy2 缓存?

    node.js - 如何在部署的 Lambda 函数中查看 console.log 语句

    scala - 找不到 org.scalacheck.Arbitrary 类型的证据参数的隐式值

    Scala - 如何创建可用于类型构造函数的单个隐式