Use k6 on AWS EC2 with instance role

Hey,
I am trying to configure k6 to work with AWS

When I follow that guide for AWS systems manager client on my local env that works fine. I am setting up env variables, run some easy script to fetch value out of AWS.

BUT on pipeline where I want to implement k6, as automated tool, I have quite different set up. I want to run it on EC2 using instance IAM role, so I have rotated credentials which. So I have no env vars set up. AWS cli has access to SSM. example below

I assume k6 SystemsManagerClient requires some configuration, as I am getting an errors while trying to initialize it without AWSConfig object.

How Can I approach this?

sample code.js

import { describe } from 'https://jslib.k6.io/functional/0.0.3/index.js';
import { Httpx, Request, Get, Post } from 'https://jslib.k6.io/httpx/0.0.2/index.js';
import { randomIntBetween, randomItem } from "https://jslib.k6.io/k6-utils/1.1.0/index.js";
// imports for handling aws secrets
import exec from 'k6/execution';
import { AWSConfig, SystemsManagerClient } from 'https://jslib.k6.io/aws/0.6.0/ssm.js';

export let options = {
.
.
.
}

const systemsManager = new SystemsManagerClient();
const testParameterSecretName = 'some_secret';

// this value was created with --type SecureString
const testParameterSecretValue = 'verysecretvalue';

export default function testSuite() {

//to be moved to setup part
const { value: encryptedParameterValue } = systemsManager.getParameter(testParameterSecretName, true);
  if (encryptedParameterValue !== testParameterSecretValue) {
    console.log(encryptedParameterValue)
    exec.test.abort('encrypted test parameter not found');
  }
    console.log(encryptedParameterValue)

// some defined tests
}

pipeline sample


k6 version
k6 v0.41.0 (2022-11-02T11:50:11+0000/v0.41.0-0-g11deb073, go1.19.3, linux/amd64)

aws configure list
      Name                    Value             Type    Location
      ----                    -----             ----    --------
   profile                <not set>             None    None
access_key     ****************TGAA         iam-role    
secret_key     ****************AAAA         iam-role    
    region                eu-west-1              env    ['AWS_REGION', 'AWS_DEFAULT_REGION']

aws ssm get-parameter --name some_secret
{
    "Parameter": {
        "Name": "some_secret",
        "Type": "SecureString",
        "Value": "notDecryptedValueReturned",
       .
       .
    }
}
k6 run --http-debug=full /tests/k6/code.js
          /\      |‾‾| /‾‾/   /‾‾/   
     /\  /  \     |  |/  /   /  /    
    /  \/    \    |     (   /   ‾‾\  
   /          \   |  |\  \ |  (‾)  | 
  / __________ \  |__| \__\ \_____/ .io
  execution: local
     script: tests/k6/code.js
     output: -
  scenarios: (100.00%) 1 scenario, 1 max VUs, 30s max duration (incl. graceful stop):
           * default: Up to 1 looping VUs for 1ms over 1 stages (gracefulRampDown: 30s, gracefulStop: 30s)
time="2022-11-07T16:59:31Z" level=error msg="TypeError: Cannot read property 'region' of undefined\n\tat get (webpack://k6-jslib-aws/./src/internal/client.ts:88:53(10))\n\tat value (webpack://k6-jslib-aws/./src/internal/ssm.ts:53:17(42))\n\tat testSuite (file://tests/k6/code.js:61:71(5))\n\tat native\n" executor=ramping-vus scenario=default source=stacktrace
.
.
#same error repeated on and on
.

Hi @irvis

Welcome to the forum :wave: and sorry for not getting back to you earlier indeed!

As you have found out, at the moment the AWS jslib for k6 relies on either the script having credentials hard-coded, or being injected via the environment. Those values are used to feed an AWSConfig object which contains credentials, and a bunch of other settings too indeed. Every client class exposed by the jslib relies on this object.

I’m not familiar with AWS Pipeline, but from what I read, it’s a CI pipeline system, which I assume would have the ability to inject AWS credentials in the instances it uses on the fly. My understanding is that you’re using rotating credentials, once again I have little knowledge of pipeline, but I believe getting it to set the proper environment variables is the (only) way to go at the moment.

And that’s linked to your other point: I assume the reason why your AWS CLI is functional is that it goes and reads the content of your $HOME/.aws/credentials file. In theory, you could try to do that in k6 too, but that would probably need some parsing trickery.

Following your use case, I opened a GitHub issue to track a potential feature consisting in acquiring credentials from a file.

Let me know if that was helpful :bowing_man:

1 Like

Thank you for your reply @oleiade !
I have used other workaround,
I have fetched secrets I need, exported to environment variables and finally used in k6 script thanks to __ENV.ENV-NAME.

1 Like

Perfect :tada: I’m glad you found a workaround!! :bowing_man:

Thanks for the detailed question and your workaround @irvis.

Ran into the exact same scenario in the exact same sequence :sweat_smile: It would be good to have authentication based on an instance role. Following the github issue :+1:

1 Like