Get ARN from step machine

Hi guys,

Been fighting with the following for quite a bit and googling doesn’t help much…

I’ve been following a combination of:

https://serverless.com/plugins/serverless-step-functions/#current-gotcha and https://serverless.com/plugins/serverless-step-functions/#how-to-specify-the-statemachine-arn-to-environment-variables

Problem is if I follow the code as it is, first it complains about:

  Trying to populate non string value into a string for variable ${opt:stage}. Please make sure the value of the property is a string.

So apparently the following somehow is not valid:

resources:
  Outputs:
    halfHourMachine:
      Value:
        Ref: HalfHourMachineDash${self:service}Dash${opt:stage}

So I am like, ok whatever, let’s go with ${self:provider.stage} instead

resources:
  Outputs:
    halfHourMachine:
      Value:
        Ref: HalfHourMachineDash${self:service}Dash${self:provider.stage}

But then I got the following error:

  Error: The CloudFormation template is invalid: Template format error: Unresolved resource dependencies [HalfHourMachineDashms-pipedriveDashdev] in the Resources block of the template

For completeness here’s the relevant parts:

Step Function

stepFunctions:
  stateMachines:
    halfHourMachine:
      name: halfHourMachine-${self:service}-${self:provider.stage}
      definition:
        StartAt: WaitSecondsTask
        States:
          WaitSecondsTask:
            Type: Wait
            SecondsPath: $.wait
            Next: checkDealsAndUpdateIfOlderThan30MinutesTask
          checkDealsAndUpdateIfOlderThan30MinutesTask:
            Type: Task
            Resource:
              Fn::GetAtt: [checkDealsAndUpdateIfOlderThan30Minutes, Arn]
            End: true

Environemnt

  environment:
    stage: ${self:provider.stage}
    stepmachine_arn: ${self:resources.Outputs.halfHourMachine.Value}

Function to be called

functions:
  checkDealsAndUpdateIfOlderThan30Minutes:
    handler: index.checkDealsAndUpdateIfOlderThan30Minutes

Any help would be greatly appreciated!

1 Like

To anyone having a similar problem I solved it with the following:

Step Functions:

stepFunctions:
  stateMachines:
    checkDealAndUpdateIfOlderThan30MinutesMachine:
      name: checkDealAndUpdateIfOlderThan30MinutesMachine
      definition:
        StartAt: WaitSecondsTask
        States:
          WaitSecondsTask:
            Type: Wait
            SecondsPath: $.wait
            Next: checkDealsAndUpdateIfOlderThan30MinutesTask
          checkDealsAndUpdateIfOlderThan30MinutesTask:
            Type: Task
            Resource: 'arn:aws:lambda:#{AWS::Region}:#{AWS::AccountId}:function:${self:service}-${opt:stage}-checkDealsAndUpdateIfOlderThan30Minutes'
            End: true

Environment:

  environment:
    stage: ${self:provider.stage}
    stepmachine_arn: ${self:resources.Outputs.CheckDealAndUpdateIfOlderThan30MinutesMachine.Value}

and Resources:

resources:
  Outputs:
    CheckDealAndUpdateIfOlderThan30MinutesMachine:
      Value:
        Ref: CheckDealAndUpdateIfOlderThan30MinutesMachine

Everything works, but I am now having another problem which is created by the fact that when I deploy to dev/prod one of them works the other one doesn’t as it claims the stepMachine is already created…

Can you add the stage in the stage machine name?

Good point, just tried and it doesn’t work?

It could be thought.

That’s what I tried:

org: melmacaluso
app: ms-pipedrive
service: ms-pipedrive

frameworkVersion: '>=1.0.0 <2.0.0'

provider:
  name: aws
  runtime: nodejs12.x
  region: eu-west-2
  stage: ${opt:stage, 'dev'}
  environment:
    stage: ${self:provider.stage}
    stepmachine_arn: ${self:resources.Outputs.CheckDealAndUpdateIfOlderThan30MinutesMachine.Value}
  iamRoleStatements:
    - Effect: 'Allow'
      Action:
        - states:*
        - secretsmanager:*
      Resource: '*'

functions:
  createDeal:
    handler: index.createDeal
    events:
      - http:
          path: create-deal
          method: post
          cors: trues

  checkDealsAndUpdateIfOlderThan30Minutes:
    handler: index.checkDealsAndUpdateIfOlderThan30Minutes

stepFunctions:
  stateMachines:
    checkDealAndUpdateIfOlderThan30MinutesMachine:
      name: checkDealAndUpdateIfOlderThan30MinutesMachine-${self:custom.service}-${opt:stage}
      definition:
        StartAt: WaitSecondsTask
        States:
          WaitSecondsTask:
            Type: Wait
            SecondsPath: $.wait
            Next: checkDealsAndUpdateIfOlderThan30MinutesTask
          checkDealsAndUpdateIfOlderThan30MinutesTask:
            Type: Task
            Resource: 'arn:aws:lambda:#{AWS::Region}:#{AWS::AccountId}:function:${self:service}-${opt:stage}-checkDealsAndUpdateIfOlderThan30Minutes'
            End: true

package:
  individually: true

plugins:
  - serverless-bundle
  - serverless-step-functions
  - serverless-pseudo-parameters

custom:
  bundle:
    sourcemaps: true
    linting: false

resources:
  Outputs:
    CheckDealAndUpdateIfOlderThan30MinutesMachine:
      Value:
        Ref: CheckDealAndUpdateIfOlderThan30MinutesMachine-${self:custom.service}-${opt:stage}

Just tried (I could be wrong) but it doesn’t work?

org: melmacaluso
app: ms-pipedrive
service: ms-pipedrive

frameworkVersion: '>=1.0.0 <2.0.0'

provider:
  name: aws
  runtime: nodejs12.x
  region: eu-west-2
  stage: ${opt:stage, 'dev'}
  environment:
    stage: ${self:provider.stage}
    stepmachine_arn: ${self:resources.Outputs.CheckDealAndUpdateIfOlderThan30MinutesMachine.Value}
  iamRoleStatements:
    - Effect: 'Allow'
      Action:
        - states:*
        - secretsmanager:*
      Resource: '*'

functions:
  createDeal:
    handler: index.createDeal
    events:
      - http:
          path: create-deal
          method: post
          cors: trues

  checkDealsAndUpdateIfOlderThan30Minutes:
    handler: index.checkDealsAndUpdateIfOlderThan30Minutes

stepFunctions:
  stateMachines:
    checkDealAndUpdateIfOlderThan30MinutesMachine:
      name: checkDealAndUpdateIfOlderThan30MinutesMachine-${self:custom.service}-${opt:stage}
      definition:
        StartAt: WaitSecondsTask
        States:
          WaitSecondsTask:
            Type: Wait
            SecondsPath: $.wait
            Next: checkDealsAndUpdateIfOlderThan30MinutesTask
          checkDealsAndUpdateIfOlderThan30MinutesTask:
            Type: Task
            Resource: 'arn:aws:lambda:#{AWS::Region}:#{AWS::AccountId}:function:${self:service}-${opt:stage}-checkDealsAndUpdateIfOlderThan30Minutes'
            End: true

package:
  individually: true

plugins:
  - serverless-bundle
  - serverless-step-functions
  - serverless-pseudo-parameters

custom:
  bundle:
    sourcemaps: true
    linting: false

resources:
  Outputs:
    CheckDealAndUpdateIfOlderThan30MinutesMachine:
      Value:
        Ref: CheckDealAndUpdateIfOlderThan30MinutesMachine-${self:custom.service}-${opt:stage}