anantab / serverless-plugin-ifelse

A Serverless Plugin to write If Else conditions in serverless YAML file
69 stars 19 forks source link

Setting variables in the custom section possible? #9

Closed gerovermaas closed 5 years ago

gerovermaas commented 5 years ago

Hi,

Is it possible to also set variables in the custom section using this plug-in?

When using the following code I get the error below.

custom:
  resource_name_infix: ${opt:resource_name_infix, ''}
  serverlessIfElse:
      - If: '${self:custom.resource_name_infix} == ""'
        Set:
          custom.domain_name_infix: ""
        ElseSet:
          custom.domain_name_infix: "${self:custom.resource_name_infix}."
  scientist_url: "https://api.${self:custom.domain_name_infix}serverlessscientist.com"

sls deploy --profile ss-ci

 Serverless Warning --------------------------------------

  A valid service attribute to satisfy the declaration 'self:custom.domain_name_infix' could not be found.

  Serverless Error ---------------------------------------

  Trying to populate non string value into a string for variable ${self:custom.domain_name_infix}. Please make sure the value of the property is a string.```
anantab commented 5 years ago

It is possible to set variable in custom with plugin. But in your case, you are referencing to the variable, before it is set by the plugin. Serverless resolves the value first before it is passed to plugins. You are getting the error because serverless cannot find that variable when it tries to resolve it. Create that variable with default value in custom. It will later be replace by plugin based on condition.

However, in your case, it would not work because , it would update custom.domain_name_infix, but custom.scientist_url will not be updated. In your example, you can set it without using serverless-if-else plugin. Try this:

custom:
  resource_name_infix: ${opt:resource_name_infix, ''}
  scientist_url: "https://api.${self:custom.resource_name_infix}serverlessscientist.com"
gerovermaas commented 5 years ago

Thanks for the quick reply.

I now have this code:

  resource_name_infix: ${opt:resource_name_infix, ''}
  domain_name_infix: ${self:custom.resource_name_infix}
  serverlessIfElse:
      - If: '"${self:custom.resource_name_infix}" == ""'
        Set:
          custom.domain_name_infix: ""
        ElseSet:
          custom.domain_name_infix: "${self:custom.resource_name_infix}."

Which runs without errors. However, the result is not yet what I expected.

Output of the sls deploy command is:

'sls deploy --profile ss-ci --resource_name_infix bla
Serverless: serverless-plugin-ifelse - Value Changed for : custom.domain_name_infix to: bla.
Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Service files not changed. Skipping deployment...

Which looks OK, I do indeed want to set the custom.domain_name_infix to bla. (note the dot at the end)

However, when using the variable as in an enironment variable for on of the functions like this: "https://api.${self:custom.domain_name_infix}serverlessscientist.com"

It is replacing ${self:custom.domain_name_infix} with bla and not with bla.. So the result is https://api.blaserverlessscientist.com instead of https://api.bla.serverlessscientist.com. So it is using the initial value of domain_name_infix and not the updated value.

Any ideas what could be causing this.

gerovermaas commented 5 years ago

@anantab I cannot reopen the issue, hope you can still look into it. See reply above.

Thanks.

anantab commented 5 years ago

@gerovermass Please read my comment above. You can solve your problem without using the ifelse plugin.

gerovermaas commented 5 years ago

Thanks @anantab . Unfortunately, that does not completely address what I'm aiming for.

The challenge is that:

Can the ifelse plugin help with that?

anantab commented 5 years ago

You will need to set scientist_url variable in serverlessIfElse condition

serverlessIfElse:
      - If: '"${self:custom.resource_name_infix}" == ""'
        Set:
          custom.scientist_url: https://api.serverlessscientist.com
        ElseSet:
          custom.scientist_url: https://api.${self:custom.resource_name_infix}.serverlessscientist.com
gerovermaas commented 5 years ago

I now have this:

  resource_name_infix: ${opt:resource_name_infix, ''}
  serverlessIfElse:
      - If: '"${self:custom.resource_name_infix}" == ""'
        Set:
          custom.scientist_url: https://api.serverlessscientist.com
        ElseSet:
          custom.scientist_url: https://api.${self:custom.resource_name_infix}.serverlessscientist.com

and then use the variable in the environment setting of a function like this:

    environment:
      ROUND_TRAFFIC_TARGET_URL:
        !Join
          - ''
          - - ${self:custom.scientist_url}
            - '/scientist'
            - '/round'

However, when i run an sls deploy I get this:

sls deploy --profile ss-ci --resource_name_infix bla

 Serverless Warning --------------------------------------

  A valid service attribute to satisfy the declaration 'self:custom.scientist_url' could not be found.

 Serverless Warning --------------------------------------

  A valid service attribute to satisfy the declaration 'self:custom.scientist_url' could not be found.

 Serverless Warning --------------------------------------

  A valid service attribute to satisfy the declaration 'self:custom.scientist_url' could not be found.

 Serverless Warning --------------------------------------

  A valid service attribute to satisfy the declaration 'self:custom.scientist_url' could not be found.

Serverless: serverless-plugin-ifelse - Value Changed for : custom.scientist_url to: https://api.bla.serverlessscientist.com
Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service sample-traffic.zip file to S3 (18.15 MB)...
Serverless: Validating template...

  Error --------------------------------------------------

  The CloudFormation template is invalid: [/Resources/RoundDashtrafficLambdaFunction/Type/Environment/Variables/ROUND_TRAFFIC_TARGET_URL/Fn::Join/1/0] 'null' values are not allowed in templates

     For debugging logs, run again after setting the "SLS_DEBUG=*" environment variable.

  Get Support --------------------------------------------
     Docs:          docs.serverless.com
     Bugs:          github.com/serverless/serverless/issues
     Issues:        forum.serverless.com

  Your Environment Information ---------------------------
     OS:                     darwin
     Node Version:           12.1.0
     Serverless Version:     1.44.1

And if I add a line before the serverlessIfElse plugin line to initialize the scientist_url variable to some value, then it keeps that value when used in the environment variables of a function (even though the plugin reports that it is updated).

What version of serverless are you using? I'm using 1.44.1 as you can see above.

Regards, Gero

ashokpokharel977 commented 3 years ago

@gerovermaas Did you get any solution?

heeksfred commented 3 years ago

@gerovermaas Did you get any solution? I have the same problem.

gerovermaas commented 3 years ago

We using this construct now:

 stageprefix:
    # NOTE Every separate environment (also dedicated ones for Enterprise Plan customers) needs an entry here.
    staging: 'staging.'
    prod: ''
    xebia: 'xebia.'
    other: 'staging.'  # Catch all.
  stageprefixVal: ${self:custom.stageprefix.${opt:stage, self:provider.stage}}

So stageprefixVal looks up the correct value using the opt:stage or self.provider.stage variable in the stageprefix map.

iDanielBot commented 3 years ago

Same problems here.. After 1 hour fighting with it (using custom section, provider section, mix of both),I ended up using the same stage mapping pattern @gerovermaas described above. 👍

No offence, but this plugin is kinda sh!t... 👎

tomhalley commented 2 years ago

Been on the same Journey as @CDanielBot and @gerovermaas, can confirm fix without plugin worked