org-formation-cli icon indicating copy to clipboard operation
org-formation-cli copied to clipboard

Feature: support functions in TemplatingContext parameters

Open zaro0508 opened this issue 3 years ago • 3 comments

Subject of the issue

OFN function references (!Ref, !Sub, !CopyValue, etc..) do no work with TemplatingContext parameters. References always resolve to object Object

Your environment

  • version of org-foramtion: 0.9.17-beta.3
  • version of node: v15.5.1
  • which OS/distro: Mac OSX 10.14

Steps to reproduce

noop.njk:

Description: noop template
AWSTemplateFormatVersion: 2010-09-09
Resources:
  {{ my_test_var }}:
    Type: AWS::CloudFormation::WaitConditionHandle

_tasks.yaml:

NoOp:
  Type: update-stacks
  Template: ./noop.njk
  StackName: noop
  TemplatingContext:
    my_test_var: !Ref MasterAccount
  DefaultOrganizationBinding:
    Account: !Ref MasterAccount
    Region: !Ref primaryRegion

run ofn print-tasks _tasks.yaml --output yaml

my out put in .printed-stacks/noop/us-east-1-master-account.yaml:

AWSTemplateFormatVersion: '2010-09-09'
Description: noop template
Parameters: {}
Resources:
  object Object:
    Type: AWS::CloudFormation::WaitConditionHandle
Outputs: {}

Expected behaviour

The resource ID/name should be set to the master account ID, something like this..

Resources:
  987264522347:
    Type: AWS::CloudFormation::WaitConditionHandle

Actual behaviour

The resource ID/name is set to object Object. Anywhere a reference (!Ref, !Sub, !CopyValue, etc..) is used it resolves to object Object.

zaro0508 avatar May 10 '21 18:05 zaro0508

what happen with these expressions is that they do not resolve before getting added to the templating context, but they are copied over as expressions.

MyAccount: {{ MasterAccount }} will resolve to MyAccount: [object object] MyAccount: {{ MasterAccount | object }} will resolve to to MyAccount: {Ref: MasterAccount}

there is a number of examples here.

the reason for this is that some expressions (e.g. CurrentAccount) cannot be resolved at "templating time", they need to be resolved at deployment time and might have a different value for each target.

Parameters do get evaluated before passed to the templating context. What you might be able to do to is have the expression evaluate early when assigned to a parameter, then pass the parameter to the templating context.

maybe a solution would be to add an Eval function? eagerly eval most expressions? but I would be interested to understand the usecase better before adding such function

OlafConijn avatar Feb 08 '22 21:02 OlafConijn

The use case for me is when I want to pass TemplatingContext variables to nunjuks templates and I want to use any of the !Ref, !Sub, !CopyValue, etc.. on those variables.

Examples:

Mappings:
  TgwSpokesA:
    VpcName:
      '111111111111': 'dustbunnyvpc'
      '222222222222': 'sandcastlevpc'  

TestStack:
  Type: update-stacks
  Template: test.yaml
  StackName: test
  TemplatingContext:
    MasterAccount: !Ref MasterAccount
    VpcId: !CopyValue [!Sub '${resourcePrefix}-tgw-${vpnVpc}-VpcId']
    SubnetIds:
      - !CopyValue [!Join ["-", [!Ref primaryRegion, !FindInMap [TgwSpokesA, VpcName, !Ref CurrentAccount], 'PrivateSubnet']]]
      - !CopyValue [!Join ["-", [!Ref primaryRegion, !FindInMap [TgwSpokesA, VpcName, !Ref CurrentAccount], 'PrivateSubnet1']]]

zaro0508 avatar Mar 28 '22 22:03 zaro0508