I am trying to write some Node code to create and execute a step function, but I have a problem in the way configuration is passed into the middleware that manages requests.
At its simplest, I can run stepfunctions-local in docker with the defaults
docker run -p 8083:8083 amazon/aws-stepfunctions-local
which means it is now running on port 8083. If I set up a dummy profile, I can then create a state machine from the CLI with
aws stepfunctions --endpoint http://localhost:8083 create-state-machine --definition "$(cat test.json)" --name test --role-arn "arn:aws:iam::012345678901:role/DummyRole" --region eu-west-1 --profile dummy
(my ~/.aws/credentials has the following entry)
[dummy]
aws_access_key_id = dummy
aws_secret_access_key = dummy
If I do the equivalent from node
sfnLocalClient = new SFNClient([{
endpoint: `http://localhost:8083`,
region: 'eu-west-1',
credentials: {
accessKeyId: 'dummy',
secretAccessKey: 'dummy',
},
}]);
stateMachine = await sfnLocalClient.send(
new CreateStateMachineCommand({
name: 'TestStateMachine',
roleArn: 'arn:aws:iam::012345678901:role/DummyRole',
definition: readFileSync('test.json', 'utf8'),
}));
It first fails due to missing region. If I set the region as an env variable it fails with no credentials provided. If I set the dummy profile as an env variable then it fails due to The security token included in the request is invalid
.
Debugging a bit, I find the requests are going to a default state machine endpoint states.eu-west-1.amazonaws.com, so it seems like again my config is being ignored. Looking into this, I find various code to pull information out of the config ready to use in a stack of middleware implementations (defined in the SFNClient constructor in @aws-sdk/client-sfn).
I'm guessing they all have the same problem, but looking at the endpoint resolution in particular (@smithy/middleware-endpoint) the resolveEndpointConfig
function tries to get configured endpoint as const { endpoint } = input;
but when I look at input I see that my endpoint config is nested inside a property called o
in the input hence it doesn't find it.
If I tamper with the code and change it to const endpoint = 'http://localhost:8080'
then it successfully creates the state machine.
Does anyone know if I'm hitting a bug or if I'm doing something obviously wrong? I'm more of a Java engineer so please let me know if I've left out important information in this question that I can look up and add.
I'm specifying ^3.398.0
as the @aws-sdk/client-sfn version. I can dig into package-lock if it helps to find versions of the aws and smithy libraries.
UPDATE
It seems that runtimeConfig.js doesn't expect a tuple of config, but the SFNClient constructor does. I don't quite get the syntax, maybe that is my problem - SFNClient code looks like
constructor(...[configuration]: __CheckOptionalClientConfig<SFNClientConfig>);
@aws-sdk/client-sfn
getRuntimConfig function puts together the config with
return {
...clientSharedValues,
...config,
which seems to include the first tuple entry as an object whereas it looks like it expects to just include the properties
Seems like the issue is with the IDE (Webstorm) that prompts me to include an array of Config objects. If I pass in just an object
it gives me compilation error
Argument type {endpoint: string, credentials: {accessKeyId: string, secretAccessKey: string}, region: string} is not assignable to parameter type __CheckOptionalClientConfig<SFNClientConfig>
But if I just run it, it all works perfectly.
This is a new world for me - in Java, I can't run code with compilation errors!