<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Integration-Testing on despatches</title><link>https://icle.es/tags/integration-testing/</link><description>Recent content in Integration-Testing on despatches</description><generator>Hugo</generator><language>en</language><lastBuildDate>Fri, 20 Jun 2025 08:42:17 +0100</lastBuildDate><atom:link href="https://icle.es/tags/integration-testing/index.xml" rel="self" type="application/rss+xml"/><item><title>How to run your lambda code locally as its role (for testing)</title><link>https://icle.es/2023/11/14/automated-testing-of-aws-lambda-locally/</link><pubDate>Tue, 14 Nov 2023 14:23:37 +0000</pubDate><guid>https://icle.es/2023/11/14/automated-testing-of-aws-lambda-locally/</guid><description>&lt;p>While AWS Lambda is fantastic in providing a serverless platform with few
worries about maintaining servers, it is not the easiest to test in an automated
fashion with rapid feedback.&lt;/p>
&lt;p>You could write end to end tests, but it means a deployment after each change
and then checking the logs to see what failed. Even if you use iac
(terraform/pulumi), the deployment will take seconds or a minute or two - not
exact rapid test feedback.&lt;/p>
&lt;p>What I have been doing is to set up a hook which is called from the lambda
handler, which can also be called locally. Within the test, I then assume the
role that runs the lambda and then test the hook.&lt;/p>
&lt;p>This mechanism allows to me easily test that the permissions are set up
correctly and that details are in place for the code to work.&lt;/p>
&lt;p>For the full end to end test, I then have a simple smoke test or two.&lt;/p>
&lt;p>The code samples are in golang(only because it happens to be my current language
of choice), but the idea should be equally applicable in other languages.&lt;/p></description><content:encoded><![CDATA[<p>While AWS Lambda is fantastic in providing a serverless platform with few
worries about maintaining servers, it is not the easiest to test in an automated
fashion with rapid feedback.</p>
<p>You could write end to end tests, but it means a deployment after each change
and then checking the logs to see what failed. Even if you use iac
(terraform/pulumi), the deployment will take seconds or a minute or two - not
exact rapid test feedback.</p>
<p>What I have been doing is to set up a hook which is called from the lambda
handler, which can also be called locally. Within the test, I then assume the
role that runs the lambda and then test the hook.</p>
<p>This mechanism allows to me easily test that the permissions are set up
correctly and that details are in place for the code to work.</p>
<p>For the full end to end test, I then have a simple smoke test or two.</p>
<p>The code samples are in golang(only because it happens to be my current language
of choice), but the idea should be equally applicable in other languages.</p>
<h1 id="assuming-the-role">Assuming The Role</h1>
```go
  roleToAssume := os.Getenv("AUTH_LAMBDA_ROLE_ARN")

    ctx := context.TODO()
    cfg, err := config.LoadDefaultConfig(ctx)

    if err != nil {
        logger.Fatal("error: ", err)
    }
    // Create the credentials from AssumeRoleProvider to assume the role
    // referenced by the "myRoleARN" ARN using the MFA token code provided.
    creds := stscreds.NewAssumeRoleProvider(sts.NewFromConfig(cfg), roleToAssume)

    logger.Debugf("creds: %v", creds)

    cfg.Credentials = aws.NewCredentialsCache(creds)
```
<p>the cfg is then passed into the <code>New</code> method for the resource you are interested
in. e.g.:</p>
```go
   ssmClient := ssm.NewFromConfig(cfg)
```
<h1 id="working-example">Working Example</h1>
<p>You can find a full, working example test in
<a href="https://github.com/drone-ah/wordsonsand">my github repo</a> under
<a href="https://github.com/drone-ah/wordsonsand/tree/main/post/2023/11/autolambdatest">post/2023/11/autolambdatest</a></p>
<p>NOTE: It WILL automatically try and deploy a role and a ssm parameter, and it
will delete it after the test.</p>
<p>The <code>BeforeSuite</code> will deploy the minimum configuration to be able to run the
test, and the <code>AfterSuite</code> will destroy the same stack.</p>
<p>You will likely need to log into pulumi to get this test to work.</p>
<p>If you run into permissions issue for AssumeRole, read on.</p>
<h1 id="assumerole-permissions">AssumeRole Permissions</h1>
<p>For this to work, the user running the tests need to have permissions to
<code>AssumeRole</code>.</p>
<p>There are two steps to this. The first part is to allow &quot;anyone&quot; to
<code>AssumeRole</code> the relevant role:</p>
```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::<your-account-id>:root"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
```
<p>This will allow &quot;any user&quot; to assume the role, as long as they have the
permission to do so.</p>
<p><code>arn:aws:iam::[your-account]:root</code> is a special user the represents the account
(and the non-IAM root user). Since IAM (user, roles etc.) exists under the
&quot;root&quot; account, all calls are also authenticated by this account - i.e. all
users, roles etc. in IAM is also this account. There is
<a href="https://www.reddit.com/r/aws/comments/oorjl2/what_exactly_is_the_root_iam_principal/">a post on reddit discussing what exactly the root iam principal is for more information</a></p>
<p>Finally, unless you have the <code>Administrator</code>Access policy set against your
account, you will also need to attach a policy to the relevant group (or your
user) that grants permissions to call <code>sts:AssumeRole</code> (or <code>*</code>)</p>
```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "123",
      "Effect": "Allow",
      "Action": ["sts:AssumeRole"],
      "Resource": ["arn:aws:iam::123456789012:role/desired-role"]
    }
  ]
}
```
<p>You can of course, also use <code>*</code> for Resource above to allow the user/group to
Assume Any role. In practice, you might want to automate this as part of the
creation of the relevant roles. (i.e. create the role, then give the relevant
group permissions to Assume that role).</p>]]></content:encoded></item></channel></rss>