Add new cloud provider in Terraform Connector (AWS)
Add new cloud provider in Terraform Connector (AWS)
Step 1: Terraform AWS authentication
Step 2: Configure an AWS Datacenter Resource Block
Terraform simplifies orchestration of cloud deployments, helping operators build small- to large-scale multi-cloud infrastructures. Instead of creating specific CloudFormation templates for AWS, ARM templates for Azure, and Cloud Deployment Manager for GCP, Terraform lets you deploy across multiple providers using 'template’ files. The ServiceNow Cloud Management application (with the Terraform Connector from the ServiceNow Store) provides out of the box support for providers such as VMware, IBM and MS Azure clouds.
This article takes you through the procedures or steps needed to add a new cloud provider (AWS, in this example) to the Terraform Connector Store app. The main steps are:
Step 1: Terraform AWS authentication:
The ServiceNow Cloud Management application supports credentials where we use access_key and secret_ key as variable defined in template. The values of `keys’ is mapped from Discovery credentials.
You can use the (Infrastructure as Code) IaC Provider Settings user interface to perform credential and service account mappings for DataCenter credentials used by the Terraform provider to provision datacenter resources and Cloud Management for discovery. Mapping credential and service account fields between Cloud Management and Terraform using the IaC Provider Settings, enables you to store and manage credentials in an external credential repository rather than directly in a ServiceNow credentials record. See product documentation for detailed steps.
- This mapping is used to map values of Discovery credential’s keys to variables defined in terraform template.
- For above example, terraform commands will be:
- terraform apply -var secretkey = ‘1234XXXX … ’ -var accesskey = ‘ABCXXXXX…’
- terraform destroy -var secretkey = ‘1234XXXX…’ -var accesskey = ‘ABCXXXXX…’
- Add terraform provider in IaC Settings:
- Discovery credential mapping with provider authentication keys.
- Final output after mapping:
Step 2: Configure an AWS Datacenter Resource Block:
Add the Terraform Orchestration interface on a resource block, to execute cloud-based operations via terraform templates. The product documentation has detailed instructions on setting up an Azure Datacenter resource block. The procedure is mostly similar except that the response processor scripts in this article are specifically for AWS Create Stack and Delete Stack operations. Similarly, you will need to create custom response processors for different resource types, e.g. if you want to add support for GCP and deploy a GCP cloud db - then a response mapping must be done for the cloud db instance.
- Go to Cloud Admin Portal à Design à ResourceBlock à AWS Datacenter
- Add Terraform Orchestration Interfaceto AWS Datacenter
- Add step to CreateStack operation:
| Form Parameter | Value |
|---|---|
| Operation Type | Invoke Cloud API |
| API Provider | Terraform OpenSource |
| API Interface | Configuration Orchestration Interface |
| API Method | ExecuteCommand |
| CAPI Version | 1.0 |
| Condition |
| Parameter | Value |
|---|---|
| AdditionalParameters | {"ServerType":"$(Script:sn_cmp_terraform.TerraformCommandUtils.getConfigProviderServerTypeByName[arg=${parameter.WorkloadConfigProvider}])"} |
| ConfigMgmtProviderInfo | $(capiResolver.NodeCredentialResolver#nodeCredentialId=$(ci.sn_cmp_wl_cfg_mgmt_provider[name=${parameter.WorkloadConfigProvider}].credential)) |
| ConfigurationParameters | ${parameter.ConfigurationParameters} |
| NodeAddress | $(ci.cmdb_ci_workload_config_provider[name=${parameter.WorkloadConfigProvider}].url) |
| ProviderParameters | ${parameter.ProviderParameters} |
| Script | ${CloudScript.scripts.TerraformDeploy} |
| TemplateParameters | ${parameter.TemplateParameters} |
- Create response processor: AWS_TF_Provision_Response_Processor
Script:
function processResponse(response, cloudServiceAccountId, ldc, correlationId, step, requestorContext, stackId) { var responseObject = global.JSON.parse(response); var tfState = global.JSON.parse(responseObject.terraform.state); var processor = new sn_cmp_terraform.TerraformResponseProcessor(); var processedResponses = processor.processResponse(tfState, cloudServiceAccountId, ldc, correlationId, step, requestorContext, stackId); return global.JSON.stringify(processedResponses);
}
- Add response processor to step: AWS_TF_Provision_Response_Processor
- Add step to DeleteStack operation:
| Form Parameter | Value |
|---|---|
| Operation Type | Invoke Cloud API |
| API Provider | Terraform OpenSource |
| API Interface | Configuration Orchestration Interface |
| API Method | ExecuteCommand |
| CAPI Version | 1.0 |
| Condition |
| Parameter | Value |
|---|---|
| AdditionalParameters | {"ServerType":"$(Script:sn_cmp_terraform.TerraformCommandUtils.getConfigProviderServerTypeByName[arg=${parameter.WorkloadConfigProvider}])"} |
| ConfigMgmtProviderInfo | $(capiResolver.NodeCredentialResolver#nodeCredentialId=$(ci.sn_cmp_wl_cfg_mgmt_provider[name=${parameter.WorkloadConfigProvider}].credential)) |
| ConfigurationParameters | ${parameter.ConfigurationParameters} |
| NodeAddress | $(ci.cmdb_ci_workload_config_provider[name=${parameter.WorkloadConfigProvider}].url) |
| ProviderParameters | ${parameter.ProviderParameters} |
| Script | ${CloudScript.scripts.DestroyTerraform} |
| TemplateParameters | ${parameter.TemplateParameters} |
- Create response processor: AWS_TF_Delete_Stack
function processResponse(response, cloudServiceAccountId, ldc, correlationId,step, requestorContext, stackId) { var responseObject = global.JSON.parse(response);var tfResponse = responseObject.terraform;var tfStateAfter = global.JSON.parse(tfResponse['state.after']);var tfStateBefore = global.JSON.parse(tfResponse['state.before']); var processor = new sn_cmp_terraform.DeprovisionTerraformResponseProcessor(); //there is no support for before state currently, hence its handled internallyvar retiredStackItems = processor.updateStackItemTermination(stackId, tfStateBefore, tfStateAfter); if(retiredStackItems) gs.info('Retired CI\'s of stack items'); else gs.warn('Havent retired CI\'s of stack items'); return global.JSON.stringify([{}]);}
Next Steps:
Create a Terraform config provider and run Discovery Create catalog items based on Terraform templates
Reference material:
Resource Blocks Configure a Response Processor Execute response processor for workflow
Create a CI class for virtual cloud resource
Virtual server response processor example (AWS VM CIs)
Labels:
https://www.servicenow.com/community/itom-articles/add-new-cloud-provider-in-terraform-connector-aws/ta-p/2321968
