Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cannot parse jsonnet int field with env or tfstate syntax #506

Closed
jsoizo opened this issue Jan 27, 2023 · 5 comments
Closed

cannot parse jsonnet int field with env or tfstate syntax #506

jsoizo opened this issue Jan 27, 2023 · 5 comments

Comments

@jsoizo
Copy link

jsoizo commented Jan 27, 2023

When a service-definition Jsonnet file as below is given,

{
  "role": "ecsServiceRole",
  "desiredCount": {{ env `SERVICE_DESIRED_COUNT` `1` }}
}

ecspresso failed with this error ( at Github Actions )

Error: /26 05:08:35 [ERROR] FAILED. failed to load service definition service-definition.jsonnet: RUNTIME ERROR: {{ env `SERVICE_DESIRED_COUNT` `1` }} is not a base 10 integer

This may be due to the fact that the jsonnet file is parsed before the environment variables or tfstate substitutions.

https://github.com/kayac/ecspresso/blob/v2/util.go#L32-L42

@fujiwara
Copy link
Contributor

Yes, but this is intentional behavior to compatibility with v1.

ecspresso v1 doesn't have a Jsonnet parser. v1 users process Jsonnet files to JSON files by the jsonnet command at first, then ecspresso read these JSON files.

So, if the order of the process is changed, v1's definition files might be broken.

I propose some workarounds,

  1. Use --ext-str and --ext-code to pass values that are not a string. https://github.com/kayac/ecspresso#use-jsonnet-instead-of-json-and-yaml
  2. Dump environment variables to a JSON file (for example, jq -n env > env.json), and jsonnet imports the file (probably used with std.parseInt function).

@fujiwara
Copy link
Contributor

fujiwara commented May 26, 2023

@jsoizo I tried to change the order of parsing jsonnet and template evaluation.

But, I found the template evaluation before parsing jsonnet breaks compatibility.

For example, as below, even if the imported file (envs.libsonnet) contains template syntax, that is not evaluated.

// envs.libsonnet
[
  { name: 'ENV', value: '{{ must_env `ENV` }}' },
]
// taskdef.jsonnet
local envs = import 'envs.libsonet';
{
  containerDefinitions: [
    {
      environment: envs,
      // ...
     }
  ],
  // ...
}

So I decided to keep the current behavior, at least ecspresso v2.

@darai0512
Copy link

お世話になります。

自分もこちらの問題の良い解決策を模索しております。
taskdefで containerDefinitions[].portMappings[].containerPort: {{ tfstate "aws_lb_target_group.hoge.port" }}と書きたいですが、jsonnetを使う場合は厳格にjsonとして吐き出すため、この時点で文字列だとダブルクオートで囲わないとダメでした。

上のケースでは先に変換をして欲しい一方で、jsonnetを使うモチベーションとしてsecretsmanager_arnの値を環境によって出し分けたく変数化しているのですが、そのケースではjsonnet to jsonの変換後にarn解決してくれる現状の仕様(If the file extension is .jsonnet, ecspresso will process Jsonnet first, convert it to JSON, and then load it.)がありがたいです。

local secretsmanager_arn = "{{ secretsmanager_arn `" + std.extVar('ENV') + "/app` }}:";

この辺の問題をみなさんがどう対処しておられるか、知見があれば伺えると助かります。
(tfstate-lookupを活用しましょうって感じなのでしょうか...)


自分の上のケースだけであれば、例えばsecretsmanager_arnの値にネストしてenvやmust_envが使えれば(現状はパースがsecretsmanager/funcs.goとgo-configで分かれて不可な認識)、jsonnetを使って変数化する必要はなくなるのですが、使ってみたら共通化の恩恵も助かり、jsonnetを使っても解決できると助かります。

@fujiwara
Copy link
Contributor

@darai0512 Jsonnetとテンプレートを併用するとどうしてもこのような(変換順序による)問題が出てしまいます。

現在作業中の #702 で、Jsonnetのnative functionとして各種テンプレート関数を提供することで、Jsonnet内でレンダリングを完結できるようになれば解決するかと思いますがどうでしょうか。

これはv2.4としてリリースする予定ですので、しばらくお待ちください。

@darai0512
Copy link

@fujiwara v2.4 助かりました!ありがとうございました!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants