如何将 Pulumi Output<t> 转换为字符串?

How to convert Pulumi Output<t> to string?

我正在处理创建 AWS API 网关的问题。我正在尝试创建 CloudWatch 日志组并将其命名为 API-Gateway-Execution-Logs_${restApiId}/${stageName}。我在 Rest API 创作中没有问题。
我的问题是将类型为 pulumi.Outout 的 restApi.id 转换为字符串。

我已经尝试了他们PR#2496

中提出的这两个版本
  1. const restApiId = apiGatewayToSqsQueueRestApi.id.apply((v) => `${v}`);
  2. const restApiId = pulumi.interpolate `${apiGatewayToSqsQueueRestApi.id}`

这里是使用代码

const cloudWatchLogGroup = new aws.cloudwatch.LogGroup(
  `API-Gateway-Execution-Logs_${restApiId}/${stageName}`,
  {},
);

stageName 只是一个字符串。

我也试过apply 再次喜欢
const restApiIdStrign = restApiId.apply((v) => v);

我总是从 pulumi up
得到这个错误 aws:cloudwatch:LogGroup API-Gateway-Execution-Logs_Calling [toString] on an [Output<T>] is not supported.

请帮我将输出转换为字符串

简答

您可以通过指定 name 输入来指定 LogGroup 的物理名称,您可以使用 [=14] 从 API 网关 id 输出构造它=].您必须使用静态字符串作为资源的第一个参数。我建议使用您提供给 API 网关资源的名称作为日志组的名称。这是一个例子:

const apiGatewayToSqsQueueRestApi = new aws.apigateway.RestApi("API-Gateway-Execution");

const cloudWatchLogGroup = new aws.cloudwatch.LogGroup(
  "API-Gateway-Execution", // this is the logical name and must be a static string
  {
    name: pulumi.interpolate`API-Gateway-Execution-Logs_${apiGatewayToSqsQueueRestApi.id}/${stageName}` // this the physical name and can be constructed from other resource outputs
  },
);

更长的答案

Pulumi 中每种资源类型的第一个参数是逻辑名称,用于 Pulumi 从一个部署到下一个部署的内部跟踪资源。默认情况下,Pulumi auto-names 来自这个逻辑名称的物理资源。您可以通过指定您自己的物理名称来覆盖此行为,通常是通过对资源的 name 输入。有关资源名称和自动命名的更多信息,请访问 here

这里的具体问题是无法从其他资源输出构造逻辑名称。它们必须是静态字符串。资源输入(例如name)可以从其他资源输出构建。

@Cameron 回答了命名问题,我想在标题中回答你的问题

无法将 Output<string> 转换为 string,或将任何 Output<T> 转换为 T

Output<T> 是未来值 T 的容器,即使在程序执行结束后也可能无法解析。也许,您的 restApiId 是由 AWS 在部署时生成的,因此如果您 运行 您的程序处于预览状态,则 restApiId.

没有任何价值

Output<T> 就像一个 Promise<T> 最终会被解决,可能在云中创建一些资源之后。

因此,只有 Output<T> 的操作是:

  • apply(f) 将其转换为另一个 Output<U>,其中 fT -> U
  • 将其分配给 Input<T> 以将其传递给另一个资源构造函数
  • 从堆栈中导出

任何值操作都必须在 apply 调用中发生。

只要在 Pulumi 脚本仍然 运行 时输出是可解析的,您就可以使用如下方法:

import {Output} from "@pulumi/pulumi";
import * as fs from "fs";

// create a GCP registry
const registry = new gcp.container.Registry("my-registry");
const registryUrl = registry.id.apply(_=>gcp.container.getRegistryRepository().then(reg=>reg.repositoryUrl));

// create a GCP storage bucket
const bucket = new gcp.storage.Bucket("my-bucket");
const bucketURL = bucket.url;

function GetValue<T>(output: Output<T>) {
    return new Promise<T>((resolve, reject)=>{
        output.apply(value=>{
            resolve(value);
        });
    });
}

(async()=>{
    fs.writeFileSync("./PulumiOutput_Public.json", JSON.stringify({
        registryURL: await GetValue(registryUrl),
        bucketURL: await GetValue(bucketURL),
    }, null, "\t"));
})();

澄清一下,此方法仅在您进行实际部署(即 pulumi up)时有效,而不仅仅是预览。 (如explained here

虽然这对我的用例来说已经足够了,因为我只想要一种方法来存储注册表-url 等每次部署后,我项目中的其他脚本就知道在哪里可以找到最新的版本。