CDKTF C#从Terraform资源的JSON对象结果中获取值(TFToken)

6fe3ivhb  于 2023-01-03  发布在  C#
关注(0)|答案(1)|浏览(139)

TLDR使用CDKTF for C#,如何在下游资源中使用ResourceGroupTemplateDeployment资源的outputContent?JSON结构为

{
  apiKey: {
     value: <the value>
  },
  queryKey: {
     value: <the query key value>
  }
}

因此,我希望能够将此值传递给Function App的配置,但任何在C#中获取apiKey的尝试都会导致错误,因为C#将此值视为Token,而不是JSON对象。
我目前正在使用CDKTF和C#来构建基础设施。我正在使用资源ResourceGroupTemplateDeployment,它返回一个Output对象,该对象是一个字符串,实际上是一个JSON对象。我想从中检索两个值,以便在下游资源中使用。在HCL中,这是很容易做到的。我只会做一些像sensitive(jsondecode(azurerm_resource_group_template_deployment.service.output_content).myKey.value)这样的事情,这就会得到我所需要的。在CDKTF中,虽然这不是那么简单。
在运行初始synth(构建C#并将其转换为json)时,Output值实际上是TFToken。这意味着它本质上是一个真实的值的占位符,由于Terraform实际上还没有运行plan/apply,因此该值目前未知。
因此,当代码第一次运行时,它返回一个字符串,但当terraform plan/apply运行时,它具有真实的值。我需要JSON对象中的值来将它们分配给下游资源,如果在构建代码时未定义它们,我怎么可能做到这一点呢?以下是我的代码:

ResourceGroupTemplateDeployment searchService = new ResourceGroupTemplateDeployment(this, "search-service", new ResourceGroupTemplateDeploymentConfig
{
                Name = $"{searchName}-{suffix.Result}",
                ResourceGroupName = rg.Name,
                DeploymentMode = "Incremental",
                ParametersContent = JsonSerializer.Serialize(new Dictionary<string, Dictionary<string,string>>{
                    {"searchServices_dev_request_search_name", new Dictionary<string, string>{
                        { "value", $"{searchName}-{suffix.Result}" }
                        }
                    }
                }),
                TemplateContent = template,
});

SearchTemplateOutput resultObj = JsonSerializer.Deserialize<SearchTemplateOutput>((searchService.OutputContent));
apiKey = resultObj.apiKey;

class SearchTemplateOutput {
        public string apiKey {get; set;}
        public string queryKey {get; set;}
}

上面的代码不起作用,并得到一个错误Unhandled exception. System.Text.Json.JsonException: '$' is an invalid start of a value.,因为值是一个令牌,它还不是一个实际的JSON对象...但它将是:/
我还尝试添加Token.AsString

SearchTemplateOutput resultObj = JsonSerializer.Deserialize<SearchTemplateOutput>(Token.AsString(searchService.OutputContent));

但是结果是一样的,反序列化结果的尝试失败了,因为它是一个令牌,而不是我以后需要引用的实际值。
我不知道如何处理这个问题,文档只是给出了非常简单的示例,其中您将获得返回给您的简单内容,并且使用返回的整个对象,但在这种情况下,返回的是具有多个值的JSON对象,因此我不知道如何访问这些值。

h5qlskok

h5qlskok1#

我的问题的答案可以在AWS文档中找到,该文档是从TF文档链接而来的,本质上说,您不能操作JSON列表/字符串,因此解决方案是使用资源组模板创建对象(因为Azure中有一个超过1年的未解决错误,其API不不符合他们自己的标准,如果使用自由层,则该标准通过Terraform来破坏搜索服务),然后在创建它之后,使用相关联的数据对象来获得值。
不管怎样,下面是我使用C#安全获取值所做的最后一个设置

DataAzurermSearchService searchSvcData = new DataAzurermSearchService(this, "search-service-data", new DataAzurermSearchServiceConfig
{
     Name = searchService.Name,
     ResourceGroupName = rg.Name
});

apiKey = searchSvcData.PrimaryKey;
queryKey = searchSvcData.QueryKeys.Get(0).GetStringAttribute("key");

对于更精通C#的人来说,这个解决方案可能是显而易见的,但我花了一些时间才弄明白。希望有一天它能帮助其他人

相关问题