unbounce / iidy

iidy (Is it done yet?) -- CloudFormation with Confidence
MIT License
52 stars 7 forks source link

YAML pre-processor prefixing parameters when using custom resources #228

Closed dannosaur closed 4 years ago

dannosaur commented 4 years ago

When using custom resources that make use of parameters, when those parameters are references to CFN parameters (via !Ref), the values which have originated from a global section are prefixed, which then breaks the reference to the parameter.

Take this example;

vpc.yml

$params:
  - Name: ProjectName
  - Name: Environment

Resources:
  VPC:
    $global: true
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 172.30.0.0/16
      EnableDnsSupport: true
      EnableDnsHostnames: true
      Tags:
        - Key: Name
          Value: !Join
            - "/"
            - - !$ ProjectName
              - !$ Environment

stack.yml

Parameters:
  ProjectName:
    Description: The project's name
    Type: String

  Environment:
    Description: The type of environment this is provisioned for
    Type: String
    AllowedValues:
      - production
      - staging
    Default: staging

Resources:
  VPC:
    Type: VPC
    Properties:
      ProjectName: !Ref ProjectName
      Environment: !Ref Environment

The actual output is...

Parameters:
  # as the input, truncated for brevity
Resources:
  VPC:
    Type: 'AWS::EC2::VPC'
    Properties:
      CidrBlock: 172.30.0.0/16
      EnableDnsSupport: true
      EnableDnsHostnames: true
      Tags:
        - Key: Name
          Value: !Join 
            - /
            - - !Ref VPCProjectName
              - !Ref VPCEnvironment

whereas I'd expect !Ref ProjectName and !Ref Environment to remain untouched.

Unless I'm missing something?

dannosaur commented 4 years ago

Ok. I get that this might be necessary in the imported template...

Parameters:
  ProjectName:
    $global: true

  Environment:
    $global: true

Which does indeed resolve the above issue. However, if the parameter passed in to the resource isn't a CFN stack parameter (for instance, if I'm referencing another resource, like if I have a memcached resource that I import multiple times and need to address a specific one), then this happens in the rendered output;

Parameters:
  # truncated for brevity
  Table: {}

which then causes CFN to complain that the parameter needs at least a Type attribute, which will then eventually demand that the parameter has a value.

So the way I see it, either imported !Ref's need to not be prefixed when processing them, or the final Parameters section in the output needs to filter out empty objects so that the $global flag can be set without causing CFN to start demanding values for parameters that aren't stack parameters.

tavisrudd commented 4 years ago

I think this is roughly the same issue as #105.