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

Error: Action not implemented as StringStep aws:runInstances #69

Open
gmarchand opened this issue Dec 11, 2023 · 1 comment
Open

Error: Action not implemented as StringStep aws:runInstances #69

gmarchand opened this issue Dec 11, 2023 · 1 comment

Comments

@gmarchand
Copy link

gmarchand commented Dec 11, 2023

Here is my cdk code

ssm_documents.StringDocument.from_yaml(
    self, "lustre-preload",
    document_yaml=lustre_preload_document_yaml
)

Here is my YAML Automation Document (it works if I copy / paste in the AWS console)

schemaVersion: "0.3"
parameters:
  filelist:
    type: StringList
    description: "(Required) The Lustre file list to preload on cluster"
mainSteps:
  - description: Launch a micro instance which mount the Lustre Cluster and preload files
    name: LaunchMicroInstance
    action: aws:runInstances
    nextStep: ChangeInstanceState
    isEnd: false
    inputs:
      ImageId: ami-005e7be1c849abba7
      InstanceType: t2.micro
      SubnetId: subnet-xxxx
      UserData: IyEvYmluL2Jhc2ggLWV4CgplY2hvICJBV1MgQmF0Y2ggZm9yIEZGTVBFRyA6IE1vdW50IEZTeCBMdXN0cmUgQ2x1c3RlciIKCmV4ZWMgPiA+KHRlZSAvdmFyL2xvZy91c2VyLWRhdGEubG9nfGxvZ2dlciAtdCB1c2VyLWRhdGEgLXMgMj4vZGV2L2NvbnNvbGUpIDI+JjEKCnVuYW1lIC1yCgpmc3hfZG5zbmFtZT1mcy0wYWFiZjMyOTNjY2YyYThkNy5mc3guZXUtd2VzdC0xLmFtYXpvbmF3cy5jb20KZnN4X21vdW50bmFtZT1qNGtzYmJldgpmc3hfbW91bnRwb2ludD0vZnN4LWx1c3RyZQoKYW1hem9uLWxpbnV4LWV4dHJhcyBpbnN0YWxsIC15IGx1c3RyZQpta2RpciAtcCAiJGZzeF9tb3VudHBvaW50Igptb3VudCAtdCBsdXN0cmUgLW8gcmVsYXRpbWUsZmxvY2sgJHtmc3hfZG5zbmFtZX1AdGNwOi8ke2ZzeF9tb3VudG5hbWV9ICR7ZnN4X21vdW50cG9pbnR9CgplY2hvICJBV1MgQmF0Y2ggZm9yIEZGTVBFRyA6IE1vdW50IEZTeCBMdXN0cmUgQ2x1c3RlciA6IEVORCIK
  - name: ChangeInstanceState
    action: aws:changeInstanceState
    description: Wait ec2 instance is running
    nextStep: PreloadFileListOnLustre
    isEnd: false
    inputs:
      InstanceIds: "{{ LaunchMicroInstance.InstanceIds }}"
      DesiredState: running
      CheckStateOnly: true
  - name: PreloadFileListOnLustre
    description: Execute Lustre command to preload files
    action: aws:runCommand
    nextStep: Loop
    isEnd: false
    inputs:
      InstanceIds: "{{ LaunchMicroInstance.InstanceIds }}"
      TimeoutSeconds: 600
      DocumentName: "AWS-RunShellScript"
      Parameters:
        commands: |-
          #!/bin/bash
          lfs hsm_restore /fsx-lustre/tests/media-assets/norisleepingmusic2_480p.mp4
  - name: Loop
    description: Wait 20 times x 30 seconds = 10 min to preload the file
    action: aws:loop
    isEnd: true
    inputs:
      MaxIterations: 30
      LoopCondition:
        Variable: '{{ PreloadFileListOnLustre.Output }}'
        StringEquals: preloaded
      Steps:
        - name: Sleep
          action: aws:sleep
          nextStep: IsFileListPreloaded
          isEnd: false
          inputs:
            Duration: PT30S
        - description: Check if file is preloaded
          name: IsFileListPreloaded
          action: aws:runCommand
          isEnd: true
          inputs:
            InstanceIds: '{{ LaunchMicroInstance.InstanceIds }}'
            TimeoutSeconds: 600
            DocumentName: AWS-RunShellScript
            Parameters:
              commands: |-
                #!/bin/bash
                lfs hsm_state /fsx-lustre/tests/media-assets/norisleepingmusic2_480p.mp4 | grep -q 'archived' && echo 'preloaded'

And the error raised by the function

    raise RuntimeError(resp.error) from JavaScriptError(resp.stack)
RuntimeError: Error: Action not implemented as StringStep aws:runInstances

@john-heinnickel
Copy link

It looks like there are only a subset of the step types implemented in StringStep. There should be a case statement for each supported step type since your error is triggered in the default case block:

            case 'aws:executeAwsApi':
            case 'aws:waitForAwsResourceProperty':
            case 'aws:assertAwsResourceProperty':
            case 'aws:pause':
            case 'aws:sleep':
            case 'aws:executeScript':
            case 'aws:branch':
            case 'aws:approve'

The good news (I think) is that all I see this code doing for the cases it does implement is extracting arguments from the input Yaml and using them to call the appropriate step constructor. For example, from the aws:assertAwsResourceProperty steps's compiled JavaScript:

            this.automationStep = new assert_aws_resource_step_1.AssertAwsResourceStep(this, props.name, {
                service: Service,
                pascalCaseApi: Api,
                apiParams: restParams,
                selector: PropertySelector,
                desiredValues: DesiredValues,
                ...sharedProps,
            });
            break;

This class is a Facade/Adapter design pattern. It may be straightforward to create a PR or fix this in a fork of your own by just adding new case blocks and calling the relevant constructor that you need (In this case, the RunInstancesStep).

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

2 participants