【问题标题】:How to convert Pulumi Output<t> to string?如何将 Pulumi Output<t> 转换为字符串?
【发布时间】:2020-10-15 02:27:54
【问题描述】:

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

我已经尝试过PR#2496 中提出的这两个版本

  1. const restApiId = apiGatewayToSqsQueueRestApi.id.apply((v) =&gt; `${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) =&gt; v);

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

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

【问题讨论】:

    标签: output pulumi


    【解决方案1】:

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

    无法将Output&lt;string&gt; 转换为string,或将任何Output&lt;T&gt; 转换为T

    Output&lt;T&gt; 是未来值T 的容器,即使在程序执行结束后也可能无法解析。也许,您的 restApiId 是 AWS 在部署时生成的,所以如果您在预览版中运行程序,restApiId 没有任何价值。

    Output&lt;T&gt; 就像 Promise&lt;T&gt; 最终会得到解决,可能在云中创建一些资源之后。

    因此,Output&lt;T&gt; 的唯一操作是:

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

    任何值操作都必须在 apply 调用中进行。

    【讨论】:

      【解决方案2】:

      简答

      您可以通过指定name 输入来指定LogGroup 的物理名称,并且可以使用pulumi.interpolate 从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 自动命名来自这个逻辑名称的物理资源。您可以通过指定自己的物理名称来覆盖此行为,通常通过name 输入资源。有关资源名称和自动命名的更多信息是here

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

      【讨论】:

        【解决方案3】:

        只要在 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 等,以便我项目中的其他脚本知道在哪里可以找到最新版本。

        【讨论】:

          猜你喜欢
          • 2011-08-19
          • 1970-01-01
          • 2019-04-16
          • 2014-03-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-02-09
          • 1970-01-01
          相关资源
          最近更新 更多