diff --git a/Packs/HashiCorpTerraform/.pack-ignore b/Packs/HashiCorpTerraform/.pack-ignore
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/Packs/HashiCorpTerraform/.secrets-ignore b/Packs/HashiCorpTerraform/.secrets-ignore
new file mode 100644
index 000000000000..a3a577a674b1
--- /dev/null
+++ b/Packs/HashiCorpTerraform/.secrets-ignore
@@ -0,0 +1,2 @@
+https://app.terraform.io
+https://test_url.com
\ No newline at end of file
diff --git a/Packs/HashiCorpTerraform/Author_image.png b/Packs/HashiCorpTerraform/Author_image.png
new file mode 100644
index 000000000000..5536a3be2913
Binary files /dev/null and b/Packs/HashiCorpTerraform/Author_image.png differ
diff --git a/Packs/HashiCorpTerraform/Integrations/HashiCorpTerraform/HashiCorpTerraform.py b/Packs/HashiCorpTerraform/Integrations/HashiCorpTerraform/HashiCorpTerraform.py
new file mode 100644
index 000000000000..77a6bd1ff8c5
--- /dev/null
+++ b/Packs/HashiCorpTerraform/Integrations/HashiCorpTerraform/HashiCorpTerraform.py
@@ -0,0 +1,358 @@
+import demistomock as demisto # noqa: F401
+from CommonServerPython import * # noqa: F401
+from requests import Response
+
+
+RUN_HR_KEY_TO_RES_KEY = {
+ 'Run id': 'id',
+ 'Status': 'attributes.status',
+ 'Plan id': 'relationships.plan.data.id',
+ 'Planned at': 'attributes.status-timestamps.planned-at'
+}
+PLAN_HR_KEY_TO_RES_KEY = {
+ "Plan id": "id",
+ "Status": "attributes.status",
+ "Agent Queued at": "attributes.status-timestamps.agent-queued-at"
+}
+POLICIES_HR_KEY_TO_RES_KEY = {
+ 'Policy id': 'id',
+ 'Policy name': 'attributes.name',
+ 'Policy description': 'attributes.description',
+ 'Kind': 'attributes.kind',
+ 'Policy Set ids': 'relationships.policy-sets.data.id',
+ 'Organization id': 'relationships.organization.data.id'
+}
+SET_HR_KEY_TO_RES_KEY = {
+ 'Policy set id': 'id',
+ 'Policy Set name': 'attributes.name',
+ 'Description': 'attributes.description',
+ 'Organization': 'relationships.organization.data.id',
+ 'Policies ids': 'relationships.policies.data.id',
+ 'Workspaces': 'relationships.workspaces.data.id',
+ 'Projects': 'relationships.projects.data.id'
+}
+CHECK_HR_KEY_TO_RES_KEY = {
+ 'Policy check id': 'id',
+ 'Result': 'attributes.result',
+ 'Status': 'attributes.status',
+ 'Scope ': 'attributes.scope'
+}
+
+
+class Client(BaseClient):
+ def __init__(
+ self, url: str, token: str,
+ default_organization_name: str | None = None,
+ default_workspace_id: str | None = None,
+ verify: bool = True, proxy: bool = False):
+ self._default_organization_name = default_organization_name
+ self._default_workspace_id = default_workspace_id
+
+ headers = {
+ 'Authorization': f'Bearer {token}'
+ }
+ super().__init__(base_url=url, verify=verify, proxy=proxy, headers=headers)
+
+ def test_connection(self):
+ return self._http_request('GET', 'account/details')
+
+ def runs_list_request(self, workspace_id: str | None = None,
+ run_id: str | None = None, filter_status: str | None = None,
+ page_number: str | None = None, page_size: str | None = None) -> dict:
+ params = {}
+ if not run_id:
+ if filter_status:
+ params['filter[status]'] = filter_status
+ if page_number:
+ params['page[number]'] = page_number
+ if page_size:
+ params['page[size]'] = page_size
+
+ workspace_id = workspace_id or self._default_workspace_id
+ if not workspace_id:
+ raise DemistoException(
+ "Please provide either, the instance param 'Default Workspace Id' or the command argument 'workspace_id'"
+ )
+ url_suffix = f'/runs/{run_id}' if run_id else f'/workspaces/{workspace_id}/runs'
+ response = self._http_request('GET', url_suffix, params=params)
+
+ return response
+
+ def run_action(self, run_id: str, action: str, comment: str | None = None) -> Response:
+
+ return self._http_request(
+ 'POST',
+ f'runs/{run_id}/actions/{action}',
+ json_data={'comment': comment} if comment and action != 'force-execute' else None,
+ headers=self._headers | {'Content-Type': 'application/vnd.api+json'},
+ ok_codes=[200, 202, 403, 404, 409],
+ resp_type='response')
+
+ def get_plan(self, plan_id: str, json_output: bool) -> Response:
+ url_suffix = f'/plans/{plan_id}{"/json-output" if json_output else ""}'
+ return self._http_request('GET', url_suffix, resp_type='response')
+
+ def list_policies(self, organization_name: str | None = None, policy_kind: str | None = None,
+ policy_name: str | None = None, policy_id: str | None = None) -> dict:
+
+ params = {}
+ if not policy_id:
+ if policy_kind:
+ params['filter[kind]'] = policy_kind
+ if policy_name:
+ params['search[name]'] = policy_name
+ organization_name = organization_name or self._default_organization_name
+ if not organization_name:
+ raise DemistoException(
+ "Please provide either the instance param '\
+ 'Default Organization Name' or the command argument 'organization_name'")
+
+ url_suffix = f'/policies/{policy_id}' if policy_id else f'/organizations/{organization_name}/policies'
+ response = self._http_request('GET', url_suffix, params=params)
+
+ return response
+
+ def list_policy_sets(self, organization_name: str | None, policy_set_id: str | None,
+ versioned: str | None, policy_set_kind: str | None, include: str | None,
+ policy_set_name: str | None, page_number: str | None,
+ page_size: str | None) -> dict:
+ params: dict[str, str] = {}
+ if not policy_set_id:
+ if versioned:
+ params['filter[versioned]'] = versioned
+ if policy_set_kind:
+ params['filter[kind]'] = policy_set_kind
+ if include:
+ params['include'] = include
+ if policy_set_name:
+ params['search[name]'] = policy_set_name
+ if page_number:
+ params['page[number]'] = page_number
+ if page_size:
+ params['page[size]'] = page_size
+ organization_name = organization_name or self._default_organization_name
+ if not organization_name:
+ raise DemistoException(
+ "Please provide either the instance param 'Default Organization Name'\
+ ' or the command argument 'organization_name'")
+
+ url_suffix = f'/policy-sets/{policy_set_id}' if policy_set_id else f'/organizations/{organization_name}/policy-sets'
+ return self._http_request('GET', url_suffix, params=params)
+
+ def list_policy_checks(self, run_id: str | None, policy_check_id: str | None,
+ page_number: str | None, page_size: str | None) -> dict:
+ """List Terraform policy checks"""
+ params = {}
+ if page_number:
+ params['page[number]'] = page_number
+ if page_size:
+ params['page[size]'] = page_size
+
+ url_suffix = f'/runs/{run_id}/policy-checks' if run_id else f'/policy-checks/{policy_check_id}'
+ return self._http_request('GET', url_suffix, params=params)
+
+
+def runs_list_command(client: Client, args: Dict[str, Any]) -> CommandResults:
+ workspace_id = args.get('workspace_id')
+ run_id = args.get('run_id')
+ filter_status = args.get('filter_status')
+ page_number = args.get('page_number')
+ page_size = args.get('page_size')
+
+ res = client.runs_list_request(workspace_id, run_id, filter_status, page_number, page_size)
+ # when run_id is provided, it returns a single run instead of a list
+ data = [res.get('data', {})] if run_id else res.get('data', [])
+ hr_items = [
+ {hr_key: demisto.get(run, response_key) for hr_key, response_key in RUN_HR_KEY_TO_RES_KEY.items()}
+ for run in data
+ ]
+ command_results = CommandResults(
+ outputs_prefix='Terraform.Run',
+ outputs_key_field='data.id',
+ outputs=res,
+ readable_output=tableToMarkdown('Terraform Runs', hr_items, removeNull=True)
+ )
+
+ return command_results
+
+
+def run_action_command(client: Client, args: Dict[str, Any]) -> str:
+
+ run_id = args.get('run_id')
+ action = args.get('action')
+ comment = args.get('comment')
+
+ if not run_id or not action:
+ raise DemistoException("run_id and action are required")
+
+ if action == 'force-execute' and comment:
+ raise DemistoException("comment parameter is invalid for force-execute action")
+
+ res = client.run_action(
+ run_id=run_id,
+ action=action,
+ comment=comment
+ )
+
+ action_msg = f'queued an {action} request for run id {run_id}'
+ if res.status_code == 202:
+ return f'Successfully {action_msg}'
+ else:
+ raise DemistoException(f'Error occurred when {action_msg}: {res.json().get("errors",[{}])[0].get("title")}')
+
+
+def plan_get_command(client: Client, args: Dict[str, Any]) -> CommandResults | dict[str, Any]:
+ plan_id = args.get('plan_id')
+ json_output = argToBoolean(args.get('json_output', False))
+
+ if not plan_id:
+ raise DemistoException("plan_id is required")
+ res = client.get_plan(plan_id, json_output)
+
+ if json_output:
+ return fileResult(filename=f'{plan_id}.json',
+ data=res.content,
+ file_type=EntryType.ENTRY_INFO_FILE)
+
+ res_json = res.json()
+ plan = res_json.get('data', {})
+ hr_plan = {hr_key: demisto.get(plan, response_key) for hr_key, response_key in PLAN_HR_KEY_TO_RES_KEY.items()}
+
+ command_results = CommandResults(
+ outputs_prefix='Terraform.Plan',
+ outputs_key_field='id',
+ outputs=plan,
+ raw_response=res_json,
+ readable_output=tableToMarkdown('Terraform Plan', hr_plan)
+ )
+
+ return command_results
+
+
+def policies_list_command(client: Client, args: Dict[str, Any]) -> CommandResults:
+ organization_name = args.get('organization_name')
+ policy_kind = args.get('policy_kind')
+ policy_name = args.get('policy_name')
+ policy_id = args.get('policy_id')
+
+ res = client.list_policies(organization_name, policy_kind, policy_name, policy_id)
+ # when policy_id is provided, it returns a single policy instead of a list
+ data = [res.get('data', {})] if policy_id else res.get('data', [])
+ hr_items = [
+ {hr_key: demisto.dt(policy, response_key) for hr_key, response_key in POLICIES_HR_KEY_TO_RES_KEY.items()}
+ for policy in data
+ ]
+
+ command_results = CommandResults(
+ outputs_prefix='Terraform.Policy',
+ outputs_key_field='id',
+ outputs=data,
+ raw_response=res,
+ readable_output=tableToMarkdown('Terraform Policies', hr_items, removeNull=True)
+ )
+
+ return command_results
+
+
+def policy_set_list_command(client: Client, args: Dict[str, Any]) -> CommandResults:
+ organization_name = args.get('organization_name')
+ policy_set_id = args.get('policy_set_id')
+ versioned = args.get('versioned')
+ policy_set_kind = args.get('policy_set_kind')
+ include = args.get('include')
+ policy_set_name = args.get('policy_set_name')
+ page_number = args.get('page_number')
+ page_size = args.get('page_size')
+
+ res = client.list_policy_sets(organization_name, policy_set_id, versioned,
+ policy_set_kind, include, policy_set_name,
+ page_number, page_size)
+ # when policy_set_id is provided, it returns a single policy set instead of a list
+ data = [res.get('data', {})] if policy_set_id else res.get('data', [])
+ hr_items = [
+ {hr_key: demisto.dt(policy_set, response_key) for hr_key, response_key in SET_HR_KEY_TO_RES_KEY.items()}
+ for policy_set in data
+ ]
+
+ return CommandResults(
+ outputs_prefix='Terraform.PolicySet',
+ outputs_key_field='id',
+ outputs=data,
+ raw_response=res,
+ readable_output=tableToMarkdown('Terraform Policy Sets', hr_items, removeNull=True)
+ )
+
+
+def policies_checks_list_command(client: Client, args: Dict[str, Any]) -> CommandResults:
+ run_id = args.get('run_id')
+ policy_check_id = args.get('policy_check_id')
+ page_number = args.get('page_number')
+ page_size = args.get('page_size')
+
+ res = client.list_policy_checks(run_id, policy_check_id, page_number, page_size)
+
+ # when policy_check_id is provided, it returns a single check instead of a list
+ data = [res.get('data', {})] if policy_check_id else res.get('data', [])
+ hr_items = [
+ {hr_key: demisto.get(policy_check, response_key) for hr_key, response_key in CHECK_HR_KEY_TO_RES_KEY.items()}
+ for policy_check in data
+ ]
+
+ return CommandResults(
+ outputs_prefix='Terraform.PolicyCheck',
+ outputs_key_field='id',
+ outputs=data,
+ raw_response=res,
+ readable_output=tableToMarkdown('Terraform Policy Checks', hr_items, removeNull=True)
+ )
+
+
+def test_module(client: Client) -> str:
+ try:
+ client.test_connection()
+ except Exception as e:
+ if 'Unauthorized' in str(e):
+ raise DemistoException('Unauthorized: Please be sure you put a valid API Token')
+ raise e
+ return 'ok'
+
+
+def main() -> None:
+
+ params: Dict[str, Any] = demisto.params()
+ args: Dict[str, Any] = demisto.args()
+ url = params.get('server_url', 'https://app.terraform.io/api/v2').rstrip('/')
+ token = params.get('credentials', {}).get('password')
+ default_workspace_id = params.get('default_workspace_id')
+ default_organization_name = params.get('default_organization_name')
+ verify_certificate: bool = not params.get('insecure', False)
+ proxy = params.get('proxy', False)
+
+ command = demisto.command()
+ demisto.debug(f'Command being called is {command}')
+
+ try:
+ client: Client = Client(url, token, default_organization_name, default_workspace_id, verify_certificate, proxy)
+
+ commands = {
+ 'terraform-runs-list': runs_list_command,
+ 'terraform-run-action': run_action_command,
+ 'terraform-plan-get': plan_get_command,
+ 'terraform-policies-list': policies_list_command,
+ 'terraform-policy-set-list': policy_set_list_command,
+ 'terraform-policies-checks-list': policies_checks_list_command,
+ }
+
+ if command == 'test-module':
+ return_results(test_module(client))
+ elif command in commands:
+ return_results(commands[command](client, args))
+ else:
+ raise NotImplementedError(f'{command} command is not implemented.')
+
+ except Exception as e:
+ return_error(str(e))
+
+
+if __name__ in ['__main__', 'builtin', 'builtins']:
+ main()
diff --git a/Packs/HashiCorpTerraform/Integrations/HashiCorpTerraform/HashiCorpTerraform.yml b/Packs/HashiCorpTerraform/Integrations/HashiCorpTerraform/HashiCorpTerraform.yml
new file mode 100644
index 000000000000..0125fdfb39bc
--- /dev/null
+++ b/Packs/HashiCorpTerraform/Integrations/HashiCorpTerraform/HashiCorpTerraform.yml
@@ -0,0 +1,627 @@
+commonfields:
+ id: HashicorpTerraform
+ version: -1
+configuration:
+- display: Server URL
+ name: server_url
+ required: true
+ type: 0
+ defaultvalue: https://app.terraform.io/api/v2
+ section: Connect
+- displaypassword: API Token
+ additionalinfo: The API Key to use for connection.
+ name: credentials
+ required: true
+ hiddenusername: true
+ type: 9
+ section: Connect
+- display: Default Organization Name
+ name: default_organization_name
+ type: 0
+ required: false
+ section: Connect
+ additionalinfo: There is an option to override with a command input parameter. If not provided, policy commands should require the organization name.
+- display: Default Workspace ID
+ name: default_workspace_id
+ type: 0
+ required: false
+ section: Collect
+ additionalinfo: There is an option to override with an input parameter. If not provided, some commands should require the workspace ID.
+- display: Trust any certificate (not secure)
+ name: insecure
+ type: 8
+ required: false
+- display: Use system proxy settings
+ name: proxy
+ type: 8
+ required: false
+name: HashicorpTerraform
+display: HashiCorp Terraform
+category: IT Services
+description: Hashicorp Terraform provide infrastructure automation to provision and manage resources in any cloud or data center with Terraform.
+script:
+ commands:
+ - name: terraform-runs-list
+ description: List runs in a workspace.
+ arguments:
+ - name: workspace_id
+ description: The workspace ID to list runs for.
+ - name: run_id
+ description: The run ID to get a specific run.
+ - name: filter_status
+ description: The run status to filter by.
+ auto: PREDEFINED
+ predefined:
+ - pending
+ - fetching
+ - fetching_completed
+ - pre_plan_running
+ - pre_plan_completed
+ - queuing
+ - plan_queued
+ - planning
+ - planned
+ - cost_estimating
+ - cost_estimated
+ - policy_checking
+ - policy_override
+ - policy_soft_failed
+ - policy_checked
+ - confirmed
+ - post_plan_running
+ - post_plan_completed
+ - planned_and_finished
+ - planned_and_saved
+ - apply_queued
+ - applying
+ - applied
+ - discarded
+ - errored
+ - canceled
+ - force_canceled
+ - name: page_number
+ description: The page number of the results to return. Default is 1.
+ - name: page_size
+ description: The number of results to return per page. Default is 20, maximum is 100.
+ outputs:
+ - contextPath: Terraform.Run.data.id
+ type: String
+ description: The run ID.
+ - contextPath: Terraform.Run.data.attributes.status
+ type: String
+ description: The run status.
+ - contextPath: Terraform.Run.data.relationships.plan.data.id
+ type: String
+ description: The plan ID.
+ - contextPath: Terraform.Run.data.attributes.status-timestamps.planned-at
+ type: Date
+ description: The datetime the plan was planned.
+ - contextPath: Terraform.Run.data.type
+ description: THe run type.
+ type: String
+ - contextPath: Terraform.Run.data.attributes.actions.is-cancelable
+ description: Flag indicating whether the Terraform run can be canceled.
+ type: Boolean
+ - contextPath: Terraform.Run.data.attributes.actions.is-confirmable
+ description: Flag indicating whether the Terraform run can be confirmed.
+ type: Boolean
+ - contextPath: Terraform.Run.data.attributes.actions.is-discardable
+ description: Flag indicating whether the Terraform run can be discarded.
+ type: Boolean
+ - contextPath: Terraform.Run.data.attributes.actions.is-force-cancelable
+ description: Flag indicating whether the Terraform run can be force-canceled.
+ type: Boolean
+ - contextPath: Terraform.Run.data.attributes.canceled-at
+ description: Timestamp indicating when the Terraform run was canceled.
+ type: Unknown
+ - contextPath: Terraform.Run.data.attributes.created-at
+ description: Timestamp indicating when the Terraform run was created.
+ type: Date
+ - contextPath: Terraform.Run.data.attributes.has-changes
+ description: Flag indicating whether there are changes in the Terraform run.
+ type: Boolean
+ - contextPath: Terraform.Run.data.attributes.auto-apply
+ description: Flag indicating whether auto-apply is enabled for the Terraform run.
+ type: Boolean
+ - contextPath: Terraform.Run.data.attributes.allow-empty-apply
+ description: Flag indicating whether empty apply is allowed for the Terraform run.
+ type: Boolean
+ - contextPath: Terraform.Run.data.attributes.allow-config-generation
+ description: Flag indicating whether configuration generation is allowed for the Terraform run.
+ type: Boolean
+ - contextPath: Terraform.Run.data.attributes.is-destroy
+ description: Flag indicating whether the Terraform run is a destroy operation.
+ type: Boolean
+ - contextPath: Terraform.Run.data.attributes.message
+ description: Text message associated with the Terraform run.
+ type: String
+ - contextPath: Terraform.Run.data.attributes.plan-only
+ description: Flag indicating whether the Terraform run is for planning only.
+ type: Boolean
+ - contextPath: Terraform.Run.data.attributes.source
+ description: Source of the Terraform run.
+ type: String
+ - contextPath: Terraform.Run.data.attributes.status-timestamps.plan-queueable-at
+ description: Timestamp indicating when the Terraform run is queueable in the plan stage.
+ type: Date
+ - contextPath: Terraform.Run.data.attributes.trigger-reason
+ description: Reason for triggering the Terraform run.
+ type: String
+ - contextPath: Terraform.Run.data.attributes.target-addrs
+ description: Target addresses associated with the Terraform run.
+ type: Unknown
+ - contextPath: Terraform.Run.data.attributes.permissions.can-apply
+ description: Flag indicating whether the user has permission to apply changes.
+ type: Boolean
+ - contextPath: Terraform.Run.data.attributes.permissions.can-cancel
+ description: Flag indicating whether the user has permission to cancel the Terraform run.
+ type: Boolean
+ - contextPath: Terraform.Run.data.attributes.permissions.can-comment
+ description: Flag indicating whether the user has permission to add comments.
+ type: Boolean
+ - contextPath: Terraform.Run.data.attributes.permissions.can-discard
+ description: Flag indicating whether the user has permission to discard the Terraform run.
+ type: Boolean
+ - contextPath: Terraform.Run.data.attributes.permissions.can-force-execute
+ description: Flag indicating whether the user has permission to force execute the Terraform run.
+ type: Boolean
+ - contextPath: Terraform.Run.data.attributes.permissions.can-force-cancel
+ description: Flag indicating whether the user has permission to force cancel the Terraform run.
+ type: Boolean
+ - contextPath: Terraform.Run.data.attributes.permissions.can-override-policy-check
+ description: Flag indicating whether the user has permission to override policy checks.
+ type: Boolean
+ - contextPath: Terraform.Run.data.attributes.refresh
+ description: Flag indicating whether the Terraform run should perform a refresh.
+ type: Boolean
+ - contextPath: Terraform.Run.data.attributes.refresh-only
+ description: Flag indicating whether the Terraform run is for refresh only.
+ type: Boolean
+ - contextPath: Terraform.Run.data.attributes.replace-addrs
+ description: Replacement addresses associated with the Terraform run.
+ type: Unknown
+ - contextPath: Terraform.Run.data.attributes.save-plan
+ description: Flag indicating whether the Terraform run plan should be saved.
+ type: Boolean
+ - contextPath: Terraform.Run.data.attributes.variables
+ description: Variables associated with the Terraform run.
+ type: Unknown
+ - contextPath: Terraform.Run.data.relationships.apply.data.id
+ description: The apply ID of the run.
+ type: String
+ - contextPath: Terraform.Run.data.relationships.comments
+ description: Relationship information for comments associated with the Terraform run.
+ type: String
+ - contextPath: Terraform.Run.data.relationships.configuration-version
+ description: Relationship information for the Terraform configuration version associated with the run.
+ type: String
+ - contextPath: Terraform.Run.data.relationships.cost-estimate
+ description: Relationship information for cost estimates associated with the Terraform run.
+ type: String
+ - contextPath: Terraform.Run.data.relationships.created-by
+ description: Relationship information for the user who created the Terraform run.
+ type: String
+ - contextPath: Terraform.Run.data.relationships.input-state-version
+ description: Relationship information for the input state version associated with the Terraform run.
+ type: String
+ - contextPath: Terraform.Run.data.relationships.run-events
+ description: Relationship information for events associated with the Terraform run.
+ type: String
+ - contextPath: Terraform.Run.data.relationships.policy-checks
+ description: Relationship information for policy checks associated with the Terraform run.
+ type: String
+ - contextPath: Terraform.Run.data.relationships.workspace
+ description: Relationship information for the Terraform workspace associated with the run.
+ type: String
+ - contextPath: Terraform.Run.data.relationships.workspace-run-alerts
+ description: Relationship information for alerts associated with the Terraform workspace run.
+ type: String
+ - contextPath: Terraform.Run.data.links.self
+ description: Link to the Terraform run data.
+ type: String
+ - name: terraform-run-action
+ arguments:
+ - name: run_id
+ required: true
+ description: The Terraform run ID to execute the action on.
+ - name: action
+ auto: PREDEFINED
+ required: true
+ predefined:
+ - apply
+ - cancel
+ - discard
+ - force-cancel
+ - force-execute
+ description: The action to execute on the Terraform run.
+ - name: comment
+ description: An optional comment to associate with the action. Not available for the action "force-execute".
+ description: 'Perform an action on a Terraform run. The available actions are: apply, cancel, discard, force-cancel, force-execute.'
+ - name: terraform-plan-get
+ arguments:
+ - name: plan_id
+ required: true
+ description: The ID of the Terraform plan to retrieve.
+ - name: json_output
+ description: Whether to return the plan as a JSON fileResult.
+ auto: PREDEFINED
+ predefined:
+ - "true"
+ - "false"
+ defaultValue: "false"
+ outputs:
+ - contextPath: Terraform.Plan.id
+ type: String
+ description: The plan ID.
+ - contextPath: Terraform.Plan.attributes.status
+ type: String
+ description: The plan status.
+ - contextPath: Terraform.Plan.type
+ description: Type of the Terraform plan data.
+ type: String
+ - contextPath: Terraform.Plan.attributes.has-changes
+ description: Flag indicating whether the Terraform plan has changes.
+ type: Boolean
+ - contextPath: Terraform.Plan.attributes.status-timestamps.started-at
+ description: Timestamp indicating when the Terraform plan started.
+ type: Date
+ - contextPath: Terraform.Plan.attributes.status-timestamps.finished-at
+ description: Timestamp indicating when the Terraform plan finished.
+ type: Date
+ - contextPath: Terraform.Plan.attributes.status-timestamps.agent-queued-at
+ description: Timestamp indicating when the Terraform plan was queued for an agent.
+ type: Date
+ - contextPath: Terraform.Plan.attributes.log-read-url
+ description: URL for reading the Terraform plan log.
+ type: String
+ - contextPath: Terraform.Plan.attributes.resource-additions
+ description: Number of resource additions in the Terraform plan.
+ type: Number
+ - contextPath: Terraform.Plan.attributes.resource-changes
+ description: Number of resource changes in the Terraform plan.
+ type: Number
+ - contextPath: Terraform.Plan.attributes.resource-destructions
+ description: Number of resource destructions in the Terraform plan.
+ type: Number
+ - contextPath: Terraform.Plan.attributes.resource-imports
+ description: Number of resource imports in the Terraform plan.
+ type: Number
+ - contextPath: Terraform.Plan.attributes.structured-run-output-enabled
+ description: Flag indicating whether structured run output is enabled in the Terraform plan.
+ type: Boolean
+ - contextPath: Terraform.Plan.attributes.generated-configuration
+ description: Flag indicating whether the Terraform plan has generated configuration.
+ type: Boolean
+ - contextPath: Terraform.Plan.attributes.actions.is-exportable
+ description: Flag indicating whether the Terraform plan is exportable.
+ type: Boolean
+ - contextPath: Terraform.Plan.attributes.execution-details.mode
+ description: Execution mode details for the Terraform plan.
+ type: String
+ - contextPath: Terraform.Plan.attributes.permissions.can-export
+ description: Flag indicating whether the user has permission to export the Terraform plan.
+ type: Boolean
+ - contextPath: Terraform.Plan.relationships.state-versions.data
+ description: Relationship information for state versions associated with the Terraform plan.
+ type: Unknown
+ - contextPath: Terraform.Plan.relationships.exports.data
+ description: Relationship information for exports associated with the Terraform plan.
+ type: Unknown
+ - contextPath: Terraform.Plan.links.self
+ description: Link to the Terraform plan data.
+ type: String
+ - contextPath: Terraform.Plan.links.json-output
+ description: Link to the JSON output of the Terraform plan.
+ type: String
+ - contextPath: Terraform.Plan.links.json-output-redacted
+ description: Link to the redacted JSON output of the Terraform plan.
+ type: String
+ - contextPath: Terraform.Plan.links.json-schema
+ description: Link to the JSON schema of the Terraform plan.
+ type: String
+ description: Get the plan JSON file or the plan meta data.
+ - name: terraform-policies-list
+ description: List the policies for an organization or get a specific policy.
+ arguments:
+ - name: organization_name
+ description: The name of the organization.
+ - name: policy_kind
+ description: If specified, restricts results to those with the matching policy kind value.
+ auto: PREDEFINED
+ predefined:
+ - sentinel
+ - opa
+ - name: policy_name
+ description: If specified, search the organization's policies by name.
+ - name: policy_id
+ description: If specified, get the specific policy.
+ outputs:
+ - contextPath: Terraform.Policy.id
+ description: The policy ID.
+ type: String
+ - contextPath: Terraform.Policy.type
+ description: The policy type.
+ type: String
+ - contextPath: Terraform.Policy.attributes.name
+ description: Name of the Terraform policy.
+ type: String
+ - contextPath: Terraform.Policy.attributes.description
+ description: Description of the Terraform policy.
+ type: Unknown
+ - contextPath: Terraform.Policy.attributes.enforce.path
+ description: Path for enforcing the Terraform policy.
+ type: String
+ - contextPath: Terraform.Policy.attributes.enforce.mode
+ description: Enforcement mode for the Terraform policy.
+ type: String
+ - contextPath: Terraform.Policy.attributes.policy-set-count
+ description: Count of policy sets associated with the Terraform policy.
+ type: Number
+ - contextPath: Terraform.Policy.attributes.updated-at
+ description: Timestamp indicating when the Terraform policy was last updated.
+ type: Date
+ - contextPath: Terraform.Policy.attributes.kind
+ description: Kind of the Terraform policy.
+ type: String
+ - contextPath: Terraform.Policy.attributes.enforcement-level
+ description: Enforcement level for the Terraform policy.
+ type: String
+ - contextPath: Terraform.Policy.relationships.organization.data.id
+ description: Unique identifier for the organization associated with the Terraform policy.
+ type: String
+ - contextPath: Terraform.Policy.relationships.organization.data.type
+ description: Type of the organization associated with the Terraform policy.
+ type: String
+ - contextPath: Terraform.Policy.relationships.policy-sets.data.id
+ description: The IDs of the policy sets that contain this policy.
+ type: String
+ - contextPath: Terraform.Policy.relationships.policy-sets.data.type
+ description: Type of the policy sets associated with the Terraform policy.
+ type: String
+ - contextPath: Terraform.Policy.links.self
+ description: Link to the Terraform policy data.
+ type: String
+ - contextPath: Terraform.Policy.links.upload
+ description: Link for uploading the Terraform policy.
+ type: String
+ - contextPath: Terraform.Policy.links.download
+ description: Link for downloading the Terraform policy.
+ type: String
+ - contextPath: Terraform.Policy.links.self
+ description: Link to the Terraform policy.
+ type: String
+ - contextPath: Terraform.Policy.links.first
+ description: Link to the first page of Terraform policies.
+ type: String
+ - contextPath: Terraform.Policy.links.prev
+ description: Link to the previous page of Terraform policies.
+ type: Unknown
+ - contextPath: Terraform.Policy.links.next
+ description: Link to the next page of Terraform policies.
+ type: Unknown
+ - contextPath: Terraform.Policy.links.last
+ description: Link to the last page of Terraform policies.
+ type: String
+ - contextPath: Terraform.Policy.meta.pagination.current-page
+ description: Current page number in the pagination of Terraform policies.
+ type: Number
+ - contextPath: Terraform.Policy.meta.pagination.page-size
+ description: Number of policies displayed per page in pagination.
+ type: Number
+ - contextPath: Terraform.Policy.meta.pagination.prev-page
+ description: Previous page number in the pagination of Terraform policies.
+ type: Unknown
+ - contextPath: Terraform.Policy.meta.pagination.next-page
+ description: Next page number in the pagination of Terraform policies.
+ type: Unknown
+ - contextPath: Terraform.Policy.meta.pagination.total-pages
+ description: Total number of pages in the pagination of Terraform policies.
+ type: Number
+ - contextPath: Terraform.Policy.meta.pagination.total-count
+ description: Total count of Terraform policies.
+ type: Number
+ - name: terraform-policy-set-list
+ description: List the policy sets for an organization or get a specific policy set.
+ arguments:
+ - name: organization_name
+ required: false
+ description: The name of the organization.
+ - name: policy_set_id
+ description: If specified, get the specific policy set.
+ - name: versioned
+ description: Allows filtering policy sets based on whether they are versioned, or use individual policy relationships. A true value returns versioned sets, and a false value returns sets with individual policy relationships. If omitted, all policy sets are returned.
+ auto: PREDEFINED
+ predefined:
+ - "true"
+ - "false"
+ - name: policy_set_kind
+ description: If specified, restricts results to those with the matching policy kind value.
+ auto: PREDEFINED
+ predefined:
+ - sentinel
+ - opa
+ - name: include
+ description: Enables you to include related resource data. Value must be a comma-separated list containing one or more projects, workspaces, workspace-exclusions, policies, newest_version, or current_version.
+ - name: policy_set_name
+ description: Allows searching the organization's policy sets by name.
+ - name: page_number
+ description: The page number of the results to return. Default is 1.
+ - name: page_size
+ description: The number of results to return per page. Default is 20, maximum is 100.
+ outputs:
+ - contextPath: Terraform.PolicySet.id
+ description: The policy set ID.
+ type: String
+ - contextPath: Terraform.PolicySet.type
+ description: The policy set type.
+ type: String
+ - contextPath: Terraform.PolicySet.attributes.name
+ description: Name of the Terraform policy set.
+ type: String
+ - contextPath: Terraform.PolicySet.attributes.description
+ description: Description of the Terraform policy set.
+ type: Unknown
+ - contextPath: Terraform.PolicySet.attributes.global
+ description: Flag indicating whether the Terraform policy set is global.
+ type: Boolean
+ - contextPath: Terraform.PolicySet.attributes.workspace-count
+ description: Number of workspaces associated with the Terraform policy set.
+ type: Number
+ - contextPath: Terraform.PolicySet.attributes.project-count
+ description: Number of projects associated with the Terraform policy set.
+ type: Number
+ - contextPath: Terraform.PolicySet.attributes.created-at
+ description: Timestamp indicating when the Terraform policy set was created.
+ type: Date
+ - contextPath: Terraform.PolicySet.attributes.updated-at
+ description: Timestamp indicating when the Terraform policy set was last updated.
+ type: Date
+ - contextPath: Terraform.PolicySet.attributes.kind
+ description: Kind of the Terraform policy set.
+ type: String
+ - contextPath: Terraform.PolicySet.attributes.agent-enabled
+ description: Flag indicating whether the Terraform policy set has agents enabled.
+ type: Boolean
+ - contextPath: Terraform.PolicySet.attributes.policy-count
+ description: Number of policies associated with the Terraform policy set.
+ type: Number
+ - contextPath: Terraform.PolicySet.attributes.versioned
+ description: Flag indicating whether the Terraform policy set is versioned.
+ type: Boolean
+ - contextPath: Terraform.PolicySet.relationships.organization.data.id
+ description: ID of the organization associated with the Terraform policy set.
+ type: String
+ - contextPath: Terraform.PolicySet.relationships.organization.data.type
+ description: Type of the organization associated with the Terraform policy set.
+ type: String
+ - contextPath: Terraform.PolicySet.relationships.policies.data.id
+ description: ID of the policies associated with the Terraform policy set.
+ type: String
+ - contextPath: Terraform.PolicySet.relationships.policies.data.type
+ description: Type of the policies associated with the Terraform policy set.
+ type: String
+ - contextPath: Terraform.PolicySet.relationships.workspaces.data.id
+ description: ID of the workspaces associated with the Terraform policy set.
+ type: String
+ - contextPath: Terraform.PolicySet.relationships.workspaces.data.type
+ description: Type of the workspaces associated with the Terraform policy set.
+ type: String
+ - contextPath: Terraform.PolicySet.relationships.projects.data.id
+ description: Relationship information for projects associated with the Terraform policy set.
+ type: String
+ - contextPath: Terraform.PolicySet.relationships.workspace-exclusions.data
+ description: Relationship information for workspace exclusions associated with the Terraform policy set.
+ type: Unknown
+ - contextPath: Terraform.PolicySet.links.self
+ description: Link to the Terraform policy set data.
+ type: String
+ - contextPath: Terraform.PolicySet.links.self
+ description: Link to the Terraform policy set.
+ type: String
+ - contextPath: Terraform.PolicySet.links.first
+ description: Link to the first page of Terraform policy sets.
+ type: String
+ - contextPath: Terraform.PolicySet.links.prev
+ description: Link to the previous page of Terraform policy sets.
+ type: Unknown
+ - contextPath: Terraform.PolicySet.links.next
+ description: Link to the next page of Terraform policy sets.
+ type: Unknown
+ - contextPath: Terraform.PolicySet.links.last
+ description: Link to the last page of Terraform policy sets.
+ type: String
+ - contextPath: Terraform.PolicySet.meta.pagination.current-page
+ description: Current page number in the pagination of Terraform policy sets.
+ type: Number
+ - contextPath: Terraform.PolicySet.meta.pagination.page-size
+ description: Number of items per page in the pagination of Terraform policy sets.
+ type: Number
+ - contextPath: Terraform.PolicySet.meta.pagination.prev-page
+ description: Link to the previous page in the pagination of Terraform policy sets.
+ type: Unknown
+ - contextPath: Terraform.PolicySet.meta.pagination.next-page
+ description: Link to the next page in the pagination of Terraform policy sets.
+ type: Unknown
+ - contextPath: Terraform.PolicySet.meta.pagination.total-pages
+ description: Total number of pages in the pagination of Terraform policy sets.
+ type: Number
+ - contextPath: Terraform.PolicySet.meta.pagination.total-count
+ description: Total number of Terraform policy sets.
+ type: Number
+ - name: terraform-policies-checks-list
+ description: List the policy checks for a Terraform run.
+ arguments:
+ - name: run_id
+ description: The run ID to list results for.
+ - name: policy_check_id
+ description: The policy check ID to retrieve details for.
+ - name: page_number
+ description: The page number of the results to return. Default is 1.
+ - name: page_size
+ description: The number of results to return per page. Default is 20, maximum is 100.
+ outputs:
+ - contextPath: Terraform.PolicyCheck.id
+ description: The policy check ID.
+ type: String
+ - contextPath: Terraform.PolicyCheck.type
+ description: Type of the Terraform policy check data.
+ type: String
+ - contextPath: Terraform.PolicyCheck.attributes.result.result
+ description: Overall result of the Terraform policy check.
+ type: Boolean
+ - contextPath: Terraform.PolicyCheck.attributes.result.passed
+ description: Number of policy checks that passed.
+ type: Number
+ - contextPath: Terraform.PolicyCheck.attributes.result.total-failed
+ description: Total number of policy checks that failed.
+ type: Number
+ - contextPath: Terraform.PolicyCheck.attributes.result.hard-failed
+ description: Number of policy checks that resulted in hard failures.
+ type: Number
+ - contextPath: Terraform.PolicyCheck.attributes.result.soft-failed
+ description: Number of policy checks that resulted in soft failures.
+ type: Number
+ - contextPath: Terraform.PolicyCheck.attributes.result.advisory-failed
+ description: Number of policy checks that resulted in advisory failures.
+ type: Number
+ - contextPath: Terraform.PolicyCheck.attributes.result.duration-ms
+ description: Duration of the policy check execution in milliseconds.
+ type: Number
+ - contextPath: Terraform.PolicyCheck.attributes.result.sentinel
+ description: Sentinel-specific result of the policy check.
+ type: Unknown
+ - contextPath: Terraform.PolicyCheck.attributes.scope
+ description: Scope or context of the Terraform policy check.
+ type: String
+ - contextPath: Terraform.PolicyCheck.attributes.status
+ description: Status of the Terraform policy check.
+ type: String
+ - contextPath: Terraform.PolicyCheck.attributes.status-timestamps.queued-at
+ description: Timestamp indicating when the Terraform policy check was queued.
+ type: Date
+ - contextPath: Terraform.PolicyCheck.attributes.status-timestamps.soft-failed-at
+ description: Timestamp indicating when the Terraform policy check encountered a soft failure.
+ type: Date
+ - contextPath: Terraform.PolicyCheck.attributes.actions.is-overridable
+ description: Flag indicating whether the Terraform policy check is overridable.
+ type: Boolean
+ - contextPath: Terraform.PolicyCheck.attributes.permissions.can-override
+ description: Flag indicating whether the user has permission to override the Terraform policy check.
+ type: Boolean
+ - contextPath: Terraform.PolicyCheck.relationships.run.data.id
+ description: Unique identifier for the Terraform run associated with the policy check.
+ type: String
+ - contextPath: Terraform.PolicyCheck.relationships.run.data.type
+ description: Type of the Terraform run associated with the policy check.
+ type: String
+ - contextPath: Terraform.PolicyCheck.links.output
+ description: Link to the output of the Terraform policy check.
+ type: String
+ runonce: false
+ script: '-'
+ type: python
+ subtype: python3
+ dockerimage: demisto/python3:3.10.13.83255
+fromversion: 6.10.0
+tests:
+- No tests (auto formatted)
diff --git a/Packs/HashiCorpTerraform/Integrations/HashiCorpTerraform/HashiCorpTerraform_description.md b/Packs/HashiCorpTerraform/Integrations/HashiCorpTerraform/HashiCorpTerraform_description.md
new file mode 100644
index 000000000000..3263290dffc5
--- /dev/null
+++ b/Packs/HashiCorpTerraform/Integrations/HashiCorpTerraform/HashiCorpTerraform_description.md
@@ -0,0 +1,10 @@
+## HashiCorp Terraform Help
+
+
+**Note:**
+There are 3 different types of tokens - Organization, User, Team
+A customer should use a User or Team token that has admin level access to the workspace.
+For details, see [HashiCorp API Tokens](https://developer.hashicorp.com/terraform/cloud-docs/users-teams-organizations/api-tokens).
+
+- *Default Workspace ID* can be taken from *Projects & workspaces* within the selected organization.
+- *Default Organization Name* can be taken from the organizations listed in [organizations](https://app.terraform.io/app/organizations).
diff --git a/Packs/HashiCorpTerraform/Integrations/HashiCorpTerraform/HashiCorpTerraform_image.png b/Packs/HashiCorpTerraform/Integrations/HashiCorpTerraform/HashiCorpTerraform_image.png
new file mode 100644
index 000000000000..5536a3be2913
Binary files /dev/null and b/Packs/HashiCorpTerraform/Integrations/HashiCorpTerraform/HashiCorpTerraform_image.png differ
diff --git a/Packs/HashiCorpTerraform/Integrations/HashiCorpTerraform/HashiCorpTerraform_test.py b/Packs/HashiCorpTerraform/Integrations/HashiCorpTerraform/HashiCorpTerraform_test.py
new file mode 100644
index 000000000000..bc8c563f9361
--- /dev/null
+++ b/Packs/HashiCorpTerraform/Integrations/HashiCorpTerraform/HashiCorpTerraform_test.py
@@ -0,0 +1,159 @@
+import pytest
+from CommonServerPython import *
+from HashiCorpTerraform import Client, runs_list_command, \
+ run_action_command, plan_get_command, policies_list_command, policy_set_list_command, policies_checks_list_command
+import re
+SERVER_URL = 'https://test_url.com'
+
+
+def util_load_json(path):
+ with open(path, encoding='utf-8') as f:
+ return json.loads(f.read())
+
+
+@pytest.fixture()
+def client():
+ return Client(
+ url=SERVER_URL, token=None,
+ default_organization_name=None, default_workspace_id=None,
+ verify=None, proxy=None)
+
+
+def test_runs_list_command(client, requests_mock):
+ """
+ Given:
+ - Client object.
+ When:
+ - run the list runs command.
+ Then:
+ - validate the results are as expected.
+ """
+ mock_response = util_load_json('./test_data/runs_list_request.json')['mock_response']
+ requests_mock.get(re.compile(f'{SERVER_URL}.*'), json=mock_response)
+ expected_results = util_load_json('./test_data/runs_list_request.json')['expected_results']
+
+ results = runs_list_command(client=client, args={'workspace_id': 'workspace_id'})
+
+ assert results.to_context() == expected_results
+
+
+def test_run_action_command(client, requests_mock):
+ """
+ Given:
+ - Client object.
+ When:
+ - error occurred when run the run action command.
+ Then:
+ - validate the exception raised as expected.
+ """
+ mock_response = util_load_json('./test_data/run_action_request.json')['mock_response']
+ requests_mock.post(re.compile(f'{SERVER_URL}.*'), json=mock_response, status_code=409)
+
+ run_id = 'run-ABCABCABCABCABCa'
+ with pytest.raises(DemistoException) as err:
+ run_action_command(client=client, args={
+ 'run_id': run_id,
+ 'action': 'apply', 'comment': 'comment'
+ })
+ assert f'Error occurred when queued an apply request for run id {run_id}' in str(err)
+
+
+def test_plan_get_command(client, requests_mock):
+ """
+ Given:
+ - Client object.
+ When:
+ - run the get plan command to get the plan meta data.
+ Then:
+ - validate the results are as expected.
+ """
+ args = {'plan_id': 'plan-Abcabcabcabcabc4'}
+
+ mock_response = util_load_json('./test_data/plan_get_request.json')['mock_response']
+ expected_results = util_load_json('./test_data/plan_get_request.json')['expected_results']
+
+ requests_mock.get(re.compile(f'{SERVER_URL}.*'), json=mock_response)
+ results = plan_get_command(client=client, args=args)
+ assert results.to_context() == expected_results
+
+
+def test_policies_list_command(client, requests_mock, mocker):
+ """
+ Given:
+ - Client object.
+ When:
+ - run the get policies list command.
+ Then:
+ - validate the results are as expected.
+ """
+ organization_name = 'organization_name'
+ args = {'organization_name': organization_name}
+
+ mock_response = util_load_json('./test_data/policies_list_request.json')['mock_response']
+ expected_results = util_load_json('./test_data/policies_list_request.json')['expected_results']
+
+ requests_mock.get(f'{SERVER_URL}/organizations/{organization_name}/policies', json=mock_response)
+ mocker.patch.object(demisto, 'dt', side_effect=lambda _, key: key)
+
+ results = policies_list_command(client=client, args=args)
+ assert results.to_context() == expected_results
+
+
+def test_policy_set_list_command(client, requests_mock, mocker):
+ """
+ Given:
+ - Client object.
+ When:
+ - run the get policy set list command.
+ Then:
+ - validate the results are as expected.
+ """
+
+ organization_name = 'organization_name'
+ args = {'organization_name': organization_name}
+
+ mock_response = util_load_json('./test_data/policy_set_list_request.json')['mock_response']
+ expected_results = util_load_json('./test_data/policy_set_list_request.json')['expected_results']
+
+ requests_mock.get(f'{SERVER_URL}/organizations/{organization_name}/policy-sets', json=mock_response)
+ mocker.patch.object(demisto, 'dt', side_effect=lambda _, key: key)
+ results = policy_set_list_command(client=client, args=args)
+ assert results.to_context() == expected_results
+
+
+def test_policies_checks_list_command(client, requests_mock):
+ """
+ Given:
+ - Client object.
+ When:
+ - run the get policies checks list command.
+ Then:
+ - validate the results are as expected.
+ """
+ run_id = 'run-abcabcabcabcabc1'
+ args = {'run_id': run_id}
+
+ mock_response = util_load_json('./test_data/policies_check_list_request.json')['mock_response']
+ expected_results = util_load_json('./test_data/policies_check_list_request.json')['expected_results']
+
+ requests_mock.get(f'{SERVER_URL}/runs/{run_id}/policy-checks', json=mock_response)
+ results = policies_checks_list_command(client=client, args=args)
+ assert results.to_context() == expected_results
+
+
+def test_test_module_command(client, mocker):
+ """
+ Given:
+ - Client object with error occurred in test_connection.
+ When:
+ - run the test module command.
+ Then:
+ - validate the expected exception.
+ """
+ import HashiCorpTerraform
+ mocker.patch.object(client, 'test_connection', side_effect=Exception('Unauthorized'))
+
+ with pytest.raises(DemistoException) as err:
+ HashiCorpTerraform.test_module(client)
+
+ assert 'Unauthorized: Please be sure you put a valid API Token' in str(err)
diff --git a/Packs/HashiCorpTerraform/Integrations/HashiCorpTerraform/README.md b/Packs/HashiCorpTerraform/Integrations/HashiCorpTerraform/README.md
new file mode 100644
index 000000000000..11f87ab3ca36
--- /dev/null
+++ b/Packs/HashiCorpTerraform/Integrations/HashiCorpTerraform/README.md
@@ -0,0 +1,753 @@
+Hashicorp Terraform provide infrastructure automation to provision and manage resources in any cloud or data center with Terraform.
+This integration was integrated and tested with version v1.4.4 of HashicorpTerraform.
+
+## Configure HashiCorp Terraform on Cortex XSOAR
+
+1. Navigate to **Settings** > **Integrations** > **Servers & Services**.
+2. Search for HashiCorp Terraform.
+3. Click **Add instance** to create and configure a new integration instance.
+
+ | **Parameter** | **Description** | **Required** |
+ | --- | --- | --- |
+ | Server URL | | True |
+ | API Token | The API Key to use for connection. | True |
+ | Default Organization Name | There is an option to override with a command input parameter. If not provided, policy commands should require the organization name. | False |
+ | Default Workspace ID | There is an option to override with an input parameter. If not provided, some commands should require the workspace ID. | False |
+ | Trust any certificate (not secure) | | False |
+ | Use system proxy settings | | False |
+
+4. Click **Test** to validate the URLs, token, and connection.
+
+## Commands
+
+You can execute these commands from the Cortex XSOAR CLI, as part of an automation, or in a playbook.
+After you successfully execute a command, a DBot message appears in the War Room with the command details.
+
+### terraform-runs-list
+
+***
+List runs in a workspace.
+
+#### Base Command
+
+`terraform-runs-list`
+
+#### Input
+
+| **Argument Name** | **Description** | **Required** |
+| --- | --- | --- |
+| workspace_id | The workspace ID to list runs for. | Optional |
+| run_id | The run ID to get a specific run. | Optional |
+| filter_status | The run status to filter by. Possible values are: pending, fetching, fetching_completed, pre_plan_running, pre_plan_completed, queuing, plan_queued, planning, planned, cost_estimating, cost_estimated, policy_checking, policy_override, policy_soft_failed, policy_checked, confirmed, post_plan_running, post_plan_completed, planned_and_finished, planned_and_saved, apply_queued, applying, applied, discarded, errored, canceled, force_canceled. | Optional |
+| page_number | The page number of the results to return. Default is 1. | Optional |
+| page_size | The number of results to return per page. Default is 20, maximum is 100. | Optional |
+
+#### Context Output
+
+| **Path** | **Type** | **Description** |
+| --- | --- | --- |
+| Terraform.Run.data.id | String | The run ID. |
+| Terraform.Run.data.attributes.status | String | The run status. |
+| Terraform.Run.data.relationships.plan.data.id | String | The plan ID. |
+| Terraform.Run.data.attributes.status-timestamps.planned-at | Date | The datetime the plan was planned. |
+| Terraform.Run.data.type | String | THe run type. |
+| Terraform.Run.data.attributes.actions.is-cancelable | Boolean | Flag indicating whether the Terraform run can be canceled. |
+| Terraform.Run.data.attributes.actions.is-confirmable | Boolean | Flag indicating whether the Terraform run can be confirmed. |
+| Terraform.Run.data.attributes.actions.is-discardable | Boolean | Flag indicating whether the Terraform run can be discarded. |
+| Terraform.Run.data.attributes.actions.is-force-cancelable | Boolean | Flag indicating whether the Terraform run can be force-canceled. |
+| Terraform.Run.data.attributes.canceled-at | Unknown | Timestamp indicating when the Terraform run was canceled. |
+| Terraform.Run.data.attributes.created-at | Date | Timestamp indicating when the Terraform run was created. |
+| Terraform.Run.data.attributes.has-changes | Boolean | Flag indicating whether there are changes in the Terraform run. |
+| Terraform.Run.data.attributes.auto-apply | Boolean | Flag indicating whether auto-apply is enabled for the Terraform run. |
+| Terraform.Run.data.attributes.allow-empty-apply | Boolean | Flag indicating whether empty apply is allowed for the Terraform run. |
+| Terraform.Run.data.attributes.allow-config-generation | Boolean | Flag indicating whether configuration generation is allowed for the Terraform run. |
+| Terraform.Run.data.attributes.is-destroy | Boolean | Flag indicating whether the Terraform run is a destroy operation. |
+| Terraform.Run.data.attributes.message | String | Text message associated with the Terraform run. |
+| Terraform.Run.data.attributes.plan-only | Boolean | Flag indicating whether the Terraform run is for planning only. |
+| Terraform.Run.data.attributes.source | String | Source of the Terraform run. |
+| Terraform.Run.data.attributes.status-timestamps.plan-queueable-at | Date | Timestamp indicating when the Terraform run is queueable in the plan stage. |
+| Terraform.Run.data.attributes.trigger-reason | String | Reason for triggering the Terraform run. |
+| Terraform.Run.data.attributes.target-addrs | Unknown | Target addresses associated with the Terraform run. |
+| Terraform.Run.data.attributes.permissions.can-apply | Boolean | Flag indicating whether the user has permission to apply changes. |
+| Terraform.Run.data.attributes.permissions.can-cancel | Boolean | Flag indicating whether the user has permission to cancel the Terraform run. |
+| Terraform.Run.data.attributes.permissions.can-comment | Boolean | Flag indicating whether the user has permission to add comments. |
+| Terraform.Run.data.attributes.permissions.can-discard | Boolean | Flag indicating whether the user has permission to discard the Terraform run. |
+| Terraform.Run.data.attributes.permissions.can-force-execute | Boolean | Flag indicating whether the user has permission to force execute the Terraform run. |
+| Terraform.Run.data.attributes.permissions.can-force-cancel | Boolean | Flag indicating whether the user has permission to force cancel the Terraform run. |
+| Terraform.Run.data.attributes.permissions.can-override-policy-check | Boolean | Flag indicating whether the user has permission to override policy checks. |
+| Terraform.Run.data.attributes.refresh | Boolean | Flag indicating whether the Terraform run should perform a refresh. |
+| Terraform.Run.data.attributes.refresh-only | Boolean | Flag indicating whether the Terraform run is for refresh only. |
+| Terraform.Run.data.attributes.replace-addrs | Unknown | Replacement addresses associated with the Terraform run. |
+| Terraform.Run.data.attributes.save-plan | Boolean | Flag indicating whether the Terraform run plan should be saved. |
+| Terraform.Run.data.attributes.variables | Unknown | Variables associated with the Terraform run. |
+| Terraform.Run.data.relationships.apply.data.id | String | The apply ID of the run. |
+| Terraform.Run.data.relationships.comments | String | Relationship information for comments associated with the Terraform run. |
+| Terraform.Run.data.relationships.configuration-version | String | Relationship information for the Terraform configuration version associated with the run. |
+| Terraform.Run.data.relationships.cost-estimate | String | Relationship information for cost estimates associated with the Terraform run. |
+| Terraform.Run.data.relationships.created-by | String | Relationship information for the user who created the Terraform run. |
+| Terraform.Run.data.relationships.input-state-version | String | Relationship information for the input state version associated with the Terraform run. |
+| Terraform.Run.data.relationships.run-events | String | Relationship information for events associated with the Terraform run. |
+| Terraform.Run.data.relationships.policy-checks | String | Relationship information for policy checks associated with the Terraform run. |
+| Terraform.Run.data.relationships.workspace | String | Relationship information for the Terraform workspace associated with the run. |
+| Terraform.Run.data.relationships.workspace-run-alerts | String | Relationship information for alerts associated with the Terraform workspace run. |
+| Terraform.Run.data.links.self | String | Link to the Terraform run data. |
+
+#### Command example
+```!terraform-runs-list```
+#### Context Example
+```json
+{
+ "Terraform": {
+ "Run": {
+ "data": [
+ {
+ "attributes": {
+ "actions": {
+ "is-cancelable": false,
+ "is-confirmable": true,
+ "is-discardable": true,
+ "is-force-cancelable": false
+ },
+ "allow-config-generation": false,
+ "allow-empty-apply": false,
+ "auto-apply": false,
+ "canceled-at": null,
+ "created-at": "2023-12-17T10:23:43.258Z",
+ "has-changes": true,
+ "is-destroy": false,
+ "message": "Triggered via UI",
+ "permissions": {
+ "can-apply": true,
+ "can-cancel": true,
+ "can-comment": true,
+ "can-discard": true,
+ "can-force-cancel": true,
+ "can-force-execute": true,
+ "can-override-policy-check": true
+ },
+ "plan-only": false,
+ "refresh": true,
+ "refresh-only": false,
+ "replace-addrs": [
+ "fakewebservices_load_balancer.primary_lb"
+ ],
+ "save-plan": false,
+ "source": "tfe-ui",
+ "status": "planned",
+ "status-timestamps": {
+ "plan-queueable-at": "2023-12-17T10:23:43+00:00",
+ "plan-queued-at": "2023-12-17T10:23:43+00:00",
+ "planned-at": "2023-12-17T10:23:52+00:00",
+ "planning-at": "2023-12-17T10:23:48+00:00",
+ "queuing-at": "2023-12-17T10:23:43+00:00"
+ },
+ "target-addrs": null,
+ "terraform-version": "1.4.4",
+ "trigger-reason": "manual",
+ "variables": []
+ },
+ "id": "run-8wpCneWr4TLSzfat",
+ "links": {
+ "self": "/api/v2/runs/run-8wpCneWr4TLSzfat"
+ },
+ "relationships": {
+ "apply": {
+ "data": {
+ "id": "apply-uEYtCmrtg5MvjgTr",
+ "type": "applies"
+ },
+ "links": {
+ "related": "/api/v2/runs/run-8wpCneWr4TLSzfat/apply"
+ }
+ },
+ "comments": {
+ "data": [],
+ "links": {
+ "related": "/api/v2/runs/run-8wpCneWr4TLSzfat/comments"
+ }
+ },
+ "configuration-version": {
+ "data": {
+ "id": "cv-YDcZaBNiRbrdy1w1",
+ "type": "configuration-versions"
+ },
+ "links": {
+ "related": "/api/v2/runs/run-8wpCneWr4TLSzfat/configuration-version"
+ }
+ },
+ "created-by": {
+ "data": {
+ "id": "user-LR5kedWrdZXBWF71",
+ "type": "users"
+ },
+ "links": {
+ "related": "/api/v2/runs/run-8wpCneWr4TLSzfat/created-by"
+ }
+ },
+ "plan": {
+ "data": {
+ "id": "plan-T7zpGYFEioRfWEAq",
+ "type": "plans"
+ },
+ "links": {
+ "related": "/api/v2/runs/run-8wpCneWr4TLSzfat/plan"
+ }
+ },
+ "policy-checks": {
+ "data": [],
+ "links": {
+ "related": "/api/v2/runs/run-8wpCneWr4TLSzfat/policy-checks"
+ }
+ },
+ "run-events": {
+ "data": [
+ {
+ "id": "re-ga2h6eu41RqrmZRn",
+ "type": "run-events"
+ },
+ {
+ "id": "re-ciqzHkW3bDooRzcn",
+ "type": "run-events"
+ },
+ {
+ "id": "re-ENvbqnmE72YFj7Wq",
+ "type": "run-events"
+ },
+ {
+ "id": "re-xkz1fSTKM25GxkMk",
+ "type": "run-events"
+ }
+ ],
+ "links": {
+ "related": "/api/v2/runs/run-8wpCneWr4TLSzfat/run-events"
+ }
+ },
+ "task-stages": {
+ "data": [],
+ "links": {
+ "related": "/api/v2/runs/run-8wpCneWr4TLSzfat/task-stages"
+ }
+ },
+ "workspace": {
+ "data": {
+ "id": "ws-ZTbNWsfXHRWRVNmE",
+ "type": "workspaces"
+ }
+ }
+ },
+ "type": "runs"
+ }
+ ],
+ "links": {
+ "first": "https://app.terraform.io/api/v2/workspaces/ws-ZTbNWsfXHRWRVNmE/runs?page%5Bnumber%5D=1&page%5Bsize%5D=20",
+ "last": "https://app.terraform.io/api/v2/workspaces/ws-ZTbNWsfXHRWRVNmE/runs?page%5Bnumber%5D=1&page%5Bsize%5D=20",
+ "next": null,
+ "prev": null,
+ "self": "https://app.terraform.io/api/v2/workspaces/ws-ZTbNWsfXHRWRVNmE/runs?page%5Bnumber%5D=1&page%5Bsize%5D=20"
+ },
+ "meta": {
+ "pagination": {
+ "current-page": 1,
+ "next-page": null,
+ "page-size": 20,
+ "prev-page": null,
+ "total-count": 9,
+ "total-pages": 1
+ },
+ "status-counts": {
+ "applied": 1,
+ "apply-queued": 0,
+ "applying": 0,
+ "assessed": 0,
+ "assessing": 0,
+ "canceled": 2,
+ "confirmed": 0,
+ "cost-estimated": 0,
+ "cost-estimating": 0,
+ "discarded": 4,
+ "errored": 0,
+ "fetching": 0,
+ "fetching-completed": 0,
+ "pending": 0,
+ "plan-queued": 0,
+ "planned": 1,
+ "planned-and-finished": 4,
+ "planned-and-saved": 0,
+ "planning": 0,
+ "policy-checked": 0,
+ "policy-checking": 0,
+ "policy-override": 0,
+ "policy-soft-failed": 0,
+ "post-apply-completed": 0,
+ "post-apply-running": 0,
+ "post-plan-awaiting-decision": 0,
+ "post-plan-completed": 0,
+ "post-plan-running": 0,
+ "pre-apply-awaiting-decision": 0,
+ "pre-apply-completed": 0,
+ "pre-apply-running": 0,
+ "pre-plan-awaiting-decision": 0,
+ "pre-plan-completed": 0,
+ "pre-plan-running": 0,
+ "queuing": 0,
+ "queuing-apply": 0,
+ "total": 12
+ }
+ }
+ }
+ }
+}
+```
+
+#### Human Readable Output
+
+>### Terraform Runs
+>|Plan id|Planned at|Run id|Status|
+>|---|---|---|---|
+>| plan-T7zpGYFEioRfWEAq | 2023-12-17T10:23:52+00:00 | run-8wpCneWr4TLSzfat | planned |
+>| plan-1JUTBdedobs1Absf | 2023-12-11T11:35:35+00:00 | run-kMNQfAmoDr1k8eaT | discarded |
+>| plan-21bfTFiDJ6Rz1VTZ | | run-jb2j5r3gBievUPfR | canceled |
+>| plan-twBdAcLwiGwuE7kt | 2023-12-11T11:29:38+00:00 | run-g7ihSa71hCV9yZt7 | discarded |
+>| plan-JEgrv5aBeNUDDRaA | 2023-12-11T11:12:04+00:00 | run-yCYvcx1ZEmmKGXnB | discarded |
+>| plan-kJLmtoaywxkXM54P | 2023-12-11T09:11:48+00:00 | run-akCRvcJ6L5cQtAhc | discarded |
+>| plan-ZunKDF28KpCyiZAn | 2023-12-10T07:10:08+00:00 | run-rpSjBkbhiKAfMuwX | planned_and_finished |
+>| plan-V4fvpvCzGQrsZikD | 2023-11-30T09:21:42+00:00 | run-Q2kS54r6pJjdyYfk | planned_and_finished |
+>| plan-ZYYZD69ESo16jENX | 2023-10-25T10:33:11+00:00 | run-wBdFQ6egn91GGRne | applied |
+
+
+### terraform-run-action
+
+***
+Perform an action on a Terraform run. The available actions are: apply, cancel, discard, force-cancel, force-execute.
+
+#### Base Command
+
+`terraform-run-action`
+
+#### Input
+
+| **Argument Name** | **Description** | **Required** |
+| --- | --- | --- |
+| run_id | The Terraform run ID to execute the action on. | Required |
+| action | The action to execute on the Terraform run. Possible values are: apply, cancel, discard, force-cancel, force-execute. | Required |
+| comment | An optional comment to associate with the action. Not available for the action "force-execute". | Optional |
+
+#### Context Output
+
+There is no context output for this command.
+#### Command example
+```!terraform-run-action run_id=run-8wpCneWr4TLSzfat action="discard" comment="test comment"```
+#### Human Readable Output
+
+>Successfully queued an discard request for run id run-8wpCneWr4TLSzfat
+
+### terraform-plan-get
+
+***
+Get the plan JSON file or the plan meta data.
+
+#### Base Command
+
+`terraform-plan-get`
+
+#### Input
+
+| **Argument Name** | **Description** | **Required** |
+| --- | --- | --- |
+| plan_id | The ID of the Terraform plan to retrieve. | Required |
+| json_output | Whether to return the plan as a JSON fileResult. Possible values are: true, false. Default is false. | Optional |
+
+#### Context Output
+
+| **Path** | **Type** | **Description** |
+| --- | --- | --- |
+| Terraform.Plan.id | String | The plan ID. |
+| Terraform.Plan.attributes.status | String | The plan status. |
+| Terraform.Plan.type | String | Type of the Terraform plan data. |
+| Terraform.Plan.attributes.has-changes | Boolean | Flag indicating whether the Terraform plan has changes. |
+| Terraform.Plan.attributes.status-timestamps.started-at | Date | Timestamp indicating when the Terraform plan started. |
+| Terraform.Plan.attributes.status-timestamps.finished-at | Date | Timestamp indicating when the Terraform plan finished. |
+| Terraform.Plan.attributes.status-timestamps.agent-queued-at | Date | Timestamp indicating when the Terraform plan was queued for an agent. |
+| Terraform.Plan.attributes.log-read-url | String | URL for reading the Terraform plan log. |
+| Terraform.Plan.attributes.resource-additions | Number | Number of resource additions in the Terraform plan. |
+| Terraform.Plan.attributes.resource-changes | Number | Number of resource changes in the Terraform plan. |
+| Terraform.Plan.attributes.resource-destructions | Number | Number of resource destructions in the Terraform plan. |
+| Terraform.Plan.attributes.resource-imports | Number | Number of resource imports in the Terraform plan. |
+| Terraform.Plan.attributes.structured-run-output-enabled | Boolean | Flag indicating whether structured run output is enabled in the Terraform plan. |
+| Terraform.Plan.attributes.generated-configuration | Boolean | Flag indicating whether the Terraform plan has generated configuration. |
+| Terraform.Plan.attributes.actions.is-exportable | Boolean | Flag indicating whether the Terraform plan is exportable. |
+| Terraform.Plan.attributes.execution-details.mode | String | Execution mode details for the Terraform plan. |
+| Terraform.Plan.attributes.permissions.can-export | Boolean | Flag indicating whether the user has permission to export the Terraform plan. |
+| Terraform.Plan.relationships.state-versions.data | Unknown | Relationship information for state versions associated with the Terraform plan. |
+| Terraform.Plan.relationships.exports.data | Unknown | Relationship information for exports associated with the Terraform plan. |
+| Terraform.Plan.links.self | String | Link to the Terraform plan data. |
+| Terraform.Plan.links.json-output | String | Link to the JSON output of the Terraform plan. |
+| Terraform.Plan.links.json-output-redacted | String | Link to the redacted JSON output of the Terraform plan. |
+| Terraform.Plan.links.json-schema | String | Link to the JSON schema of the Terraform plan. |
+
+#### Command example
+```!terraform-plan-get plan_id=plan-V4fvpvCzGQrsZikD```
+#### Context Example
+```json
+{
+ "Terraform": {
+ "Plan": {
+ "attributes": {
+ "actions": {
+ "is-exportable": true
+ },
+ "execution-details": {
+ "mode": "remote"
+ },
+ "generated-configuration": false,
+ "has-changes": false,
+ "log-read-url": "url",
+ "permissions": {
+ "can-export": true
+ },
+ "resource-additions": 0,
+ "resource-changes": 0,
+ "resource-destructions": 0,
+ "resource-imports": 0,
+ "status": "finished",
+ "status-timestamps": {
+ "agent-queued-at": "2023-11-30T09:21:33+00:00",
+ "finished-at": "2023-11-30T09:21:41+00:00",
+ "started-at": "2023-11-30T09:21:37+00:00"
+ },
+ "structured-run-output-enabled": true
+ },
+ "id": "plan-V4fvpvCzGQrsZikD",
+ "links": {
+ "json-output": "/api/v2/plans/plan-V4fvpvCzGQrsZikD/json-output",
+ "json-output-redacted": "/api/v2/plans/plan-V4fvpvCzGQrsZikD/json-output-redacted",
+ "json-schema": "/api/v2/plans/plan-V4fvpvCzGQrsZikD/json-schema",
+ "self": "/api/v2/plans/plan-V4fvpvCzGQrsZikD"
+ },
+ "relationships": {
+ "exports": {
+ "data": []
+ },
+ "state-versions": {
+ "data": []
+ }
+ },
+ "type": "plans"
+ }
+ }
+}
+```
+
+#### Human Readable Output
+
+>### Terraform Plan
+>|Agent Queued at|Plan id|Status|
+>|---|---|---|
+>| 2023-11-30T09:21:33+00:00 | plan-V4fvpvCzGQrsZikD | finished |
+
+
+#### Command example
+```!terraform-plan-get plan_id=plan-V4fvpvCzGQrsZikD json_output="true"```
+#### Context Example
+```json
+{
+ "InfoFile": {
+ "EntryID": "375@03d8b507-a516-4959-8133-979b2d80a807",
+ "Extension": "json",
+ "Info": "application/json",
+ "Name": "plan-V4fvpvCzGQrsZikD.json",
+ "Size": 3686,
+ "Type": "JSON data"
+ }
+}
+```
+
+#### Human Readable Output
+
+
+
+### terraform-policies-list
+
+***
+List the policies for an organization or get a specific policy.
+
+#### Base Command
+
+`terraform-policies-list`
+
+#### Input
+
+| **Argument Name** | **Description** | **Required** |
+| --- | --- | --- |
+| organization_name | The name of the organization. | Optional |
+| policy_kind | If specified, restricts results to those with the matching policy kind value. Possible values are: sentinel, opa. | Optional |
+| policy_name | If specified, search the organization's policies by name. | Optional |
+| policy_id | If specified, get the specific policy. | Optional |
+
+#### Context Output
+
+| **Path** | **Type** | **Description** |
+| --- | --- | --- |
+| Terraform.Policy.id | String | The policy ID. |
+| Terraform.Policy.type | String | The policy type. |
+| Terraform.Policy.attributes.name | String | Name of the Terraform policy. |
+| Terraform.Policy.attributes.description | Unknown | Description of the Terraform policy. |
+| Terraform.Policy.attributes.enforce.path | String | Path for enforcing the Terraform policy. |
+| Terraform.Policy.attributes.enforce.mode | String | Enforcement mode for the Terraform policy. |
+| Terraform.Policy.attributes.policy-set-count | Number | Count of policy sets associated with the Terraform policy. |
+| Terraform.Policy.attributes.updated-at | Date | Timestamp indicating when the Terraform policy was last updated. |
+| Terraform.Policy.attributes.kind | String | Kind of the Terraform policy. |
+| Terraform.Policy.attributes.enforcement-level | String | Enforcement level for the Terraform policy. |
+| Terraform.Policy.relationships.organization.data.id | String | Unique identifier for the organization associated with the Terraform policy. |
+| Terraform.Policy.relationships.organization.data.type | String | Type of the organization associated with the Terraform policy. |
+| Terraform.Policy.relationships.policy-sets.data.id | String | The IDs of the policy sets that contain this policy. |
+| Terraform.Policy.relationships.policy-sets.data.type | String | Type of the policy sets associated with the Terraform policy. |
+| Terraform.Policy.links.self | String | Link to the Terraform policy data. |
+| Terraform.Policy.links.upload | String | Link for uploading the Terraform policy. |
+| Terraform.Policy.links.download | String | Link for downloading the Terraform policy. |
+| Terraform.Policy.links.self | String | Link to the Terraform policy. |
+| Terraform.Policy.links.first | String | Link to the first page of Terraform policies. |
+| Terraform.Policy.links.prev | Unknown | Link to the previous page of Terraform policies. |
+| Terraform.Policy.links.next | Unknown | Link to the next page of Terraform policies. |
+| Terraform.Policy.links.last | String | Link to the last page of Terraform policies. |
+| Terraform.Policy.meta.pagination.current-page | Number | Current page number in the pagination of Terraform policies. |
+| Terraform.Policy.meta.pagination.page-size | Number | Number of policies displayed per page in pagination. |
+| Terraform.Policy.meta.pagination.prev-page | Unknown | Previous page number in the pagination of Terraform policies. |
+| Terraform.Policy.meta.pagination.next-page | Unknown | Next page number in the pagination of Terraform policies. |
+| Terraform.Policy.meta.pagination.total-pages | Number | Total number of pages in the pagination of Terraform policies. |
+| Terraform.Policy.meta.pagination.total-count | Number | Total count of Terraform policies. |
+
+#### Command example
+```!terraform-policies-list```
+#### Context Example
+```json
+{
+ "Terraform": {
+ "Policy": {
+ "attributes": {
+ "description": null,
+ "enforce": [
+ {
+ "mode": "hard-mandatory",
+ "path": "nat-policies.sentinel"
+ }
+ ],
+ "enforcement-level": "hard-mandatory",
+ "kind": "sentinel",
+ "name": "nat-policies",
+ "policy-set-count": 1,
+ "updated-at": "2023-11-14T18:12:36.702Z"
+ },
+ "id": "pol-ycCqXorxsFjaH5aK",
+ "links": {
+ "download": "/api/v2/policies/pol-ycCqXorxsFjaH5aK/download",
+ "self": "/api/v2/policies/pol-ycCqXorxsFjaH5aK",
+ "upload": "/api/v2/policies/pol-ycCqXorxsFjaH5aK/upload"
+ },
+ "relationships": {
+ "organization": {
+ "data": {
+ "id": "example-org-40dc3b",
+ "type": "organizations"
+ }
+ },
+ "policy-sets": {
+ "data": [
+ {
+ "id": "polset-hc2bvqDW8YRgHEt8",
+ "type": "policy-sets"
+ }
+ ]
+ }
+ },
+ "type": "policies"
+ }
+ }
+}
+```
+
+#### Human Readable Output
+
+>### Terraform Policies
+>|Kind|Organization id|Policy Set ids|Policy id|Policy name|
+>|---|---|---|---|---|
+>| sentinel | example-org-40dc3b | polset-hc2bvqDW8YRgHEt8 | pol-ycCqXorxsFjaH5aK | nat-policies |
+
+
+### terraform-policy-set-list
+
+***
+List the policy sets for an organization or get a specific policy set.
+
+#### Base Command
+
+`terraform-policy-set-list`
+
+#### Input
+
+| **Argument Name** | **Description** | **Required** |
+| --- | --- | --- |
+| organization_name | The name of the organization. | Optional |
+| policy_set_id | If specified, get the specific policy set. | Optional |
+| versioned | Allows filtering policy sets based on whether they are versioned, or use individual policy relationships. A true value returns versioned sets, and a false value returns sets with individual policy relationships. If omitted, all policy sets are returned. Possible values are: true, false. | Optional |
+| policy_set_kind | If specified, restricts results to those with the matching policy kind value. Possible values are: sentinel, opa. | Optional |
+| include | Enables you to include related resource data. Value must be a comma-separated list containing one or more projects, workspaces, workspace-exclusions, policies, newest_version, or current_version. | Optional |
+| policy_set_name | Allows searching the organization's policy sets by name. | Optional |
+| page_number | The page number of the results to return. Default is 1. | Optional |
+| page_size | The number of results to return per page. Default is 20, maximum is 100. | Optional |
+
+#### Context Output
+
+| **Path** | **Type** | **Description** |
+| --- | --- | --- |
+| Terraform.PolicySet.id | String | The policy set ID. |
+| Terraform.PolicySet.type | String | The policy set type. |
+| Terraform.PolicySet.attributes.name | String | Name of the Terraform policy set. |
+| Terraform.PolicySet.attributes.description | Unknown | Description of the Terraform policy set. |
+| Terraform.PolicySet.attributes.global | Boolean | Flag indicating whether the Terraform policy set is global. |
+| Terraform.PolicySet.attributes.workspace-count | Number | Number of workspaces associated with the Terraform policy set. |
+| Terraform.PolicySet.attributes.project-count | Number | Number of projects associated with the Terraform policy set. |
+| Terraform.PolicySet.attributes.created-at | Date | Timestamp indicating when the Terraform policy set was created. |
+| Terraform.PolicySet.attributes.updated-at | Date | Timestamp indicating when the Terraform policy set was last updated. |
+| Terraform.PolicySet.attributes.kind | String | Kind of the Terraform policy set. |
+| Terraform.PolicySet.attributes.agent-enabled | Boolean | Flag indicating whether the Terraform policy set has agents enabled. |
+| Terraform.PolicySet.attributes.policy-count | Number | Number of policies associated with the Terraform policy set. |
+| Terraform.PolicySet.attributes.versioned | Boolean | Flag indicating whether the Terraform policy set is versioned. |
+| Terraform.PolicySet.relationships.organization.data.id | String | ID of the organization associated with the Terraform policy set. |
+| Terraform.PolicySet.relationships.organization.data.type | String | Type of the organization associated with the Terraform policy set. |
+| Terraform.PolicySet.relationships.policies.data.id | String | ID of the policies associated with the Terraform policy set. |
+| Terraform.PolicySet.relationships.policies.data.type | String | Type of the policies associated with the Terraform policy set. |
+| Terraform.PolicySet.relationships.workspaces.data.id | String | ID of the workspaces associated with the Terraform policy set. |
+| Terraform.PolicySet.relationships.workspaces.data.type | String | Type of the workspaces associated with the Terraform policy set. |
+| Terraform.PolicySet.relationships.projects.data.id | String | Relationship information for projects associated with the Terraform policy set. |
+| Terraform.PolicySet.relationships.workspace-exclusions.data | Unknown | Relationship information for workspace exclusions associated with the Terraform policy set. |
+| Terraform.PolicySet.links.self | String | Link to the Terraform policy set data. |
+| Terraform.PolicySet.links.self | String | Link to the Terraform policy set. |
+| Terraform.PolicySet.links.first | String | Link to the first page of Terraform policy sets. |
+| Terraform.PolicySet.links.prev | Unknown | Link to the previous page of Terraform policy sets. |
+| Terraform.PolicySet.links.next | Unknown | Link to the next page of Terraform policy sets. |
+| Terraform.PolicySet.links.last | String | Link to the last page of Terraform policy sets. |
+| Terraform.PolicySet.meta.pagination.current-page | Number | Current page number in the pagination of Terraform policy sets. |
+| Terraform.PolicySet.meta.pagination.page-size | Number | Number of items per page in the pagination of Terraform policy sets. |
+| Terraform.PolicySet.meta.pagination.prev-page | Unknown | Link to the previous page in the pagination of Terraform policy sets. |
+| Terraform.PolicySet.meta.pagination.next-page | Unknown | Link to the next page in the pagination of Terraform policy sets. |
+| Terraform.PolicySet.meta.pagination.total-pages | Number | Total number of pages in the pagination of Terraform policy sets. |
+| Terraform.PolicySet.meta.pagination.total-count | Number | Total number of Terraform policy sets. |
+
+#### Command example
+```!terraform-policy-set-list```
+#### Context Example
+```json
+{
+ "Terraform": {
+ "PolicySet": {
+ "attributes": {
+ "agent-enabled": false,
+ "created-at": "2023-11-08T11:25:06.196Z",
+ "description": null,
+ "global": false,
+ "kind": "sentinel",
+ "name": "test-policy-set",
+ "policy-count": 1,
+ "project-count": 0,
+ "updated-at": "2023-11-08T11:25:06.196Z",
+ "versioned": false,
+ "workspace-count": 1
+ },
+ "id": "polset-hc2bvqDW8YRgHEt8",
+ "links": {
+ "self": "/api/v2/policy-sets/polset-hc2bvqDW8YRgHEt8"
+ },
+ "relationships": {
+ "organization": {
+ "data": {
+ "id": "example-org-40dc3b",
+ "type": "organizations"
+ }
+ },
+ "policies": {
+ "data": [
+ {
+ "id": "pol-ycCqXorxsFjaH5aK",
+ "type": "policies"
+ }
+ ]
+ },
+ "projects": {
+ "data": []
+ },
+ "workspace-exclusions": {
+ "data": []
+ },
+ "workspaces": {
+ "data": [
+ {
+ "id": "ws-u7kVixWpJYWiERMG",
+ "type": "workspaces"
+ }
+ ]
+ }
+ },
+ "type": "policy-sets"
+ }
+ }
+}
+```
+
+#### Human Readable Output
+
+>### Terraform Policy Sets
+>|Organization|Policies ids|Policy Set name|Policy set id|Workspaces|
+>|---|---|---|---|---|
+>| example-org-40dc3b | pol-ycCqXorxsFjaH5aK | test-policy-set | polset-hc2bvqDW8YRgHEt8 | ws-u7kVixWpJYWiERMG |
+
+
+### terraform-policies-checks-list
+
+***
+List the policy checks for a Terraform run.
+
+#### Base Command
+
+`terraform-policies-checks-list`
+
+#### Input
+
+| **Argument Name** | **Description** | **Required** |
+| --- | --- | --- |
+| run_id | The run ID to list results for. | Optional |
+| policy_check_id | The policy check ID to retrieve details for. | Optional |
+| page_number | The page number of the results to return. Default is 1. | Optional |
+| page_size | The number of results to return per page. Default is 20, maximum is 100. | Optional |
+
+#### Context Output
+
+| **Path** | **Type** | **Description** |
+| --- | --- | --- |
+| Terraform.PolicyCheck.id | String | The policy check ID. |
+| Terraform.PolicyCheck.type | String | Type of the Terraform policy check data. |
+| Terraform.PolicyCheck.attributes.result.result | Boolean | Overall result of the Terraform policy check. |
+| Terraform.PolicyCheck.attributes.result.passed | Number | Number of policy checks that passed. |
+| Terraform.PolicyCheck.attributes.result.total-failed | Number | Total number of policy checks that failed. |
+| Terraform.PolicyCheck.attributes.result.hard-failed | Number | Number of policy checks that resulted in hard failures. |
+| Terraform.PolicyCheck.attributes.result.soft-failed | Number | Number of policy checks that resulted in soft failures. |
+| Terraform.PolicyCheck.attributes.result.advisory-failed | Number | Number of policy checks that resulted in advisory failures. |
+| Terraform.PolicyCheck.attributes.result.duration-ms | Number | Duration of the policy check execution in milliseconds. |
+| Terraform.PolicyCheck.attributes.result.sentinel | Unknown | Sentinel-specific result of the policy check. |
+| Terraform.PolicyCheck.attributes.scope | String | Scope or context of the Terraform policy check. |
+| Terraform.PolicyCheck.attributes.status | String | Status of the Terraform policy check. |
+| Terraform.PolicyCheck.attributes.status-timestamps.queued-at | Date | Timestamp indicating when the Terraform policy check was queued. |
+| Terraform.PolicyCheck.attributes.status-timestamps.soft-failed-at | Date | Timestamp indicating when the Terraform policy check encountered a soft failure. |
+| Terraform.PolicyCheck.attributes.actions.is-overridable | Boolean | Flag indicating whether the Terraform policy check is overridable. |
+| Terraform.PolicyCheck.attributes.permissions.can-override | Boolean | Flag indicating whether the user has permission to override the Terraform policy check. |
+| Terraform.PolicyCheck.relationships.run.data.id | String | Unique identifier for the Terraform run associated with the policy check. |
+| Terraform.PolicyCheck.relationships.run.data.type | String | Type of the Terraform run associated with the policy check. |
+| Terraform.PolicyCheck.links.output | String | Link to the output of the Terraform policy check. |
+
+#### Command example
+```!terraform-policies-checks-list run_id=run-8wpCneWr4TLSzfat```
+#### Human Readable Output
+
+>### Terraform Policy Checks
+>**No entries.**
+
diff --git a/Packs/HashiCorpTerraform/Integrations/HashiCorpTerraform/command_examples b/Packs/HashiCorpTerraform/Integrations/HashiCorpTerraform/command_examples
new file mode 100644
index 000000000000..b43d6c9d41cc
--- /dev/null
+++ b/Packs/HashiCorpTerraform/Integrations/HashiCorpTerraform/command_examples
@@ -0,0 +1,7 @@
+!terraform-runs-list
+!terraform-policy-set-list
+!terraform-policies-list
+!terraform-run-action run_id=run-8wpCneWr4TLSzfat action="discard" comment="test comment"
+!terraform-policies-checks-list run_id=run-8wpCneWr4TLSzfat
+!terraform-plan-get plan_id=plan-V4fvpvCzGQrsZikD
+!terraform-plan-get plan_id=plan-V4fvpvCzGQrsZikD json_output="true"
diff --git a/Packs/HashiCorpTerraform/Integrations/HashiCorpTerraform/test_data/plan_get_request.json b/Packs/HashiCorpTerraform/Integrations/HashiCorpTerraform/test_data/plan_get_request.json
new file mode 100644
index 000000000000..3dc25896be2a
--- /dev/null
+++ b/Packs/HashiCorpTerraform/Integrations/HashiCorpTerraform/test_data/plan_get_request.json
@@ -0,0 +1,143 @@
+{
+ "mock_response": {
+ "data": {
+ "id": "plan-Abcabcabcabcabc4",
+ "type": "plans",
+ "attributes": {
+ "has-changes": false,
+ "status": "finished",
+ "status-timestamps": {
+ "started-at": "2023-11-30T09:21:37+00:00",
+ "finished-at": "2023-11-30T09:21:41+00:00",
+ "agent-queued-at": "2023-11-30T09:21:33+00:00"
+ },
+ "resource-additions": 0,
+ "resource-changes": 0,
+ "resource-destructions": 0,
+ "resource-imports": 0,
+ "structured-run-output-enabled": true,
+ "generated-configuration": false,
+ "actions": {
+ "is-exportable": true
+ },
+ "execution-details": {
+ "mode": "remote"
+ },
+ "permissions": {
+ "can-export": true
+ }
+ },
+ "relationships": {
+ "state-versions": {
+ "data": []
+ },
+ "exports": {
+ "data": []
+ }
+ },
+ "links": {
+ "self": "/api/v2/plans/plan-Abcabcabcabcabc4",
+ "json-output": "/api/v2/plans/plan-Abcabcabcabcabc4/json-output",
+ "json-output-redacted": "/api/v2/plans/plan-Abcabcabcabcabc4/json-output-redacted",
+ "json-schema": "/api/v2/plans/plan-Abcabcabcabcabc4/json-schema"
+ }
+ }
+ },
+ "expected_results": {
+ "Type": 1,
+ "ContentsFormat": "json",
+ "Contents": {
+ "data": {
+ "id": "plan-Abcabcabcabcabc4",
+ "type": "plans",
+ "attributes": {
+ "has-changes": false,
+ "status": "finished",
+ "status-timestamps": {
+ "started-at": "2023-11-30T09:21:37+00:00",
+ "finished-at": "2023-11-30T09:21:41+00:00",
+ "agent-queued-at": "2023-11-30T09:21:33+00:00"
+ },
+ "resource-additions": 0,
+ "resource-changes": 0,
+ "resource-destructions": 0,
+ "resource-imports": 0,
+ "structured-run-output-enabled": true,
+ "generated-configuration": false,
+ "actions": {
+ "is-exportable": true
+ },
+ "execution-details": {
+ "mode": "remote"
+ },
+ "permissions": {
+ "can-export": true
+ }
+ },
+ "relationships": {
+ "state-versions": {
+ "data": []
+ },
+ "exports": {
+ "data": []
+ }
+ },
+ "links": {
+ "self": "/api/v2/plans/plan-Abcabcabcabcabc4",
+ "json-output": "/api/v2/plans/plan-Abcabcabcabcabc4/json-output",
+ "json-output-redacted": "/api/v2/plans/plan-Abcabcabcabcabc4/json-output-redacted",
+ "json-schema": "/api/v2/plans/plan-Abcabcabcabcabc4/json-schema"
+ }
+ }
+ },
+ "HumanReadable": "### Terraform Plan\n|Agent Queued at|Plan id|Status|\n|---|---|---|\n| 2023-11-30T09:21:33+00:00 | plan-Abcabcabcabcabc4 | finished |\n",
+ "EntryContext": {
+ "Terraform.Plan(val.id && val.id == obj.id)": {
+ "id": "plan-Abcabcabcabcabc4",
+ "type": "plans",
+ "attributes": {
+ "has-changes": false,
+ "status": "finished",
+ "status-timestamps": {
+ "started-at": "2023-11-30T09:21:37+00:00",
+ "finished-at": "2023-11-30T09:21:41+00:00",
+ "agent-queued-at": "2023-11-30T09:21:33+00:00"
+ },
+ "resource-additions": 0,
+ "resource-changes": 0,
+ "resource-destructions": 0,
+ "resource-imports": 0,
+ "structured-run-output-enabled": true,
+ "generated-configuration": false,
+ "actions": {
+ "is-exportable": true
+ },
+ "execution-details": {
+ "mode": "remote"
+ },
+ "permissions": {
+ "can-export": true
+ }
+ },
+ "relationships": {
+ "state-versions": {
+ "data": []
+ },
+ "exports": {
+ "data": []
+ }
+ },
+ "links": {
+ "self": "/api/v2/plans/plan-Abcabcabcabcabc4",
+ "json-output": "/api/v2/plans/plan-Abcabcabcabcabc4/json-output",
+ "json-output-redacted": "/api/v2/plans/plan-Abcabcabcabcabc4/json-output-redacted",
+ "json-schema": "/api/v2/plans/plan-Abcabcabcabcabc4/json-schema"
+ }
+ }
+ },
+ "IndicatorTimeline": [],
+ "IgnoreAutoExtract": false,
+ "Note": false,
+ "Relationships": []
+ }
+}
\ No newline at end of file
diff --git a/Packs/HashiCorpTerraform/Integrations/HashiCorpTerraform/test_data/policies_check_list_request.json b/Packs/HashiCorpTerraform/Integrations/HashiCorpTerraform/test_data/policies_check_list_request.json
new file mode 100644
index 000000000000..bc9aa991eba5
--- /dev/null
+++ b/Packs/HashiCorpTerraform/Integrations/HashiCorpTerraform/test_data/policies_check_list_request.json
@@ -0,0 +1,137 @@
+{
+ "mock_response": {
+ "data": [
+ {
+ "id": "polchk-abcabcabcabcabc4",
+ "type": "policy-checks",
+ "attributes": {
+ "result": {
+ "result": false,
+ "passed": 0,
+ "total-failed": 1,
+ "hard-failed": 0,
+ "soft-failed": 1,
+ "advisory-failed": 0,
+ "duration-ms": 0
+ },
+ "scope": "organization",
+ "status": "soft_failed",
+ "status-timestamps": {
+ "queued-at": "2017-11-29T20:02:17+00:00",
+ "soft-failed-at": "2017-11-29T20:02:20+00:00"
+ },
+ "actions": {
+ "is-overridable": true
+ },
+ "permissions": {
+ "can-override": false
+ }
+ },
+ "relationships": {
+ "run": {
+ "data": {
+ "id": "run-abcabcabcabcabc4",
+ "type": "runs"
+ }
+ }
+ },
+ "links": {
+ "output": "/api/v2/policy-checks/polchk-abcabcabcabcabc4/output"
+ }
+ }
+ ]
+ },
+ "expected_results": {
+ "Type": 1,
+ "ContentsFormat": "json",
+ "Contents": {
+ "data": [
+ {
+ "id": "polchk-abcabcabcabcabc4",
+ "type": "policy-checks",
+ "attributes": {
+ "result": {
+ "result": false,
+ "passed": 0,
+ "total-failed": 1,
+ "hard-failed": 0,
+ "soft-failed": 1,
+ "advisory-failed": 0,
+ "duration-ms": 0
+ },
+ "scope": "organization",
+ "status": "soft_failed",
+ "status-timestamps": {
+ "queued-at": "2017-11-29T20:02:17+00:00",
+ "soft-failed-at": "2017-11-29T20:02:20+00:00"
+ },
+ "actions": {
+ "is-overridable": true
+ },
+ "permissions": {
+ "can-override": false
+ }
+ },
+ "relationships": {
+ "run": {
+ "data": {
+ "id": "run-abcabcabcabcabc4",
+ "type": "runs"
+ }
+ }
+ },
+ "links": {
+ "output": "/api/v2/policy-checks/polchk-abcabcabcabcabc4/output"
+ }
+ }
+ ]
+ },
+ "HumanReadable": "### Terraform Policy Checks\n|Policy check id|Result|Scope |Status|\n|---|---|---|---|\n| polchk-abcabcabcabcabc4 | result: false
passed: 0
total-failed: 1
hard-failed: 0
soft-failed: 1
advisory-failed: 0
duration-ms: 0 | organization | soft_failed |\n",
+ "EntryContext": {
+ "Terraform.PolicyCheck(val.id && val.id == obj.id)": [
+ {
+ "id": "polchk-abcabcabcabcabc4",
+ "type": "policy-checks",
+ "attributes": {
+ "result": {
+ "result": false,
+ "passed": 0,
+ "total-failed": 1,
+ "hard-failed": 0,
+ "soft-failed": 1,
+ "advisory-failed": 0,
+ "duration-ms": 0
+ },
+ "scope": "organization",
+ "status": "soft_failed",
+ "status-timestamps": {
+ "queued-at": "2017-11-29T20:02:17+00:00",
+ "soft-failed-at": "2017-11-29T20:02:20+00:00"
+ },
+ "actions": {
+ "is-overridable": true
+ },
+ "permissions": {
+ "can-override": false
+ }
+ },
+ "relationships": {
+ "run": {
+ "data": {
+ "id": "run-abcabcabcabcabc4",
+ "type": "runs"
+ }
+ }
+ },
+ "links": {
+ "output": "/api/v2/policy-checks/polchk-abcabcabcabcabc4/output"
+ }
+ }
+ ]
+ },
+ "IndicatorTimeline": [],
+ "IgnoreAutoExtract": false,
+ "Note": false,
+ "Relationships": []
+ }
+}
\ No newline at end of file
diff --git a/Packs/HashiCorpTerraform/Integrations/HashiCorpTerraform/test_data/policies_list_request.json b/Packs/HashiCorpTerraform/Integrations/HashiCorpTerraform/test_data/policies_list_request.json
new file mode 100644
index 000000000000..c172fdca10f6
--- /dev/null
+++ b/Packs/HashiCorpTerraform/Integrations/HashiCorpTerraform/test_data/policies_list_request.json
@@ -0,0 +1,174 @@
+{
+ "mock_response": {
+ "data": [
+ {
+ "id": "pol-Abcabcabcabcabc4",
+ "type": "policies",
+ "attributes": {
+ "name": "nat-policies",
+ "description": null,
+ "enforce": [
+ {
+ "path": "nat-policies.sentinel",
+ "mode": "hard-mandatory"
+ }
+ ],
+ "policy-set-count": 1,
+ "updated-at": "2023-11-14T18:12:36.702Z",
+ "kind": "sentinel",
+ "enforcement-level": "hard-mandatory"
+ },
+ "relationships": {
+ "organization": {
+ "data": {
+ "id": "example-org-123Abc",
+ "type": "organizations"
+ }
+ },
+ "policy-sets": {
+ "data": [
+ {
+ "id": "polset-Abcabcabcabcabc5",
+ "type": "policy-sets"
+ }
+ ]
+ }
+ },
+ "links": {
+ "self": "/api/v2/policies/pol-Abcabcabcabcabc4",
+ "upload": "/api/v2/policies/pol-Abcabcabcabcabc4/upload",
+ "download": "/api/v2/policies/pol-Abcabcabcabcabc4/download"
+ }
+ }
+ ],
+ "links": {
+ "self": "https://app.terraform.io/api/v2/organizations/example-org-123Abc/policies?page%5Bnumber%5D=1&page%5Bsize%5D=20",
+ "first": "https://app.terraform.io/api/v2/organizations/example-org-123Abc/policies?page%5Bnumber%5D=1&page%5Bsize%5D=20",
+ "prev": null,
+ "next": null,
+ "last": "https://app.terraform.io/api/v2/organizations/example-org-123Abc/policies?page%5Bnumber%5D=1&page%5Bsize%5D=20"
+ },
+ "meta": {
+ "pagination": {
+ "current-page": 1,
+ "page-size": 20,
+ "prev-page": null,
+ "next-page": null,
+ "total-pages": 1,
+ "total-count": 1
+ }
+ }
+ },
+ "expected_results": {
+ "Type": 1,
+ "ContentsFormat": "json",
+ "Contents": {
+ "data": [
+ {
+ "id": "pol-Abcabcabcabcabc4",
+ "type": "policies",
+ "attributes": {
+ "name": "nat-policies",
+ "description": null,
+ "enforce": [
+ {
+ "path": "nat-policies.sentinel",
+ "mode": "hard-mandatory"
+ }
+ ],
+ "policy-set-count": 1,
+ "updated-at": "2023-11-14T18:12:36.702Z",
+ "kind": "sentinel",
+ "enforcement-level": "hard-mandatory"
+ },
+ "relationships": {
+ "organization": {
+ "data": {
+ "id": "example-org-123Abc",
+ "type": "organizations"
+ }
+ },
+ "policy-sets": {
+ "data": [
+ {
+ "id": "polset-Abcabcabcabcabc5",
+ "type": "policy-sets"
+ }
+ ]
+ }
+ },
+ "links": {
+ "self": "/api/v2/policies/pol-Abcabcabcabcabc4",
+ "upload": "/api/v2/policies/pol-Abcabcabcabcabc4/upload",
+ "download": "/api/v2/policies/pol-Abcabcabcabcabc4/download"
+ }
+ }
+ ],
+ "links": {
+ "self": "https://app.terraform.io/api/v2/organizations/example-org-123Abc/policies?page%5Bnumber%5D=1&page%5Bsize%5D=20",
+ "first": "https://app.terraform.io/api/v2/organizations/example-org-123Abc/policies?page%5Bnumber%5D=1&page%5Bsize%5D=20",
+ "prev": null,
+ "next": null,
+ "last": "https://app.terraform.io/api/v2/organizations/example-org-123Abc/policies?page%5Bnumber%5D=1&page%5Bsize%5D=20"
+ },
+ "meta": {
+ "pagination": {
+ "current-page": 1,
+ "page-size": 20,
+ "prev-page": null,
+ "next-page": null,
+ "total-pages": 1,
+ "total-count": 1
+ }
+ }
+ },
+ "HumanReadable": "### Terraform Policies\n|Kind|Organization id|Policy Set ids|Policy description|Policy id|Policy name|\n|---|---|---|---|---|---|\n| attributes.kind | relationships.organization.data.id | relationships.policy-sets.data.id | attributes.description | id | attributes.name |\n",
+ "EntryContext": {
+ "Terraform.Policy(val.id && val.id == obj.id)": [
+ {
+ "id": "pol-Abcabcabcabcabc4",
+ "type": "policies",
+ "attributes": {
+ "name": "nat-policies",
+ "description": null,
+ "enforce": [
+ {
+ "path": "nat-policies.sentinel",
+ "mode": "hard-mandatory"
+ }
+ ],
+ "policy-set-count": 1,
+ "updated-at": "2023-11-14T18:12:36.702Z",
+ "kind": "sentinel",
+ "enforcement-level": "hard-mandatory"
+ },
+ "relationships": {
+ "organization": {
+ "data": {
+ "id": "example-org-123Abc",
+ "type": "organizations"
+ }
+ },
+ "policy-sets": {
+ "data": [
+ {
+ "id": "polset-Abcabcabcabcabc5",
+ "type": "policy-sets"
+ }
+ ]
+ }
+ },
+ "links": {
+ "self": "/api/v2/policies/pol-Abcabcabcabcabc4",
+ "upload": "/api/v2/policies/pol-Abcabcabcabcabc4/upload",
+ "download": "/api/v2/policies/pol-Abcabcabcabcabc4/download"
+ }
+ }
+ ]
+ },
+ "IndicatorTimeline": [],
+ "IgnoreAutoExtract": false,
+ "Note": false,
+ "Relationships": []
+ }
+}
\ No newline at end of file
diff --git a/Packs/HashiCorpTerraform/Integrations/HashiCorpTerraform/test_data/policy_set_list_request.json b/Packs/HashiCorpTerraform/Integrations/HashiCorpTerraform/test_data/policy_set_list_request.json
new file mode 100644
index 000000000000..819c88b2fa8c
--- /dev/null
+++ b/Packs/HashiCorpTerraform/Integrations/HashiCorpTerraform/test_data/policy_set_list_request.json
@@ -0,0 +1,207 @@
+{
+ "mock_response": {
+ "data": [
+ {
+ "id": "polset-abcABCabcabc1234",
+ "type": "policy-sets",
+ "attributes": {
+ "name": "test-policy-set",
+ "description": null,
+ "global": false,
+ "workspace-count": 1,
+ "project-count": 0,
+ "created-at": "2023-11-08T11:25:06.196Z",
+ "updated-at": "2023-11-08T11:25:06.196Z",
+ "kind": "sentinel",
+ "agent-enabled": false,
+ "policy-count": 1,
+ "versioned": false
+ },
+ "relationships": {
+ "organization": {
+ "data": {
+ "id": "example-org-12ab3c",
+ "type": "organizations"
+ }
+ },
+ "policies": {
+ "data": [
+ {
+ "id": "pol-abcabcabcabcabc6",
+ "type": "policies"
+ }
+ ]
+ },
+ "workspaces": {
+ "data": [
+ {
+ "id": "ws-abcabcabcabcabc6",
+ "type": "workspaces"
+ }
+ ]
+ },
+ "projects": {
+ "data": []
+ },
+ "workspace-exclusions": {
+ "data": []
+ }
+ },
+ "links": {
+ "self": "/api/v2/policy-sets/polset-abcABCabcabc1234"
+ }
+ }
+ ],
+ "links": {
+ "self": "https://app.terraform.io/api/v2/organizations/example-org-12ab3c/policy-sets?page%5Bnumber%5D=1&page%5Bsize%5D=20",
+ "first": "https://app.terraform.io/api/v2/organizations/example-org-12ab3c/policy-sets?page%5Bnumber%5D=1&page%5Bsize%5D=20",
+ "prev": null,
+ "next": null,
+ "last": "https://app.terraform.io/api/v2/organizations/example-org-12ab3c/policy-sets?page%5Bnumber%5D=1&page%5Bsize%5D=20"
+ },
+ "meta": {
+ "pagination": {
+ "current-page": 1,
+ "page-size": 20,
+ "prev-page": null,
+ "next-page": null,
+ "total-pages": 1,
+ "total-count": 1
+ }
+ }
+ },
+ "expected_results": {
+ "Type": 1,
+ "ContentsFormat": "json",
+ "Contents": {
+ "data": [
+ {
+ "id": "polset-abcABCabcabc1234",
+ "type": "policy-sets",
+ "attributes": {
+ "name": "test-policy-set",
+ "description": null,
+ "global": false,
+ "workspace-count": 1,
+ "project-count": 0,
+ "created-at": "2023-11-08T11:25:06.196Z",
+ "updated-at": "2023-11-08T11:25:06.196Z",
+ "kind": "sentinel",
+ "agent-enabled": false,
+ "policy-count": 1,
+ "versioned": false
+ },
+ "relationships": {
+ "organization": {
+ "data": {
+ "id": "example-org-12ab3c",
+ "type": "organizations"
+ }
+ },
+ "policies": {
+ "data": [
+ {
+ "id": "pol-abcabcabcabcabc6",
+ "type": "policies"
+ }
+ ]
+ },
+ "workspaces": {
+ "data": [
+ {
+ "id": "ws-abcabcabcabcabc6",
+ "type": "workspaces"
+ }
+ ]
+ },
+ "projects": {
+ "data": []
+ },
+ "workspace-exclusions": {
+ "data": []
+ }
+ },
+ "links": {
+ "self": "/api/v2/policy-sets/polset-abcABCabcabc1234"
+ }
+ }
+ ],
+ "links": {
+ "self": "https://app.terraform.io/api/v2/organizations/example-org-12ab3c/policy-sets?page%5Bnumber%5D=1&page%5Bsize%5D=20",
+ "first": "https://app.terraform.io/api/v2/organizations/example-org-12ab3c/policy-sets?page%5Bnumber%5D=1&page%5Bsize%5D=20",
+ "prev": null,
+ "next": null,
+ "last": "https://app.terraform.io/api/v2/organizations/example-org-12ab3c/policy-sets?page%5Bnumber%5D=1&page%5Bsize%5D=20"
+ },
+ "meta": {
+ "pagination": {
+ "current-page": 1,
+ "page-size": 20,
+ "prev-page": null,
+ "next-page": null,
+ "total-pages": 1,
+ "total-count": 1
+ }
+ }
+ },
+ "HumanReadable": "### Terraform Policy Sets\n|Description|Organization|Policies ids|Policy Set name|Policy set id|Projects|Workspaces|\n|---|---|---|---|---|---|---|\n| attributes.description | relationships.organization.data.id | relationships.policies.data.id | attributes.name | id | relationships.projects.data.id | relationships.workspaces.data.id |\n",
+ "EntryContext": {
+ "Terraform.PolicySet(val.id && val.id == obj.id)": [
+ {
+ "id": "polset-abcABCabcabc1234",
+ "type": "policy-sets",
+ "attributes": {
+ "name": "test-policy-set",
+ "description": null,
+ "global": false,
+ "workspace-count": 1,
+ "project-count": 0,
+ "created-at": "2023-11-08T11:25:06.196Z",
+ "updated-at": "2023-11-08T11:25:06.196Z",
+ "kind": "sentinel",
+ "agent-enabled": false,
+ "policy-count": 1,
+ "versioned": false
+ },
+ "relationships": {
+ "organization": {
+ "data": {
+ "id": "example-org-12ab3c",
+ "type": "organizations"
+ }
+ },
+ "policies": {
+ "data": [
+ {
+ "id": "pol-abcabcabcabcabc6",
+ "type": "policies"
+ }
+ ]
+ },
+ "workspaces": {
+ "data": [
+ {
+ "id": "ws-abcabcabcabcabc6",
+ "type": "workspaces"
+ }
+ ]
+ },
+ "projects": {
+ "data": []
+ },
+ "workspace-exclusions": {
+ "data": []
+ }
+ },
+ "links": {
+ "self": "/api/v2/policy-sets/polset-abcABCabcabc1234"
+ }
+ }
+ ]
+ },
+ "IndicatorTimeline": [],
+ "IgnoreAutoExtract": false,
+ "Note": false,
+ "Relationships": []
+ }
+}
\ No newline at end of file
diff --git a/Packs/HashiCorpTerraform/Integrations/HashiCorpTerraform/test_data/run_action_request.json b/Packs/HashiCorpTerraform/Integrations/HashiCorpTerraform/test_data/run_action_request.json
new file mode 100644
index 000000000000..499123f8b2ba
--- /dev/null
+++ b/Packs/HashiCorpTerraform/Integrations/HashiCorpTerraform/test_data/run_action_request.json
@@ -0,0 +1,10 @@
+{
+ "mock_response": {
+ "errors": [
+ {
+ "status": "409",
+ "title": "transition not allowed"
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/Packs/HashiCorpTerraform/Integrations/HashiCorpTerraform/test_data/runs_list_request.json b/Packs/HashiCorpTerraform/Integrations/HashiCorpTerraform/test_data/runs_list_request.json
new file mode 100644
index 000000000000..f578ebd11650
--- /dev/null
+++ b/Packs/HashiCorpTerraform/Integrations/HashiCorpTerraform/test_data/runs_list_request.json
@@ -0,0 +1,985 @@
+{
+ "mock_response": {
+ "data": [
+ {
+ "id": "run-ABCABCABCABCABCA",
+ "type": "runs",
+ "attributes": {
+ "actions": {
+ "is-cancelable": false,
+ "is-confirmable": false,
+ "is-discardable": false,
+ "is-force-cancelable": false
+ },
+ "allow-config-generation": false,
+ "allow-empty-apply": false,
+ "auto-apply": false,
+ "canceled-at": null,
+ "created-at": "2023-11-30T09:21:33.373Z",
+ "has-changes": false,
+ "is-destroy": false,
+ "message": "Triggered via UI",
+ "plan-only": false,
+ "refresh": true,
+ "refresh-only": true,
+ "replace-addrs": [],
+ "save-plan": false,
+ "source": "tfe-ui",
+ "status-timestamps": {
+ "planned-at": "2023-11-30T09:21:42+00:00",
+ "queuing-at": "2023-11-30T09:21:33+00:00",
+ "planning-at": "2023-11-30T09:21:37+00:00",
+ "plan-queued-at": "2023-11-30T09:21:33+00:00",
+ "plan-queueable-at": "2023-11-30T09:21:33+00:00",
+ "planned-and-finished-at": "2023-11-30T09:21:42+00:00"
+ },
+ "status": "planned_and_finished",
+ "target-addrs": null,
+ "trigger-reason": "manual",
+ "terraform-version": "1.4.4",
+ "permissions": {
+ "can-apply": true,
+ "can-cancel": true,
+ "can-comment": true,
+ "can-discard": true,
+ "can-force-execute": true,
+ "can-force-cancel": true,
+ "can-override-policy-check": true
+ },
+ "variables": []
+ },
+ "relationships": {
+ "workspace": {
+ "data": {
+ "id": "ws-ABCABCABCABCABCA",
+ "type": "workspaces"
+ }
+ },
+ "apply": {
+ "data": {
+ "id": "apply-ABCABCABCABCABCA",
+ "type": "applies"
+ },
+ "links": {
+ "related": "/api/v2/runs/run-ABCABCABCABCABCA/apply"
+ }
+ },
+ "configuration-version": {
+ "data": {
+ "id": "cv-ABCABCABCABCABCA",
+ "type": "configuration-versions"
+ },
+ "links": {
+ "related": "/api/v2/runs/run-ABCABCABCABCABCA/configuration-version"
+ }
+ },
+ "created-by": {
+ "data": {
+ "id": "user-ABCABCABCABCABCA",
+ "type": "users"
+ },
+ "links": {
+ "related": "/api/v2/runs/run-ABCABCABCABCABCA/created-by"
+ }
+ },
+ "plan": {
+ "data": {
+ "id": "plan-ABCABCABCABCABCA",
+ "type": "plans"
+ },
+ "links": {
+ "related": "/api/v2/runs/run-ABCABCABCABCABCA/plan"
+ }
+ },
+ "run-events": {
+ "data": [
+ {
+ "id": "re-ABCABCABCABCABCA",
+ "type": "run-events"
+ },
+ {
+ "id": "re-ABCABCABCABCABCA",
+ "type": "run-events"
+ },
+ {
+ "id": "re-ABCABCABCABCABCA",
+ "type": "run-events"
+ },
+ {
+ "id": "re-ABCABCABCABCABCA",
+ "type": "run-events"
+ }
+ ],
+ "links": {
+ "related": "/api/v2/runs/run-ABCABCABCABCABCA/run-events"
+ }
+ },
+ "task-stages": {
+ "data": [],
+ "links": {
+ "related": "/api/v2/runs/run-ABCABCABCABCABCA/task-stages"
+ }
+ },
+ "policy-checks": {
+ "data": [],
+ "links": {
+ "related": "/api/v2/runs/run-ABCABCABCABCABCA/policy-checks"
+ }
+ },
+ "comments": {
+ "data": [],
+ "links": {
+ "related": "/api/v2/runs/run-ABCABCABCABCABCA/comments"
+ }
+ }
+ },
+ "links": {
+ "self": "/api/v2/runs/run-ABCABCABCABCABCA"
+ }
+ },
+ {
+ "id": "run-ABCABCABCABCABCA",
+ "type": "runs",
+ "attributes": {
+ "actions": {
+ "is-cancelable": false,
+ "is-confirmable": false,
+ "is-discardable": false,
+ "is-force-cancelable": false
+ },
+ "allow-config-generation": false,
+ "allow-empty-apply": false,
+ "auto-apply": true,
+ "canceled-at": null,
+ "created-at": "2023-10-25T10:33:02.368Z",
+ "has-changes": true,
+ "is-destroy": false,
+ "message": "Triggered via CLI",
+ "plan-only": false,
+ "refresh": true,
+ "refresh-only": false,
+ "replace-addrs": null,
+ "save-plan": false,
+ "source": "terraform+cloud",
+ "status-timestamps": {
+ "applied-at": "2023-10-25T10:33:19+00:00",
+ "planned-at": "2023-10-25T10:33:11+00:00",
+ "queuing-at": "2023-10-25T10:33:02+00:00",
+ "applying-at": "2023-10-25T10:33:16+00:00",
+ "planning-at": "2023-10-25T10:33:07+00:00",
+ "confirmed-at": "2023-10-25T10:33:11+00:00",
+ "plan-queued-at": "2023-10-25T10:33:03+00:00",
+ "apply-queued-at": "2023-10-25T10:33:12+00:00",
+ "queuing-apply-at": "2023-10-25T10:33:11+00:00",
+ "plan-queueable-at": "2023-10-25T10:33:02+00:00"
+ },
+ "status": "applied",
+ "target-addrs": null,
+ "trigger-reason": "manual",
+ "terraform-version": "1.4.4",
+ "permissions": {
+ "can-apply": true,
+ "can-cancel": true,
+ "can-comment": true,
+ "can-discard": true,
+ "can-force-execute": true,
+ "can-force-cancel": true,
+ "can-override-policy-check": true
+ },
+ "variables": []
+ },
+ "relationships": {
+ "workspace": {
+ "data": {
+ "id": "ws-ABCABCABCABCABCA",
+ "type": "workspaces"
+ }
+ },
+ "apply": {
+ "data": {
+ "id": "apply-ABCABCABCABCABCA",
+ "type": "applies"
+ },
+ "links": {
+ "related": "/api/v2/runs/run-ABCABCABCABCABCA/apply"
+ }
+ },
+ "configuration-version": {
+ "data": {
+ "id": "cv-ABCABCABCABCABCA",
+ "type": "configuration-versions"
+ },
+ "links": {
+ "related": "/api/v2/runs/run-ABCABCABCABCABCA/configuration-version"
+ }
+ },
+ "created-by": {
+ "data": {
+ "id": "user--ABCABCABCABCABCA",
+ "type": "users"
+ },
+ "links": {
+ "related": "/api/v2/runs/run-ABCABCABCABCABCA/created-by"
+ }
+ },
+ "plan": {
+ "data": {
+ "id": "plan-ABCABCABCABCABCA",
+ "type": "plans"
+ },
+ "links": {
+ "related": "/api/v2/runs/run-ABCABCABCABCABCA/plan"
+ }
+ },
+ "run-events": {
+ "data": [
+ {
+ "id": "re-ABCABCABCABCABCA",
+ "type": "run-events"
+ }
+ ],
+ "links": {
+ "related": "/api/v2/runs/run-ABCABCABCABCABCA/run-events"
+ }
+ },
+ "task-stages": {
+ "data": [],
+ "links": {
+ "related": "/api/v2/runs/run-ABCABCABCABCABCA/task-stages"
+ }
+ },
+ "policy-checks": {
+ "data": [],
+ "links": {
+ "related": "/api/v2/runs/run-ABCABCABCABCABCA/policy-checks"
+ }
+ },
+ "comments": {
+ "data": [],
+ "links": {
+ "related": "/api/v2/runs/run-ABCABCABCABCABCA/comments"
+ }
+ }
+ },
+ "links": {
+ "self": "/api/v2/runs/run-ABCABCABCABCABCA"
+ }
+ }
+ ],
+ "links": {
+ "self": "https://app.terraform.io/api/v2/workspaces/ws-ABCABCABCABCABCA/runs?page%5Bnumber%5D=1&page%5Bsize%5D=20",
+ "first": "https://app.terraform.io/api/v2/workspaces/ws-ABCABCABCABCABCA/runs?page%5Bnumber%5D=1&page%5Bsize%5D=20",
+ "prev": null,
+ "next": null,
+ "last": "https://app.terraform.io/api/v2/workspaces/ws-ABCABCABCABCABCA/runs?page%5Bnumber%5D=1&page%5Bsize%5D=20"
+ },
+ "meta": {
+ "pagination": {
+ "current-page": 1,
+ "page-size": 20,
+ "prev-page": null,
+ "next-page": null,
+ "total-pages": 1,
+ "total-count": 2
+ },
+ "status-counts": {
+ "pending": 0,
+ "fetching": 0,
+ "fetching-completed": 0,
+ "pre-plan-running": 0,
+ "pre-plan-completed": 0,
+ "queuing": 0,
+ "plan-queued": 0,
+ "planning": 0,
+ "planned": 0,
+ "confirmed": 0,
+ "queuing-apply": 0,
+ "apply-queued": 0,
+ "applying": 0,
+ "applied": 1,
+ "discarded": 0,
+ "errored": 0,
+ "canceled": 0,
+ "cost-estimating": 0,
+ "cost-estimated": 0,
+ "policy-checking": 0,
+ "policy-override": 0,
+ "policy-checked": 0,
+ "policy-soft-failed": 0,
+ "planned-and-finished": 2,
+ "planned-and-saved": 0,
+ "post-plan-running": 0,
+ "post-plan-completed": 0,
+ "pre-apply-running": 0,
+ "pre-apply-completed": 0,
+ "post-apply-running": 0,
+ "post-apply-completed": 0,
+ "assessing": 0,
+ "assessed": 0,
+ "pre-plan-awaiting-decision": 0,
+ "post-plan-awaiting-decision": 0,
+ "pre-apply-awaiting-decision": 0,
+ "total": 3
+ }
+ }
+ },
+ "expected_results": {
+ "Type": 1,
+ "ContentsFormat": "json",
+ "Contents": {
+ "data": [
+ {
+ "id": "run-ABCABCABCABCABCA",
+ "type": "runs",
+ "attributes": {
+ "actions": {
+ "is-cancelable": false,
+ "is-confirmable": false,
+ "is-discardable": false,
+ "is-force-cancelable": false
+ },
+ "allow-config-generation": false,
+ "allow-empty-apply": false,
+ "auto-apply": false,
+ "canceled-at": null,
+ "created-at": "2023-11-30T09:21:33.373Z",
+ "has-changes": false,
+ "is-destroy": false,
+ "message": "Triggered via UI",
+ "plan-only": false,
+ "refresh": true,
+ "refresh-only": true,
+ "replace-addrs": [],
+ "save-plan": false,
+ "source": "tfe-ui",
+ "status-timestamps": {
+ "planned-at": "2023-11-30T09:21:42+00:00",
+ "queuing-at": "2023-11-30T09:21:33+00:00",
+ "planning-at": "2023-11-30T09:21:37+00:00",
+ "plan-queued-at": "2023-11-30T09:21:33+00:00",
+ "plan-queueable-at": "2023-11-30T09:21:33+00:00",
+ "planned-and-finished-at": "2023-11-30T09:21:42+00:00"
+ },
+ "status": "planned_and_finished",
+ "target-addrs": null,
+ "trigger-reason": "manual",
+ "terraform-version": "1.4.4",
+ "permissions": {
+ "can-apply": true,
+ "can-cancel": true,
+ "can-comment": true,
+ "can-discard": true,
+ "can-force-execute": true,
+ "can-force-cancel": true,
+ "can-override-policy-check": true
+ },
+ "variables": []
+ },
+ "relationships": {
+ "workspace": {
+ "data": {
+ "id": "ws-ABCABCABCABCABCA",
+ "type": "workspaces"
+ }
+ },
+ "apply": {
+ "data": {
+ "id": "apply-ABCABCABCABCABCA",
+ "type": "applies"
+ },
+ "links": {
+ "related": "/api/v2/runs/run-ABCABCABCABCABCA/apply"
+ }
+ },
+ "configuration-version": {
+ "data": {
+ "id": "cv-ABCABCABCABCABCA",
+ "type": "configuration-versions"
+ },
+ "links": {
+ "related": "/api/v2/runs/run-ABCABCABCABCABCA/configuration-version"
+ }
+ },
+ "created-by": {
+ "data": {
+ "id": "user-ABCABCABCABCABCA",
+ "type": "users"
+ },
+ "links": {
+ "related": "/api/v2/runs/run-ABCABCABCABCABCA/created-by"
+ }
+ },
+ "plan": {
+ "data": {
+ "id": "plan-ABCABCABCABCABCA",
+ "type": "plans"
+ },
+ "links": {
+ "related": "/api/v2/runs/run-ABCABCABCABCABCA/plan"
+ }
+ },
+ "run-events": {
+ "data": [
+ {
+ "id": "re-ABCABCABCABCABCA",
+ "type": "run-events"
+ },
+ {
+ "id": "re-ABCABCABCABCABCA",
+ "type": "run-events"
+ },
+ {
+ "id": "re-ABCABCABCABCABCA",
+ "type": "run-events"
+ },
+ {
+ "id": "re-ABCABCABCABCABCA",
+ "type": "run-events"
+ }
+ ],
+ "links": {
+ "related": "/api/v2/runs/run-ABCABCABCABCABCA/run-events"
+ }
+ },
+ "task-stages": {
+ "data": [],
+ "links": {
+ "related": "/api/v2/runs/run-ABCABCABCABCABCA/task-stages"
+ }
+ },
+ "policy-checks": {
+ "data": [],
+ "links": {
+ "related": "/api/v2/runs/run-ABCABCABCABCABCA/policy-checks"
+ }
+ },
+ "comments": {
+ "data": [],
+ "links": {
+ "related": "/api/v2/runs/run-ABCABCABCABCABCA/comments"
+ }
+ }
+ },
+ "links": {
+ "self": "/api/v2/runs/run-ABCABCABCABCABCA"
+ }
+ },
+ {
+ "id": "run-ABCABCABCABCABCA",
+ "type": "runs",
+ "attributes": {
+ "actions": {
+ "is-cancelable": false,
+ "is-confirmable": false,
+ "is-discardable": false,
+ "is-force-cancelable": false
+ },
+ "allow-config-generation": false,
+ "allow-empty-apply": false,
+ "auto-apply": true,
+ "canceled-at": null,
+ "created-at": "2023-10-25T10:33:02.368Z",
+ "has-changes": true,
+ "is-destroy": false,
+ "message": "Triggered via CLI",
+ "plan-only": false,
+ "refresh": true,
+ "refresh-only": false,
+ "replace-addrs": null,
+ "save-plan": false,
+ "source": "terraform+cloud",
+ "status-timestamps": {
+ "applied-at": "2023-10-25T10:33:19+00:00",
+ "planned-at": "2023-10-25T10:33:11+00:00",
+ "queuing-at": "2023-10-25T10:33:02+00:00",
+ "applying-at": "2023-10-25T10:33:16+00:00",
+ "planning-at": "2023-10-25T10:33:07+00:00",
+ "confirmed-at": "2023-10-25T10:33:11+00:00",
+ "plan-queued-at": "2023-10-25T10:33:03+00:00",
+ "apply-queued-at": "2023-10-25T10:33:12+00:00",
+ "queuing-apply-at": "2023-10-25T10:33:11+00:00",
+ "plan-queueable-at": "2023-10-25T10:33:02+00:00"
+ },
+ "status": "applied",
+ "target-addrs": null,
+ "trigger-reason": "manual",
+ "terraform-version": "1.4.4",
+ "permissions": {
+ "can-apply": true,
+ "can-cancel": true,
+ "can-comment": true,
+ "can-discard": true,
+ "can-force-execute": true,
+ "can-force-cancel": true,
+ "can-override-policy-check": true
+ },
+ "variables": []
+ },
+ "relationships": {
+ "workspace": {
+ "data": {
+ "id": "ws-ABCABCABCABCABCA",
+ "type": "workspaces"
+ }
+ },
+ "apply": {
+ "data": {
+ "id": "apply-ABCABCABCABCABCA",
+ "type": "applies"
+ },
+ "links": {
+ "related": "/api/v2/runs/run-ABCABCABCABCABCA/apply"
+ }
+ },
+ "configuration-version": {
+ "data": {
+ "id": "cv-ABCABCABCABCABCA",
+ "type": "configuration-versions"
+ },
+ "links": {
+ "related": "/api/v2/runs/run-ABCABCABCABCABCA/configuration-version"
+ }
+ },
+ "created-by": {
+ "data": {
+ "id": "user--ABCABCABCABCABCA",
+ "type": "users"
+ },
+ "links": {
+ "related": "/api/v2/runs/run-ABCABCABCABCABCA/created-by"
+ }
+ },
+ "plan": {
+ "data": {
+ "id": "plan-ABCABCABCABCABCA",
+ "type": "plans"
+ },
+ "links": {
+ "related": "/api/v2/runs/run-ABCABCABCABCABCA/plan"
+ }
+ },
+ "run-events": {
+ "data": [
+ {
+ "id": "re-ABCABCABCABCABCA",
+ "type": "run-events"
+ }
+ ],
+ "links": {
+ "related": "/api/v2/runs/run-ABCABCABCABCABCA/run-events"
+ }
+ },
+ "task-stages": {
+ "data": [],
+ "links": {
+ "related": "/api/v2/runs/run-ABCABCABCABCABCA/task-stages"
+ }
+ },
+ "policy-checks": {
+ "data": [],
+ "links": {
+ "related": "/api/v2/runs/run-ABCABCABCABCABCA/policy-checks"
+ }
+ },
+ "comments": {
+ "data": [],
+ "links": {
+ "related": "/api/v2/runs/run-ABCABCABCABCABCA/comments"
+ }
+ }
+ },
+ "links": {
+ "self": "/api/v2/runs/run-ABCABCABCABCABCA"
+ }
+ }
+ ],
+ "links": {
+ "self": "https://app.terraform.io/api/v2/workspaces/ws-ABCABCABCABCABCA/runs?page%5Bnumber%5D=1&page%5Bsize%5D=20",
+ "first": "https://app.terraform.io/api/v2/workspaces/ws-ABCABCABCABCABCA/runs?page%5Bnumber%5D=1&page%5Bsize%5D=20",
+ "prev": null,
+ "next": null,
+ "last": "https://app.terraform.io/api/v2/workspaces/ws-ABCABCABCABCABCA/runs?page%5Bnumber%5D=1&page%5Bsize%5D=20"
+ },
+ "meta": {
+ "pagination": {
+ "current-page": 1,
+ "page-size": 20,
+ "prev-page": null,
+ "next-page": null,
+ "total-pages": 1,
+ "total-count": 2
+ },
+ "status-counts": {
+ "pending": 0,
+ "fetching": 0,
+ "fetching-completed": 0,
+ "pre-plan-running": 0,
+ "pre-plan-completed": 0,
+ "queuing": 0,
+ "plan-queued": 0,
+ "planning": 0,
+ "planned": 0,
+ "confirmed": 0,
+ "queuing-apply": 0,
+ "apply-queued": 0,
+ "applying": 0,
+ "applied": 1,
+ "discarded": 0,
+ "errored": 0,
+ "canceled": 0,
+ "cost-estimating": 0,
+ "cost-estimated": 0,
+ "policy-checking": 0,
+ "policy-override": 0,
+ "policy-checked": 0,
+ "policy-soft-failed": 0,
+ "planned-and-finished": 2,
+ "planned-and-saved": 0,
+ "post-plan-running": 0,
+ "post-plan-completed": 0,
+ "pre-apply-running": 0,
+ "pre-apply-completed": 0,
+ "post-apply-running": 0,
+ "post-apply-completed": 0,
+ "assessing": 0,
+ "assessed": 0,
+ "pre-plan-awaiting-decision": 0,
+ "post-plan-awaiting-decision": 0,
+ "pre-apply-awaiting-decision": 0,
+ "total": 3
+ }
+ }
+ },
+ "HumanReadable": "### Terraform Runs\n|Plan id|Planned at|Run id|Status|\n|---|---|---|---|\n| plan-ABCABCABCABCABCA | 2023-11-30T09:21:42+00:00 | run-ABCABCABCABCABCA | planned_and_finished |\n| plan-ABCABCABCABCABCA | 2023-10-25T10:33:11+00:00 | run-ABCABCABCABCABCA | applied |\n",
+ "EntryContext": {
+ "Terraform.Run(val.data.id && val.data.id == obj.data.id)": {
+ "data": [
+ {
+ "id": "run-ABCABCABCABCABCA",
+ "type": "runs",
+ "attributes": {
+ "actions": {
+ "is-cancelable": false,
+ "is-confirmable": false,
+ "is-discardable": false,
+ "is-force-cancelable": false
+ },
+ "allow-config-generation": false,
+ "allow-empty-apply": false,
+ "auto-apply": false,
+ "canceled-at": null,
+ "created-at": "2023-11-30T09:21:33.373Z",
+ "has-changes": false,
+ "is-destroy": false,
+ "message": "Triggered via UI",
+ "plan-only": false,
+ "refresh": true,
+ "refresh-only": true,
+ "replace-addrs": [],
+ "save-plan": false,
+ "source": "tfe-ui",
+ "status-timestamps": {
+ "planned-at": "2023-11-30T09:21:42+00:00",
+ "queuing-at": "2023-11-30T09:21:33+00:00",
+ "planning-at": "2023-11-30T09:21:37+00:00",
+ "plan-queued-at": "2023-11-30T09:21:33+00:00",
+ "plan-queueable-at": "2023-11-30T09:21:33+00:00",
+ "planned-and-finished-at": "2023-11-30T09:21:42+00:00"
+ },
+ "status": "planned_and_finished",
+ "target-addrs": null,
+ "trigger-reason": "manual",
+ "terraform-version": "1.4.4",
+ "permissions": {
+ "can-apply": true,
+ "can-cancel": true,
+ "can-comment": true,
+ "can-discard": true,
+ "can-force-execute": true,
+ "can-force-cancel": true,
+ "can-override-policy-check": true
+ },
+ "variables": []
+ },
+ "relationships": {
+ "workspace": {
+ "data": {
+ "id": "ws-ABCABCABCABCABCA",
+ "type": "workspaces"
+ }
+ },
+ "apply": {
+ "data": {
+ "id": "apply-ABCABCABCABCABCA",
+ "type": "applies"
+ },
+ "links": {
+ "related": "/api/v2/runs/run-ABCABCABCABCABCA/apply"
+ }
+ },
+ "configuration-version": {
+ "data": {
+ "id": "cv-ABCABCABCABCABCA",
+ "type": "configuration-versions"
+ },
+ "links": {
+ "related": "/api/v2/runs/run-ABCABCABCABCABCA/configuration-version"
+ }
+ },
+ "created-by": {
+ "data": {
+ "id": "user-ABCABCABCABCABCA",
+ "type": "users"
+ },
+ "links": {
+ "related": "/api/v2/runs/run-ABCABCABCABCABCA/created-by"
+ }
+ },
+ "plan": {
+ "data": {
+ "id": "plan-ABCABCABCABCABCA",
+ "type": "plans"
+ },
+ "links": {
+ "related": "/api/v2/runs/run-ABCABCABCABCABCA/plan"
+ }
+ },
+ "run-events": {
+ "data": [
+ {
+ "id": "re-ABCABCABCABCABCA",
+ "type": "run-events"
+ },
+ {
+ "id": "re-ABCABCABCABCABCA",
+ "type": "run-events"
+ },
+ {
+ "id": "re-ABCABCABCABCABCA",
+ "type": "run-events"
+ },
+ {
+ "id": "re-ABCABCABCABCABCA",
+ "type": "run-events"
+ }
+ ],
+ "links": {
+ "related": "/api/v2/runs/run-ABCABCABCABCABCA/run-events"
+ }
+ },
+ "task-stages": {
+ "data": [],
+ "links": {
+ "related": "/api/v2/runs/run-ABCABCABCABCABCA/task-stages"
+ }
+ },
+ "policy-checks": {
+ "data": [],
+ "links": {
+ "related": "/api/v2/runs/run-ABCABCABCABCABCA/policy-checks"
+ }
+ },
+ "comments": {
+ "data": [],
+ "links": {
+ "related": "/api/v2/runs/run-ABCABCABCABCABCA/comments"
+ }
+ }
+ },
+ "links": {
+ "self": "/api/v2/runs/run-ABCABCABCABCABCA"
+ }
+ },
+ {
+ "id": "run-ABCABCABCABCABCA",
+ "type": "runs",
+ "attributes": {
+ "actions": {
+ "is-cancelable": false,
+ "is-confirmable": false,
+ "is-discardable": false,
+ "is-force-cancelable": false
+ },
+ "allow-config-generation": false,
+ "allow-empty-apply": false,
+ "auto-apply": true,
+ "canceled-at": null,
+ "created-at": "2023-10-25T10:33:02.368Z",
+ "has-changes": true,
+ "is-destroy": false,
+ "message": "Triggered via CLI",
+ "plan-only": false,
+ "refresh": true,
+ "refresh-only": false,
+ "replace-addrs": null,
+ "save-plan": false,
+ "source": "terraform+cloud",
+ "status-timestamps": {
+ "applied-at": "2023-10-25T10:33:19+00:00",
+ "planned-at": "2023-10-25T10:33:11+00:00",
+ "queuing-at": "2023-10-25T10:33:02+00:00",
+ "applying-at": "2023-10-25T10:33:16+00:00",
+ "planning-at": "2023-10-25T10:33:07+00:00",
+ "confirmed-at": "2023-10-25T10:33:11+00:00",
+ "plan-queued-at": "2023-10-25T10:33:03+00:00",
+ "apply-queued-at": "2023-10-25T10:33:12+00:00",
+ "queuing-apply-at": "2023-10-25T10:33:11+00:00",
+ "plan-queueable-at": "2023-10-25T10:33:02+00:00"
+ },
+ "status": "applied",
+ "target-addrs": null,
+ "trigger-reason": "manual",
+ "terraform-version": "1.4.4",
+ "permissions": {
+ "can-apply": true,
+ "can-cancel": true,
+ "can-comment": true,
+ "can-discard": true,
+ "can-force-execute": true,
+ "can-force-cancel": true,
+ "can-override-policy-check": true
+ },
+ "variables": []
+ },
+ "relationships": {
+ "workspace": {
+ "data": {
+ "id": "ws-ABCABCABCABCABCA",
+ "type": "workspaces"
+ }
+ },
+ "apply": {
+ "data": {
+ "id": "apply-ABCABCABCABCABCA",
+ "type": "applies"
+ },
+ "links": {
+ "related": "/api/v2/runs/run-ABCABCABCABCABCA/apply"
+ }
+ },
+ "configuration-version": {
+ "data": {
+ "id": "cv-ABCABCABCABCABCA",
+ "type": "configuration-versions"
+ },
+ "links": {
+ "related": "/api/v2/runs/run-ABCABCABCABCABCA/configuration-version"
+ }
+ },
+ "created-by": {
+ "data": {
+ "id": "user--ABCABCABCABCABCA",
+ "type": "users"
+ },
+ "links": {
+ "related": "/api/v2/runs/run-ABCABCABCABCABCA/created-by"
+ }
+ },
+ "plan": {
+ "data": {
+ "id": "plan-ABCABCABCABCABCA",
+ "type": "plans"
+ },
+ "links": {
+ "related": "/api/v2/runs/run-ABCABCABCABCABCA/plan"
+ }
+ },
+ "run-events": {
+ "data": [
+ {
+ "id": "re-ABCABCABCABCABCA",
+ "type": "run-events"
+ }
+ ],
+ "links": {
+ "related": "/api/v2/runs/run-ABCABCABCABCABCA/run-events"
+ }
+ },
+ "task-stages": {
+ "data": [],
+ "links": {
+ "related": "/api/v2/runs/run-ABCABCABCABCABCA/task-stages"
+ }
+ },
+ "policy-checks": {
+ "data": [],
+ "links": {
+ "related": "/api/v2/runs/run-ABCABCABCABCABCA/policy-checks"
+ }
+ },
+ "comments": {
+ "data": [],
+ "links": {
+ "related": "/api/v2/runs/run-ABCABCABCABCABCA/comments"
+ }
+ }
+ },
+ "links": {
+ "self": "/api/v2/runs/run-ABCABCABCABCABCA"
+ }
+ }
+ ],
+ "links": {
+ "self": "https://app.terraform.io/api/v2/workspaces/ws-ABCABCABCABCABCA/runs?page%5Bnumber%5D=1&page%5Bsize%5D=20",
+ "first": "https://app.terraform.io/api/v2/workspaces/ws-ABCABCABCABCABCA/runs?page%5Bnumber%5D=1&page%5Bsize%5D=20",
+ "prev": null,
+ "next": null,
+ "last": "https://app.terraform.io/api/v2/workspaces/ws-ABCABCABCABCABCA/runs?page%5Bnumber%5D=1&page%5Bsize%5D=20"
+ },
+ "meta": {
+ "pagination": {
+ "current-page": 1,
+ "page-size": 20,
+ "prev-page": null,
+ "next-page": null,
+ "total-pages": 1,
+ "total-count": 2
+ },
+ "status-counts": {
+ "pending": 0,
+ "fetching": 0,
+ "fetching-completed": 0,
+ "pre-plan-running": 0,
+ "pre-plan-completed": 0,
+ "queuing": 0,
+ "plan-queued": 0,
+ "planning": 0,
+ "planned": 0,
+ "confirmed": 0,
+ "queuing-apply": 0,
+ "apply-queued": 0,
+ "applying": 0,
+ "applied": 1,
+ "discarded": 0,
+ "errored": 0,
+ "canceled": 0,
+ "cost-estimating": 0,
+ "cost-estimated": 0,
+ "policy-checking": 0,
+ "policy-override": 0,
+ "policy-checked": 0,
+ "policy-soft-failed": 0,
+ "planned-and-finished": 2,
+ "planned-and-saved": 0,
+ "post-plan-running": 0,
+ "post-plan-completed": 0,
+ "pre-apply-running": 0,
+ "pre-apply-completed": 0,
+ "post-apply-running": 0,
+ "post-apply-completed": 0,
+ "assessing": 0,
+ "assessed": 0,
+ "pre-plan-awaiting-decision": 0,
+ "post-plan-awaiting-decision": 0,
+ "pre-apply-awaiting-decision": 0,
+ "total": 3
+ }
+ }
+ }
+ },
+ "IndicatorTimeline": [],
+ "IgnoreAutoExtract": false,
+ "Note": false,
+ "Relationships": []
+ }
+}
\ No newline at end of file
diff --git a/Packs/HashiCorpTerraform/README.md b/Packs/HashiCorpTerraform/README.md
new file mode 100644
index 000000000000..c25acf97fe4f
--- /dev/null
+++ b/Packs/HashiCorpTerraform/README.md
@@ -0,0 +1,8 @@
+HashiCorp Terraform is an Infrastructure as Code (IaC) tool designed to streamline and automate the deployment and management of infrastructure across diverse environments.
+
+## What does this pack do?
+- List runs in a workspace.
+- Perform actions on a run such as: apply, cancel, discard, etc.
+- Show a plan.
+- List a policy's policy sets and policy checks.
+
diff --git a/Packs/HashiCorpTerraform/TestPlaybooks/HasiCoprTerraformTest.yml b/Packs/HashiCorpTerraform/TestPlaybooks/HasiCoprTerraformTest.yml
new file mode 100644
index 000000000000..95e3b9be8c52
--- /dev/null
+++ b/Packs/HashiCorpTerraform/TestPlaybooks/HasiCoprTerraformTest.yml
@@ -0,0 +1,590 @@
+id: HasiCoprTerraformTest
+version: -1
+name: HasiCoprTerraformTest
+fromversion: 6.10.0
+starttaskid: "0"
+tasks:
+ "0":
+ id: "0"
+ taskid: 6375b828-bb18-4371-815f-ca382522a88f
+ type: start
+ task:
+ id: 6375b828-bb18-4371-815f-ca382522a88f
+ version: -1
+ name: ""
+ iscommand: false
+ brand: ""
+ description: ''
+ nexttasks:
+ '#none#':
+ - "1"
+ separatecontext: false
+ continueonerrortype: ""
+ view: |-
+ {
+ "position": {
+ "x": 480,
+ "y": 50
+ }
+ }
+ note: false
+ timertriggers: []
+ ignoreworker: false
+ skipunavailable: false
+ quietmode: 0
+ isoversize: false
+ isautoswitchedtoquietmode: false
+ "1":
+ id: "1"
+ taskid: 626a14eb-fddc-441a-832b-89c6e2f89388
+ type: regular
+ task:
+ id: 626a14eb-fddc-441a-832b-89c6e2f89388
+ version: -1
+ name: Delete Context
+ description: |-
+ Delete field from context.
+
+ This automation runs using the default Limited User role, unless you explicitly change the permissions.
+ For more information, see the section about permissions here:
+ https://docs-cortex.paloaltonetworks.com/r/Cortex-XSOAR/6.10/Cortex-XSOAR-Administrator-Guide/Automations
+ scriptName: DeleteContext
+ type: regular
+ iscommand: false
+ brand: ""
+ nexttasks:
+ '#none#':
+ - "2"
+ - "5"
+ - "7"
+ scriptarguments:
+ all:
+ simple: "yes"
+ separatecontext: false
+ continueonerrortype: ""
+ view: |-
+ {
+ "position": {
+ "x": 480,
+ "y": 195
+ }
+ }
+ note: false
+ timertriggers: []
+ ignoreworker: false
+ skipunavailable: false
+ quietmode: 0
+ isoversize: false
+ isautoswitchedtoquietmode: false
+ "2":
+ id: "2"
+ taskid: 5bb5eb7e-4a8c-458a-8672-35ba16b45603
+ type: regular
+ task:
+ id: 5bb5eb7e-4a8c-458a-8672-35ba16b45603
+ version: -1
+ name: Get runs
+ description: List Runs in a Workspace.
+ script: HashicorpTerraform|||terraform-runs-list
+ type: regular
+ iscommand: true
+ brand: HashicorpTerraform
+ nexttasks:
+ '#none#':
+ - "3"
+ separatecontext: false
+ continueonerrortype: ""
+ view: |-
+ {
+ "position": {
+ "x": 1237.5,
+ "y": 370
+ }
+ }
+ note: false
+ timertriggers: []
+ ignoreworker: false
+ skipunavailable: false
+ quietmode: 0
+ isoversize: false
+ isautoswitchedtoquietmode: false
+ "3":
+ id: "3"
+ taskid: d56a6240-1a27-4a0b-8f81-c54d4e593a3e
+ type: condition
+ task:
+ id: d56a6240-1a27-4a0b-8f81-c54d4e593a3e
+ version: -1
+ name: Check results
+ type: condition
+ iscommand: false
+ brand: ""
+ nexttasks:
+ "yes":
+ - "9"
+ - "14"
+ separatecontext: false
+ conditions:
+ - label: "yes"
+ condition:
+ - - operator: isNotEmpty
+ left:
+ value:
+ simple: Terraform.Run.data.id
+ iscontext: true
+ continueonerrortype: ""
+ view: |-
+ {
+ "position": {
+ "x": 1237.5,
+ "y": 545
+ }
+ }
+ note: false
+ timertriggers: []
+ ignoreworker: false
+ skipunavailable: false
+ quietmode: 0
+ isoversize: false
+ isautoswitchedtoquietmode: false
+ "4":
+ id: "4"
+ taskid: bf005cc4-5bbf-4753-8bae-4ed9daa6944e
+ type: condition
+ task:
+ id: bf005cc4-5bbf-4753-8bae-4ed9daa6944e
+ version: -1
+ name: Check results
+ type: condition
+ iscommand: false
+ brand: ""
+ nexttasks:
+ "yes":
+ - "6"
+ separatecontext: false
+ conditions:
+ - label: "yes"
+ condition:
+ - - operator: isNotEmpty
+ left:
+ value:
+ simple: Terraform.Policy.id
+ iscontext: true
+ right:
+ value: {}
+ continueonerrortype: ""
+ view: |-
+ {
+ "position": {
+ "x": 50,
+ "y": 1245
+ }
+ }
+ note: false
+ timertriggers: []
+ ignoreworker: false
+ skipunavailable: false
+ quietmode: 0
+ isoversize: false
+ isautoswitchedtoquietmode: false
+ "5":
+ id: "5"
+ taskid: 32d0a14c-8316-40f9-863b-480cbf3ed08c
+ type: regular
+ task:
+ id: 32d0a14c-8316-40f9-863b-480cbf3ed08c
+ version: -1
+ name: Get policies
+ description: List the policies for an organization or get a specific policy.
+ script: HashicorpTerraform|||terraform-policies-list
+ type: regular
+ iscommand: true
+ brand: HashicorpTerraform
+ nexttasks:
+ '#none#':
+ - "4"
+ separatecontext: false
+ continueonerrortype: ""
+ view: |-
+ {
+ "position": {
+ "x": 50,
+ "y": 1070
+ }
+ }
+ note: false
+ timertriggers: []
+ ignoreworker: false
+ skipunavailable: false
+ quietmode: 0
+ isoversize: false
+ isautoswitchedtoquietmode: false
+ "6":
+ id: "6"
+ taskid: 76a15b24-c939-4b4e-8776-ff9b48f8b023
+ type: title
+ task:
+ id: 76a15b24-c939-4b4e-8776-ff9b48f8b023
+ version: -1
+ name: Done
+ type: title
+ iscommand: false
+ brand: ""
+ description: ''
+ separatecontext: false
+ continueonerrortype: ""
+ view: |-
+ {
+ "position": {
+ "x": 910,
+ "y": 1420
+ }
+ }
+ note: false
+ timertriggers: []
+ ignoreworker: false
+ skipunavailable: false
+ quietmode: 0
+ isoversize: false
+ isautoswitchedtoquietmode: false
+ "7":
+ id: "7"
+ taskid: ceaa78e4-a2bd-4d32-8678-787fde152023
+ type: regular
+ task:
+ id: ceaa78e4-a2bd-4d32-8678-787fde152023
+ version: -1
+ name: Get policies set
+ description: List the policy sets for an organization or get a specific policy set.
+ script: HashicorpTerraform|||terraform-policy-set-list
+ type: regular
+ iscommand: true
+ brand: HashicorpTerraform
+ nexttasks:
+ '#none#':
+ - "8"
+ separatecontext: false
+ continueonerrortype: ""
+ view: |-
+ {
+ "position": {
+ "x": 480,
+ "y": 1070
+ }
+ }
+ note: false
+ timertriggers: []
+ ignoreworker: false
+ skipunavailable: false
+ quietmode: 0
+ isoversize: false
+ isautoswitchedtoquietmode: false
+ "8":
+ id: "8"
+ taskid: 53b3c8d0-49b6-435c-81b9-eb6287adcd7b
+ type: condition
+ task:
+ id: 53b3c8d0-49b6-435c-81b9-eb6287adcd7b
+ version: -1
+ name: Check results
+ type: condition
+ iscommand: false
+ brand: ""
+ nexttasks:
+ "yes":
+ - "6"
+ separatecontext: false
+ conditions:
+ - label: "yes"
+ condition:
+ - - operator: isNotEmpty
+ left:
+ value:
+ simple: Terraform.PolicySet.id
+ iscontext: true
+ right:
+ value: {}
+ - - operator: isNotEmpty
+ left:
+ value:
+ simple: Terraform.PolicySet.relationships.policies.data.id
+ iscontext: true
+ continueonerrortype: ""
+ view: |-
+ {
+ "position": {
+ "x": 480,
+ "y": 1245
+ }
+ }
+ note: false
+ timertriggers: []
+ ignoreworker: false
+ skipunavailable: false
+ quietmode: 0
+ isoversize: false
+ isautoswitchedtoquietmode: false
+ "9":
+ id: "9"
+ taskid: 3a9c20ab-f588-4c89-8028-417d2ecc037f
+ type: regular
+ task:
+ id: 3a9c20ab-f588-4c89-8028-417d2ecc037f
+ version: -1
+ name: Get policies checks
+ description: List the policy checks for a Terraform run.
+ script: HashicorpTerraform|||terraform-policies-checks-list
+ type: regular
+ iscommand: true
+ brand: HashicorpTerraform
+ nexttasks:
+ '#none#':
+ - "10"
+ scriptarguments:
+ run_id:
+ complex:
+ root: ${Terraform.Run.data
+ accessor: id}
+ transformers:
+ - operator: FirstArrayElement
+ separatecontext: false
+ continueonerrortype: ""
+ view: |-
+ {
+ "position": {
+ "x": 910,
+ "y": 720
+ }
+ }
+ note: false
+ timertriggers: []
+ ignoreworker: false
+ skipunavailable: false
+ quietmode: 0
+ isoversize: false
+ isautoswitchedtoquietmode: false
+ "10":
+ id: "10"
+ taskid: 281f4176-8cde-472b-8bfa-587300ee929d
+ type: regular
+ task:
+ id: 281f4176-8cde-472b-8bfa-587300ee929d
+ version: -1
+ name: Get plan meta
+ description: Get plan JSON file or the plan meta data.
+ script: HashicorpTerraform|||terraform-plan-get
+ type: regular
+ iscommand: true
+ brand: HashicorpTerraform
+ nexttasks:
+ '#none#':
+ - "11"
+ scriptarguments:
+ plan_id:
+ complex:
+ root: Terraform.Run.data.relationships.plan.data
+ accessor: id
+ transformers:
+ - operator: FirstArrayElement
+ separatecontext: false
+ continueonerrortype: ""
+ view: |-
+ {
+ "position": {
+ "x": 910,
+ "y": 895
+ }
+ }
+ note: false
+ timertriggers: []
+ ignoreworker: false
+ skipunavailable: false
+ quietmode: 0
+ isoversize: false
+ isautoswitchedtoquietmode: false
+ "11":
+ id: "11"
+ taskid: 1881c39a-2d9a-4b1d-868f-ec2296b3164c
+ type: condition
+ task:
+ id: 1881c39a-2d9a-4b1d-868f-ec2296b3164c
+ version: -1
+ name: Check response
+ type: condition
+ iscommand: false
+ brand: ""
+ nexttasks:
+ "yes":
+ - "12"
+ separatecontext: false
+ conditions:
+ - label: "yes"
+ condition:
+ - - operator: isNotEmpty
+ left:
+ value:
+ simple: Terraform.Plan.attributes.status
+ iscontext: true
+ continueonerrortype: ""
+ view: |-
+ {
+ "position": {
+ "x": 910,
+ "y": 1070
+ }
+ }
+ note: false
+ timertriggers: []
+ ignoreworker: false
+ skipunavailable: false
+ quietmode: 0
+ isoversize: false
+ isautoswitchedtoquietmode: false
+ "12":
+ id: "12"
+ taskid: b318ab98-ca6c-4bbc-8c75-0c70d045ea5c
+ type: regular
+ task:
+ id: b318ab98-ca6c-4bbc-8c75-0c70d045ea5c
+ version: -1
+ name: Get plan file result
+ description: Get plan JSON file or the plan meta data.
+ script: HashicorpTerraform|||terraform-plan-get
+ type: regular
+ iscommand: true
+ brand: HashicorpTerraform
+ nexttasks:
+ '#none#':
+ - "6"
+ scriptarguments:
+ json_output:
+ simple: "true"
+ plan_id:
+ complex:
+ root: Terraform.Plan
+ accessor: id
+ transformers:
+ - operator: FirstArrayElement
+ separatecontext: false
+ continueonerrortype: ""
+ view: |-
+ {
+ "position": {
+ "x": 910,
+ "y": 1245
+ }
+ }
+ note: false
+ timertriggers: []
+ ignoreworker: false
+ skipunavailable: false
+ quietmode: 0
+ isoversize: false
+ isautoswitchedtoquietmode: false
+ "13":
+ id: "13"
+ taskid: 9675207f-b3a6-4a2b-80d6-9b7706157b1c
+ type: regular
+ task:
+ id: 9675207f-b3a6-4a2b-80d6-9b7706157b1c
+ version: -1
+ name: Run action
+ description: 'Perform an action on a Terraform run. The available actions are: apply, cancel, discard, force-cancel, force-execute.'
+ script: HashicorpTerraform|||terraform-run-action
+ type: regular
+ iscommand: true
+ brand: HashicorpTerraform
+ nexttasks:
+ '#none#':
+ - "6"
+ scriptarguments:
+ action:
+ simple: discard
+ comment:
+ simple: comment from TPB
+ run_id:
+ complex:
+ root: Terraform.Run.data
+ filters:
+ - - operator: isEqualString
+ left:
+ value:
+ simple: Terraform.Run.data.attributes.actions.is-discardable
+ iscontext: true
+ right:
+ value:
+ simple: "true"
+ accessor: id
+ transformers:
+ - operator: FirstArrayElement
+ separatecontext: false
+ continueonerrortype: ""
+ view: |-
+ {
+ "position": {
+ "x": 1340,
+ "y": 1245
+ }
+ }
+ note: false
+ timertriggers: []
+ ignoreworker: false
+ skipunavailable: false
+ quietmode: 0
+ isoversize: false
+ isautoswitchedtoquietmode: false
+ "14":
+ id: "14"
+ taskid: 7fd5e23d-089a-4003-8bab-faf19a556929
+ type: condition
+ task:
+ id: 7fd5e23d-089a-4003-8bab-faf19a556929
+ version: -1
+ name: There are run to discard
+ type: condition
+ iscommand: false
+ brand: ""
+ nexttasks:
+ '#default#':
+ - "6"
+ "yes":
+ - "13"
+ separatecontext: false
+ conditions:
+ - label: "yes"
+ condition:
+ - - operator: isTrue
+ left:
+ value:
+ simple: Terraform.Run.data.attributes.actions.is-discardable
+ iscontext: true
+ continueonerrortype: ""
+ view: |-
+ {
+ "position": {
+ "x": 1452.5,
+ "y": 1070
+ }
+ }
+ note: false
+ timertriggers: []
+ ignoreworker: false
+ skipunavailable: false
+ quietmode: 0
+ isoversize: false
+ isautoswitchedtoquietmode: false
+view: |-
+ {
+ "linkLabelsPosition": {},
+ "paper": {
+ "dimensions": {
+ "height": 1435,
+ "width": 1782.5,
+ "x": 50,
+ "y": 50
+ }
+ }
+ }
+inputs: []
+outputs: []
+description: ''
diff --git a/Packs/HashiCorpTerraform/pack_metadata.json b/Packs/HashiCorpTerraform/pack_metadata.json
new file mode 100644
index 000000000000..4e9ffbaefb84
--- /dev/null
+++ b/Packs/HashiCorpTerraform/pack_metadata.json
@@ -0,0 +1,19 @@
+{
+ "name": "HashiCorp Terraform",
+ "description": "Hashicorp Terraform provide infrastructure automation to provision and manage resources in any cloud or data center with Terraform.",
+ "support": "xsoar",
+ "currentVersion": "1.0.0",
+ "author": "Cortex XSOAR",
+ "url": "https://www.paloaltonetworks.com/cortex",
+ "email": "",
+ "categories": [
+ "IT Services"
+ ],
+ "tags": [],
+ "useCases": [],
+ "keywords": [],
+ "marketplaces": [
+ "xsoar",
+ "marketplacev2"
+ ]
+}
\ No newline at end of file
diff --git a/Tests/conf.json b/Tests/conf.json
index c7952f72b202..451df39c4995 100644
--- a/Tests/conf.json
+++ b/Tests/conf.json
@@ -3514,6 +3514,11 @@
"integrations": "Code42",
"fromversion": "6.10.0"
},
+ {
+ "playbookID": "HasiCoprTerraformTest",
+ "integrations": "HashicorpTerraform",
+ "fromversion": "6.10.0"
+ },
{
"playbookID": "FetchIndicatorsFromFile-test",
"fromversion": "5.5.0"