10

我正在处理创建 AWS API Gateway。我正在尝试创建 CloudWatch Log 组并将其命名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.

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

4

3 回答 3

16

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

无法将 an 转换Output<string>string或 any Output<T>to T

Output<T>是未来值的容器,T即使在程序执行结束后也可能无法解析。也许,你restApiId是 AWS 在部署时生成的,所以如果你在预览中运行你的程序,那么restApiId.

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

因此,唯一的操作Output<T>是:

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

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

于 2020-06-24T19:37:43.567 回答
3

简答

您可以LogGroup通过指定name输入来指定您的物理名称,并且您可以id使用pulumi.interpolate. 您必须使用静态字符串作为资源的第一个参数。我建议使用您为 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 会根据这个逻辑名称自动命名物理资源。您可以通过指定您自己的物理名称来覆盖此行为,通常是通过name对资源的输入。有关资源名称和自动命名的更多信息在这里

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

于 2020-06-24T19:23:06.137 回答
0

只要在 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)时才有效,而不仅仅是预览。(如此处所述

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

于 2021-08-28T02:21:31.580 回答