如何将 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
中提出的这两个版本
const restApiId = apiGatewayToSqsQueueRestApi.id.apply((v) => `${v}`);
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>
,其中 f
:T -> 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 等每次部署后,我项目中的其他脚本就知道在哪里可以找到最新的版本。
我正在处理创建 AWS API 网关的问题。我正在尝试创建 CloudWatch 日志组并将其命名为 API-Gateway-Execution-Logs_${restApiId}/${stageName}
。我在 Rest API 创作中没有问题。
我的问题是将类型为 pulumi.Outout 的 restApi.id 转换为字符串。
我已经尝试了他们PR#2496
中提出的这两个版本const restApiId = apiGatewayToSqsQueueRestApi.id.apply((v) => `${v}`);
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>
,其中f
:T -> 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 等每次部署后,我项目中的其他脚本就知道在哪里可以找到最新的版本。