# Configuring the Jenkinsfile to Assume the Integration Test IAM Role

Jenkins must assume the IAM role created by terraform in order to read secrets from Secrets Manager during integration tests. This is done using the `withAWS` step plugin.

## How the role name is derived

The terraform `main.tf` creates the role with this name:

```hcl
resource "aws_iam_role" "jenkins_invoke_role" {
  name = "${var.environment}-${var.service_name}-role"
  ...
}
```

Given `environment = "qa"` and `service_name = "<service-name>-integration-test"`, the resulting role name is:

```
qa-<service-name>-integration-test-role
```

This is the value you pass to `withAWS` in the Jenkinsfile.

## What to add to the Jenkinsfile

Define constants near the top of the file (alongside the other role/account constants):

```groovy
String QA_ACCOUNT_ID = '437795906767'
String QA_MY_SERVICE_INTEGRATION_TEST_ROLE = 'qa-<service-name>-integration-test-role'
String SESSION_NAME = 'qa-<service-name>-integration-test'
```

Then wrap the integration test step. **The nesting order is critical** — `withEcr` outermost, then `withAWS`, then optionally `withSecrets` if the service needs secrets from Secrets Manager:

```groovy
stage('Integration Tests') {
    when {
        branch 'master'
    }
    steps {
        withEcr {
            withAWS(role: QA_MY_SERVICE_INTEGRATION_TEST_ROLE, roleAccount: QA_ACCOUNT_ID, roleSessionName: SESSION_NAME, useNode: true) {
                // withSecrets is optional — only include it if your tests need secrets from Secrets Manager
                withSecrets(secrets: [
                    [id: 'qa/<service-name>/SOME_SECRET', environmentVariable: 'SOME_SECRET'],
                ]) {
                    sh 'make ci_test_integration'
                }
            }
        }
    }
}
```

If your service doesn't need any Secrets Manager secrets, omit `withSecrets` entirely:

```groovy
stage('Integration Tests') {
    when {
        branch 'master'
    }
    steps {
        withEcr {
            withAWS(role: QA_MY_SERVICE_INTEGRATION_TEST_ROLE, roleAccount: QA_ACCOUNT_ID, roleSessionName: SESSION_NAME, useNode: true) {
                sh 'make ci_test_integration'
            }
        }
    }
}
```

**Critical nesting rules:**
- `withEcr` must be outermost — it authenticates the Docker pull of the ECR base image
- `withAWS` must wrap `withSecrets` (if used) — it provides the AWS credentials that `withSecrets` uses to fetch secrets
- `withSecrets` is optional — only add it if your integration tests need secrets from Secrets Manager
- **Never** put `withAWS` inside `withSecrets` — the credential chain runs outer-to-inner
- When using `withAWS`, do **not** pass `awsAccountId` or `awsRole` to `withSecrets` — `withAWS` already provides the AWS context

## Real example: graphql-user Jenkinsfile

From [theorchard/graphql-user Jenkinsfile](https://github.com/theorchard/graphql-user/blob/master/Jenkinsfile):

```groovy
String QA_ACCOUNT_ID = '437795906767'
String QA_GRAPHQL_USER_INTEGRATION_TEST_ROLE = 'qa-graphql-user-integration-test-role'
String SESSION_NAME = "qa-graphql-user-integration-test"

// ...

stage('Integration Tests') {
    // ...
    steps {
        retry(2) {
            withCredentials([...]) {
                withEcr {
                    withAWS(role: QA_GRAPHQL_USER_INTEGRATION_TEST_ROLE, roleAccount: QA_ACCOUNT_ID, roleSessionName: SESSION_NAME, useNode: true) {
                        sh '''
                        docker compose up --build \
                        --exit-code-from integration-tests \
                        --abort-on-container-exit \
                        --remove-orphans \
                        integration-tests
                        '''
                    }
                }
            }
        }
    }
}
```

The role name `qa-graphql-user-integration-test-role` matches the terraform `service_name = "graphql-user-integration-test"` exactly.

## Real example: ows-track Jenkinsfile

From [theorchard/ows-track Jenkinsfile](https://github.com/theorchard/ows-track/blob/master/Jenkinsfile):

```groovy
String QA_ACCOUNT_ID = '437795906767'
String BUILD_ROLE = 'qa-ows-track-integration-test-role'

// ...

stage('Integration Tests') {
    // ...
    steps {
        withEcr {
            withAWS(role: BUILD_ROLE, roleAccount: QA_ACCOUNT_ID, roleSessionName: 'qa-ows-track-integration-test', useNode: true) {
                withSecrets(secrets: [
                    [id: 'qa/ows-track/AUTOMATION_QA_DB_PASS', environmentVariable: 'QA_DB_PASS'],
                ]) {
                    sh 'make docker_test_integration'
                }
            }
        }
    }
}
```

The role name `qa-ows-track-integration-test-role` matches the terraform `service_name = "ows-track-integration-test"` exactly.

## Notes

- `QA_ACCOUNT_ID` (`437795906767`) is the standard QA AWS account ID — reuse it, don't change it.
- `roleSessionName` is an arbitrary label that appears in CloudTrail logs; use something descriptive like `qa-<service-name>-integration-test`.
- `useNode: true` authenticates by retrieving credentials from the Jenkins node in scope — required when running docker-based integration tests so the injected AWS credentials are available to the container.
- If your integration tests are currently running without `withAWS`, adding it is a no-op for everything except Secrets Manager access — existing env vars and credentials are unaffected.
