Terraform
Tests API
Tests are terraform operations(runs) and are referred to as Test Runs within the HCP Terraform API.
Performing a test on a new configuration is a multi-step process.
- Create a configuration version on the registry module.
- Upload configuration files to the configuration version.
- Create a test on the module; HCP Terraform completes this step automatically when you upload a configuration file.
Alternatively, you can create a test with a pre-existing configuration version, even one from another module. This is useful for promoting known good code from one module to another.
Attributes
The tests
API endpoint has the following attributes.
Test Run States
The state of the test operation is found in data.attributes.status
, and you can reference the following list of possible states.
State | Description |
---|---|
pending | The initial status of a run after creation. |
queued | HCP Terraform has queued the test operation to start. |
running | HCP Terraform is executing the test. |
errored | The test has errored. This is a final state. |
canceled | The test has been canceled. This is a final state. |
finished | The test has completed. This is a final state. |
Test run status
The final test status is found in data.attributes.test-status
, and you can reference the following list of possible states.
Status | Description |
---|---|
pass | The given tests have passed. |
fail | The given tests have failed. |
Detailed test status
The test results can be found via the following attributes
Status | Description | |
---|---|---|
data.attributes.tests-passed | The number of tests that have passed. | |
data.attributes.tests-failed | The number of tests that have failed. | |
data.attributes.tests-errored | The number of tests that have errored out. | |
data.attributes.tests-skipped | The number of tests that have been skipped. |
Test Sources
List tests for a module. You can use the following sources as tests list query parameters.
Source | Description |
---|---|
terraform | Indicates a test was queued from HCP Terraform CLI. |
tfe-api | Indicates a test was queued from HCP Terraform API. |
tfe-configuration-version | Indicates a test was queued from a Configuration Version, triggered from a VCS provider. |
Create a Test
POST /organizations/:organization_name/tests/registry-modules/private/:namespace/:name/:provider/test-runs
Parameter | Description |
---|---|
:organization_name | The name of the organization for the module. The organization must already exist, and the token authenticating the API request must belong to the "owners" team or a member of the "owners" team. |
:namespace | The namespace of the module for which the test is being created. For private modules this is the same as the :organization_name parameter. |
:name | The name of the module for which the test is being created. |
:provider | The name of the provider for which the test is being created. |
A test run executes tests against a registry module, using a configuration version and the modules’s current environment variables.
Creating a test run requires permission to access the specified module. Refer to Permissions for more information.
When creating a test run, you may optionally provide a list of variable objects containing key and value attributes. These values apply to that test run specifically and take precedence over variables with the same key that are created within the module. All values must be expressed as an HCL literal in the same syntax you would use when writing Terraform code.
Sample Test Variables:
"attributes": {
"variables": [
{ "key": "replicas", "value": "2" },
{ "key": "access_key", "value": "\"ABCDE12345\"" }
]
}
Request Body
This POST endpoint requires a JSON object with the following properties as a request payload.
Properties without a default value are required.
Key path | Type | Default | Description |
---|---|---|---|
data.attributes.verbose | bool | false | Specifies whether Terraform should print the plan or state for each test run block as it executes. |
data.attributes.test-directory | string | "tests" | Sets the directory where HCP Terraform executes the tests. |
data.attributes.filters | array[string] | (empty array) | When specified, HCP Terraform only executes the test files contained within this array. |
data.attributes.variables | array[{key, value}] | (empty array) | Specifies an optional list of test-specific environment variable values. |
data.relationships.configuration-version.data.id | string | none | Specifies the configuration version that HCP Terraform executes the test against. |
Sample Payload
{
"data": {
"attributes": {
"verbose": true,
"filters": ["tests/test.tftest.hcl"],
"test-directory": "tests",
"variables": [
{ "key" : "number", "value": 4}
]
},
"type":"test-runs"
}
}
Sample Request
curl \
--header "Authorization: Bearer $TOKEN" \
--header "Content-Type: application/vnd.api+json" \
--request POST \
--data @payload.json \
https://app.terraform.io/api/v2/organizations/my-organization/tests/registry-modules/private/my-organization/private/registry-provider/test-runs
Sample Response
{
"data": {
"id": "trun-KFg8DSiRz4E37mdJ",
"type": "test-runs",
"attributes": {
"status": "queued",
"status-timestamps": {
"queued-at": "2023-10-03T18:27:39+00:00"
},
"created-at": "2023-10-03T18:27:39.239Z",
"updated-at": "2023-10-03T18:27:39.264Z",
"test-configurable-type": "RegistryModule",
"test-configurable-id": "mod-9rjVHLCUE9QD3k6L",
"variables": [
{
"key": "number",
"value": "4"
}
],
"filters": [
"tests/test.tftest.hcl"
],
"test-directory": "tests",
"verbose": true,
"test-status": null,
"tests-passed": null,
"tests-failed": null,
"tests-errored": null,
"tests-skipped": null,
"source": "tfe-api",
"message": "Queued manually via the Terraform Enterprise API"
},
"relationships": {
"configuration-version": {
"data": {
"id": "cv-d3zBGFf5DfWY4GY9",
"type": "configuration-versions"
},
"links": {
"related": "/api/v2/configuration-versions/cv-d3zBGFf5DfWY4GY9"
}
},
"created-by": {
"data": {
"id": "user-zsRFs3AGaAHzbEfs",
"type": "users"
},
"links": {
"related": "/api/v2/users/user-zsRFs3AGaAHzbEfs"
}
}
}
}
}
Create a Configuration Version for a Test
POST /organizations/:organization_name/tests/registry-modules/private/:namespace/:name/:provider/test-runs/configuration-versions
Parameter | Description |
---|---|
:organization_name | The name of the organization for the module. The organization must already exist, and the token authenticating the API request must belong to the "owners" team or a member of the "owners" team. |
:namespace | The namespace of the module for which the configuration version is being created. For private modules this is the same as the :organization_name parameter. |
:name | The name of the module for which the configuration version is being created. |
:provider | The name of the provider for which the configuration version is being created. |
Sample Request
curl \
--header "Authorization: Bearer $TOKEN" \
--header "Content-Type: application/vnd.api+json" \
--request POST \
https://app.terraform.io/api/v2/organizations/my-organization/tests/registry-modules/private/my-organization/registry-name/registry-provider/test-runs/configuration-versions
Sample Response
{
"data": {
"id": "cv-aaady7niJMY1wAvx",
"type": "configuration-versions",
"attributes": {
"auto-queue-runs": true,
"error": null,
"error-message": null,
"source": "tfe-api",
"speculative": false,
"status": "pending",
"status-timestamps": {},
"changed-files": [],
"provisional": false,
"upload-url": "https://archivist.terraform.io/v1/object/dmF1bHQ6djM6eFliQ0l1ZEhNUDRMZmdWeExoYWZ1WnFwaCtYQUFSQjFaWVcySkEyT0tyZTZXQ0hjN3ZYQkFvbkJHWkg2Y0U2MDRHRXFvQVl6cUJqQzJ0VkppVHBXTlJNWmpVc1ZTekg5Q1hMZ0hNaUpNdUhib1hGS1RpT3czRGdRaWtPZFZ3VWpDQ1U0S2dhK2xLTUQ2ZFZDaUZ3SktiNytrMlpoVHd0cXdGVHIway8zRkFmejdzMSt0Rm9TNFBTV3dWYjZUTzJVNE1jaW9UZ2VKVFJNRnUvbjBudUp4U0l6VzFDYkNzVVFsb2VFbC9DRFlCTWFsbXBMNzZLUGQxeTJHb09ZTkxHL1d2K1NtcmlEQXptZTh1Q1BwR1dhbVBXQTRiREdlTkI3Qyt1YTRRamFkRzBWYUg3NE52TGpqT1NKbzFrZ3J3QmxnMGhHT3VaTHNhSmo0eXpv"
},
"relationships": {
"ingress-attributes": {
"data": null,
"links": {
"related": "/api/v2/configuration-versions/cv-aaady7niJMY1wAvx/ingress-attributes"
}
}
},
"links": {
"self": "/api/v2/configuration-versions/cv-aaady7niJMY1wAvx"
}
}
}
Upload Configuration Files for a Test
PUT https://archivist.terraform.io/v1/object/<UNIQUE OBJECT ID>
The URL is provided in the upload-url
attribute when creating a configuration-versions
resource. After creation, the URL is hidden on the resource and no longer available.
Sample Request
@filename is the name of the configuration file you wish to upload.
curl \
--header "Content-Type: application/octet-stream" \
--request PUT \
--data-binary @filename \
https://archivist.terraform.io/v1/object/4c44d964-eba7-4dd5-ad29-1ece7b99e8da
List Tests for a Module
GET /organizations/:organization_name/tests/registry-modules/private/:namespace/:name/:provider/test-runs/
Parameter | Description |
---|---|
:organization_name | The name of the organization for the module. The organization must already exist, and the token authenticating the API request must belong to the "owners" team or a member of the "owners" team. |
:namespace | The namespace of the module which the tests have executed against. For private modules this is the same as the :organization_name parameter. |
:name | The name of the module which the tests have executed against. |
:provider | The name of the provider which the tests have executed against. |
Query Parameters
This endpoint supports pagination with standard URL query parameters; remember to percent-encode [
as %5B
and ]
as %5D
if your tooling does not automatically encode URLs.
Parameter | Description | Required |
---|---|---|
page[number] | If omitted, the endpoint returns the first page. | Optional |
page[size] | If omitted, the endpoint returns 20 runs per page. | Optional |
filter[source] | Optional. A comma-separated list of test sources; the result will only include tests that came from one of these sources. Options are listed in Test Sources. |
Sample Request
curl \
--header "Authorization: Bearer $TOKEN" \
--header "Content-Type: application/vnd.api+json" \
https://app.terraform.io/api/v2/organizations/my-organization/tests/registry-modules/private/my-organization/registry-name/registry-provider/test-runs
Sample Response
{
"data": [
{
"id": "trun-KFg8DSiRz4E37mdJ",
"type": "test-runs",
"attributes": {
"status": "finished",
"status-timestamps": {
"queued-at": "2023-10-03T18:27:39+00:00",
"started-at": "2023-10-03T18:27:41+00:00",
"finished-at": "2023-10-03T18:27:53+00:00"
},
"log-read-url": "https://archivist.terraform.io/v1/object/dmF1bHQ6djM6eFliQ0l1ZEhNUDRMZmdWeExoYWZ1WnFwaCtYQUFSQjFaWVcySkEyT0tyZTZXQ0hjN3ZYQkFvbkJHWkg2Y0U2MDRHRXFvQVl6cUJqQzJ0VkppVHBXTlJNWmpVc1ZTekg5Q1hMZ0hNaUpNdUhib1hGS1RpT3czRGdRaWtPZFZ3VWpDQ1U0S2dhK2xLTUQ2ZFZDaUZ3SktiNytrMlpoVHd0cXdGVHIway8zRkFmejdzMSt0Rm9TNFBTV3dWYjZUTzJVNE1jaW9UZ2VKVFJNRnUvbjBudUp4U0l6VzFDYkNzVVFsb2VFbC9DRFlCTWFsbXBMNzZLUGQxeTJHb09ZTkxHL1d2K1NtcmlEQXptZTh1Q1BwR1dhbVBXQTRiREdlTkI3Qyt1YTRRamFkRzBWYUg3NE52TGpqT1NKbzFrZ3J3QmxnMGhHT3VaTHNhSmo0eXpv",
"created-at": "2023-10-03T18:27:39.239Z",
"updated-at": "2023-10-03T18:27:53.574Z",
"test-configurable-type": "RegistryModule",
"test-configurable-id": "mod-9rjVHLCUE9QD3k6L",
"variables": [
{
"key": "number",
"value": "4"
}
],
"filters": [
"tests/test.tftest.hcl"
],
"test-directory": "tests",
"verbose": true,
"test-status": "pass",
"tests-passed": 1,
"tests-failed": 0,
"tests-errored": 0,
"tests-skipped": 0,
"source": "tfe-api",
"message": "Queued manually via the Terraform Enterprise API"
},
"relationships": {
"configuration-version": {
"data": {
"id": "cv-d3zBGFf5DfWY4GY9",
"type": "configuration-versions"
},
"links": {
"related": "/api/v2/configuration-versions/cv-d3zBGFf5DfWY4GY9"
}
},
"created-by": {
"data": {
"id": "user-zsRFs3AGaAHzbEfs",
"type": "users"
},
"links": {
"related": "/api/v2/users/user-zsRFs3AGaAHzbEfs"
}
}
}
},
{...}
]
}
Get Test Details
GET /organizations/:organization_name/tests/registry-modules/private/:namespace/:name/:provider/test-runs/:test_run_id
Parameter | Description |
---|---|
:organization_name | The name of the organization for the module. The organization must already exist, and the token authenticating the API request must belong to the "owners" team or a member of the "owners" team. |
:namespace | The namespace of the module which the test was executed against. For private modules this is the same as the :organization_name parameter. |
:name | The name of the module which the test was executed against. |
:provider | The name of the provider which the test was executed against. |
:test_run_id | The test ID to get. |
Sample Request
curl \
--header "Authorization: Bearer $TOKEN" \
--header "Content-Type: application/vnd.api+json" \
https://app.terraform.io/api/v2/organizations/my-organization/tests/registry-modules/private/my-organization/registry-name/registry-provider/test-runs/trun-xFMAHM3FhkFBL6Z7
Sample Response
{
"data": {
"id": "trun-KFg8DSiRz4E37mdJ",
"type": "test-runs",
"attributes": {
"status": "finished",
"status-timestamps": {
"queued-at": "2023-10-03T18:27:39+00:00",
"started-at": "2023-10-03T18:27:41+00:00",
"finished-at": "2023-10-03T18:27:53+00:00"
},
"log-read-url": "https://archivist.terraform.io/v1/object/dmF1bHQ6djM6eFliQ0l1ZEhNUDRMZmdWeExoYWZ1WnFwaCtYQUFSQjFaWVcySkEyT0tyZTZXQ0hjN3ZYQkFvbkJHWkg2Y0U2MDRHRXFvQVl6cUJqQzJ0VkppVHBXTlJNWmpVc1ZTekg5Q1hMZ0hNaUpNdUhib1hGS1RpT3czRGdRaWtPZFZ3VWpDQ1U0S2dhK2xLTUQ2ZFZDaUZ3SktiNytrMlpoVHd0cXdGVHIway8zRkFmejdzMSt0Rm9TNFBTV3dWYjZUTzJVNE1jaW9UZ2VKVFJNRnUvbjBudUp4U0l6VzFDYkNzVVFsb2VFbC9DRFlCTWFsbXBMNzZLUGQxeTJHb09ZTkxHL1d2K1NtcmlEQXptZTh1Q1BwR1dhbVBXQTRiREdlTkI3Qyt1YTRRamFkRzBWYUg3NE52TGpqT1NKbzFrZ3J3QmxnMGhHT3VaTHNhSmo0eXpv",
"created-at": "2023-10-03T18:27:39.239Z",
"updated-at": "2023-10-03T18:27:53.574Z",
"test-configurable-type": "RegistryModule",
"test-configurable-id": "mod-9rjVHLCUE9QD3k6L",
"variables": [
{
"key": "number",
"value": "4"
}
],
"filters": [
"tests/test.tftest.hcl"
],
"test-directory": "tests",
"verbose": true,
"test-status": "pass",
"tests-passed": 1,
"tests-failed": 0,
"tests-errored": 0,
"tests-skipped": 0,
"source": "tfe-api",
"message": "Queued manually via the Terraform Enterprise API"
},
"relationships": {
"configuration-version": {
"data": {
"id": "cv-d3zBGFf5DfWY4GY9",
"type": "configuration-versions"
},
"links": {
"related": "/api/v2/configuration-versions/cv-d3zBGFf5DfWY4GY9"
}
},
"created-by": {
"data": {
"id": "user-zsRFs3AGaAHzbEfs",
"type": "users"
},
"links": {
"related": "/api/v2/users/user-zsRFs3AGaAHzbEfs"
}
}
}
}
}
Cancel a Test
POST /organizations/:organization_name/tests/registry-modules/private/:namespace/:name/:provider/test-runs/:test_run_id/cancel
Parameter | Description |
---|---|
:organization_name | The name of the organization to create a test in. The organization must already exist, and the token authenticating the API request must belong to the "owners" team or a member of the "owners" team. |
:namespace | The namespace of the module for which the test is being canceled. For private modules this is the same as the :organization_name parameter. |
:name | The name of the module for which the test is being canceled. |
:provider | The name of the provider for which the test is being canceled. |
:test_run_id | The test ID to cancel. |
Use the cancel
action to interrupt a test that is currently running. The action sends an INT
signal to the running Terraform process, which instructs Terraform to safely end the tests and attempt to teardown any infrastructure that your tests create.
Status | Response | Reason(s) |
---|---|---|
202 | none | Successfully queued a cancel request. |
409 | JSON API error object | Test was not running; cancel not allowed. |
404 | JSON API error object | Test was not found or user not authorized. |
Sample Request
curl \
--header "Authorization: Bearer $TOKEN" \
--header "Content-Type: application/vnd.api+json" \
--request POST \
https://app.terraform.io/api/v2/organizations/my-organization/tests/registry-modules/private/my-organization/registry-name/registry-provider/test-runs/trun-xFMAHM3FhkFBL6Z7/cancel
Forcefully cancel a Test
POST /organizations/:organization_name/tests/registry-modules/private/:namespace/:name/:provider/test-runs/:test_run_id/force-cancel
Parameter | Description |
---|---|
:organization_name | The name of the organization for the module. The organization must already exist, and the token authenticating the API request must belong to the owners team or a member of the owners team. |
:namespace | The namespace of the module for which the test is being force-canceled. For private modules this is the same as the :organization_name parameter. |
:name | The name of the module for which the test is being force-canceled. |
:provider | The name of the provider for which the test is being force-canceled. |
:test_run_id | The test ID to cancel. |
The force-cancel
action ends the test immediately. Once invoked, Terraform places the test into a canceled
state and terminates the running Terraform process.
Warning: This endpoint has potentially dangerous side-effects, including loss of any in-flight state in the running Terraform process. Use this operation with extreme caution.
Status | Response | Reason(s) |
---|---|---|
202 | none | Successfully queued a cancel request. |
409 | JSON API error object | Test was not running, or has not been canceled non-forcefully. |
404 | JSON API error object | Test was not found or user not authorized. |
Sample Request
curl \
--header "Authorization: Bearer $TOKEN" \
--header "Content-Type: application/vnd.api+json" \
--request POST \
https://app.terraform.io/api/v2/organizations/my-organization/tests/registry-modules/private/my-organization/registry-name/registry-provider/test-runs/trun-xFMAHM3FhkFBL6Z7/force-cancel
Create an Environment Variable for Module Tests
POST /organizations/:organization_name/tests/registry-modules/private/:namespace/:name/:provider/vars
Parameter | Description |
---|---|
:organization_name | The name of the organization of the module. The organization must already exist, and the token authenticating the API request must belong to the "owners" team or a member of the "owners" team. |
:namespace | The namespace of the module for which the testing environment variable is being created. For private modules this is the same as the :organization_name parameter. |
:name | The name of the module for which the testing environment variable is being created. |
:provider | The name of the provider for which the testing environment variable is being created. |
Request Body
This POST endpoint requires a JSON object with the following properties as a request payload.
Properties without a default value are required.
Key path | Type | Default | Description |
---|---|---|---|
data.type | string | none | Must be "vars" . |
data.attributes.key | string | none | The variable's name. Test variable keys must begin with a letter or underscore and can only contain letters, numbers, and underscores. |
data.attributes.value | string | "" | The value of the variable. |
data.attributes.description | string | none | The description of the variable. |
data.attributes.category | string | none | This must be "env" . |
data.attributes.sensitive | bool | false | Whether the value is sensitive. When set to true , Terraform writes the variable once and is not visible thereafter. |
Sample Payload
{
"data": {
"type":"vars",
"attributes": {
"key":"some_key",
"value":"some_value",
"description":"some description",
"category":"env",
"sensitive":false
}
}
}
Sample Request
curl \
--header "Authorization: Bearer $TOKEN" \
--header "Content-Type: application/vnd.api+json" \
--request POST \
--data @payload.json \
https://app.terraform.io/api/v2/organizations/my-organization/tests/registry-modules/private/my-organization/registry-name/registry-provider/vars
Sample Response
{
"data": {
"id": "var-xSCUzCxdqMs2ygcg",
"type": "vars",
"attributes": {
"key": "keykey",
"value": "some_value",
"sensitive": false,
"category": "env",
"hcl": false,
"created-at": "2023-10-03T19:47:05.393Z",
"description": "some description",
"version-id": "699b14ea5d5e5c02f6352fac6bfd0a1424c21d32be14d1d9eb79f5e1f28f663a"
},
"links": {
"self": "/api/v2/vars/var-xSCUzCxdqMs2ygcg"
}
}
}
List Test Variables for a Module
GET /organizations/:organization_name/tests/registry-modules/private/:namespace/:name/:provider/vars
Parameter | Description |
---|---|
:organization_name | The name of the organization for the module. The organization must already exist, and the token authenticating the API request must belong to the owners team or a member of the owners team. |
:namespace | The namespace of the module which the test environment variables were created for. For private modules this is the same as the :organization_name parameter. |
:name | The name of the module which the test environment variables were created for. |
:provider | The name of the provider which the test environment variables were created for. |
Sample Request
$ curl \
--header "Authorization: Bearer $TOKEN" \
--header "Content-Type: application/vnd.api+json" \
https://app.terraform.io/api/v2/organizations/my-organization/tests/registry-modules/private/my-organization/registry-name/registry-provider/vars
Sample Response
{
"data": [
{
"id": "var-xSCUzCxdqMs2ygcg",
"type": "vars",
"attributes": {
"key": "keykey",
"value": "some_value",
"sensitive": false,
"category": "env",
"hcl": false,
"created-at": "2023-10-03T19:47:05.393Z",
"description": "some description",
"version-id": "699b14ea5d5e5c02f6352fac6bfd0a1424c21d32be14d1d9eb79f5e1f28f663a"
},
"links": {
"self": "/api/v2/vars/var-xSCUzCxdqMs2ygcg"
}
}
]
}
Update Test Variables for a Module
PATCH /organizations/:organization_name/tests/registry-modules/private/:namespace/:name/:provider/vars/variable_id
Parameter | Description |
---|---|
:organization_name | The name of the organization for the module. The organization must already exist, and the token authenticating the API request must belong to the "owners" team or a member of the "owners" team. |
:namespace | The namespace of the module for which the test environment variable is being updated. For private modules this is the same as the :organization_name parameter. |
:name | The name of the module for which the test environment variable is being updated. |
:provider | The name of the provider for which the test environment variable is being updated. |
:variable_id | The ID of the variable to update. |
Request Body
This PATCH endpoint requires a JSON object with the following properties as a request payload.
Properties without a default value are required.
Key path | Type | Default | Description |
---|---|---|---|
data.type | string | Must be "vars" . | |
data.attributes | object | none | New attributes for the variable. This object can include key , value , description , category , and sensitive properties. Refer to Create an Environment Variable for Module Tests for additional information. All properties are optional. |
Sample Payload
{
"data": {
"attributes": {
"key":"name",
"value":"mars",
"description": "new description",
"category":"env",
"sensitive": false
},
"type":"vars"
}
}
Sample Request
$ curl \
--header "Authorization: Bearer $TOKEN" \
--header "Content-Type: application/vnd.api+json" \
--request PATCH \
--data @payload.json \
https://app.terraform.io/api/v2/organizations/my-organization/tests/registry-modules/private/my-organization/registry-name/registry-provider/vars/var-yRmifb4PJj7cLkMG
Sample Response
{
"data": {
"id":"var-yRmifb4PJj7cLkMG",
"type":"vars",
"attributes": {
"key":"name",
"value":"mars",
"description":"new description",
"sensitive":false,
"category":"env",
"hcl":false
}
}
}
Delete Test Variable for a Module
DELETE /organizations/:organization_name/tests/registry-modules/private/:namespace/:name/:provider/vars/variable_id
Parameter | Description |
---|---|
:organization_name | The name of the organization for the module. The organization must already exist, and the token authenticating the API request must belong to the owners team or a member of the owners team. |
:namespace | The namespace of the module for which the test environment variable is being deleted. For private modules this is the same as the :organization_name parameter. |
:name | The name of the module for which the test environment variable is being deleted. |
:provider | The name of the provider for which the test environment variable is being deleted. |
:variable_id | The ID of the variable to delete. |
Sample Request
$ curl \
--header "Authorization: Bearer $TOKEN" \
--header "Content-Type: application/vnd.api+json" \
--request DELETE \
https://app.terraform.io/api/v2/organizations/my-organization/tests/registry-modules/private/my-organization/registry-name/registry-provider/vars/var-yRmifb4PJj7cLkMG