AWS Cloud Operations & Migrations Blog

Automate AWS Account configuration and onboarding for AWS Service Management Connector for ServiceNow

Many enterprises use ServiceNow to support their IT Service Management (ITSM) processes.  These enterprises are looking for ways to manage and integrate their AWS cloud operations with their existing ServiceNow deployments.  AWS provides the AWS Service Management Connector (SMC) for ServiceNow to enable users to provision, manage, and operate AWS resources natively through ServiceNow.

To setup the SMC, customers are required to configure AWS Identity and Access Management (IAM) user credentials for all required AWS accounts within their AWS Organizations deployment. This requires customers to share credentials with their cloud operations team and their ServiceNow team for manual entry into ServiceNow.  The SMC provides integrations with multiple AWS services and these must also be configured per account within ServiceNow and the AWS account.  The IAM user access keys configured for every account also needed to be rotated on a defined schedule and manually updated in SMC to comply with security best practices.

Customers may also utilize multiple ServiceNow instances for development, test, and production that need to be integrated and configured with SMC. This blog provides a solution to automate the AWS account onboarding and configuration process for SMC.

The source code for the solution is available here.

Solution overview

This solution enables you to automatically configure new and existing AWS accounts with ServiceNow instances. The solution automates the IAM credential configuration and management required by the SMC across multiple AWS accounts and regions.  IAM user access key rotation and update within SMC can also be automated on a schedule of your choice.

Using this solution, SMC integrations can be selectively enabled / disabled consistently across multiple accounts.

Services used

The following services are used within this post:

  1. AWS Organizations – The solution reads AWS account names from Organizations to name each corresponding configuration within the SMC in ServiceNow.
  2. AWS CloudFormationService-managed StackSets are used to automatically deploy and update the solution across AWS accounts within the Organizational Units (OUs) that you specify. A CloudFormation custom resource is used to manage the solution lifecycle for each account.
  3. AWS Lambda – Lambda implements the automation logic for the solution as a CloudFormation custom resource. The code is written in Python.
  4. AWS Systems Manager Parameter Store – ServiceNow credentials are stored within AWS Systems Manager Parameter Store for each ServiceNow instance. These credentials are read by the Lambda function to make authenticated calls with ServiceNow to automatically configure the SMC.

Architecture diagram

Figure 1. Architecture diagram describing how IAM credentials are created in individual workload accounts and the Lambda invocation to create the AWS account entry in ServiceNow.

Figure 1. Architecture diagram describing how IAM credentials are created in individual workload accounts and the Lambda invocation to create the AWS account entry in ServiceNow

CloudFormation service-managed StackSets

CloudFormation service-managed StackSets are used by the solution to deploy the IAM Users, access keys, and additional resources required by the SMC for the target OUs that you want to enable. Automatic deployments are used by the solution to automate the process for new accounts. Service-managed StackSets, along with automatic deployments, automate the solution account management when accounts are added to a target Organization or OU, removed from a target Organization or OU, or moved between target OUs.

Before you create a StackSet with service-managed permissions, you must first complete the following tasks:

Enable all features in Organizations. With only consolidated billing features enabled, you can’t create a StackSet with service-managed permissions.
Enable trusted access with Organizations. After trusted access is enabled, StackSets creates the necessary IAM roles in the Organization’s management account and target (member) accounts when you create StackSets with service-managed permissions.

Service-managed StackSets must be deployed in either the Organizations Management account or a Delegated Administrator account for CloudFormation StackSets.

CloudFormation custom resource backed by Lambda

A Lambda-backed CloudFormation custom resource is used to manage the credentials in ServiceNow for the account. The custom resource receives the IAM User access key and secret access key under resource properties. Deploying the solution as a CloudFormation custom resource enables you to manage the solution lifecycle for each AWS account and automate the solution deployment and update.

Based on invocation type, a new account entry will be created in ServiceNow (CloudFormation create) or the existing account will be updated (CloudFormation Update). If you’re deploying the Custom Resource Lambda within a VPC, then make sure that any firewalls in use are updated to allow connectivity from Lambda to the ServiceNow endpoints.

The Lambda function should be deployed in an AWS account, such as a shared services account, where connectivity to the configured ServiceNow endpoints is available. As shown in the previous figure, CloudFormation stack instances for each AWS account invoke the Lambda function to configure the SMC in ServiceNow. ServiceNow API credentials are stored in AWS Systems Manager Parameter Store and the Lambda function stores the generated IAM credentials in AWS Secrets Manager as a backup. When IAM credentials are changed on a schedule, the AWS Secrets Manager keys are updated as well.

Solution deployment

Follow these steps to deploy the solution. The source code is available here.

Prerequisites

The following prerequisites are required to follow along with this post:

  1. An Amazon Simple Storage Service (Amazon S3) bucket where you can copy files for Lambda function deployment.
  2. A ServiceNow account and password for each target ServiceNow instance that ’you’ll be integrating with the AWS Service Management Connector.
  3. Permissions to deploy an IAM role in your Organizations Management/Root account or Delegated Admin account.
  4. An AWS account where the Lambda function will be deployed and where your ServiceNow account credentials will be securely stored in AWS Systems Manager Parameter Store (referred to as Solution Deployment account in this README).

1. Storing the ServiceNow API credentials

The ServiceNow API endpoint credentials are stored in the AWS Systems Manager parameter store as a secret string. The path should be defined as shown in the following.

  • Log in to the AWS Shared Service Account
  • Navigate to AWS Systems Manager -> Parameter Store

Create the Username Parameter:

  • Select the Create parameter button.
  • Complete the fields on the form
    • Name: /ServiceNow/<ServiceNow Instance Name>.servicenow.com/username
    • Description: Valid description for parameter. For example: “ServiceNow API username”
    • Tier: Standard
    • Type: String
    • Data Type: Text
    • Value: Provide the username that will be used to authenticate with the ServiceNow AWS Accounts API.
  • Select the Create Parameter at the bottom to save.

Create the password parameter:

  • Select the Create parameter button.
  • Complete the fields on the form
    • Name: /ServiceNow/<ServiceNow Instance Name>.servicenow.com/password
    • Description: Valid description for parameter. For example: “ServiceNow API password”
    • Tier: Standard
    • Type: SecureString
    • KMS Key Source: My Current Account
    • KMS Key ID: Choose the Key that will be used to encrypt the secret. Note that the Lambda function should have access to this key to decrypt the password parameter.
    • Data Type: Text
    • Value: Provide the password that will be used to authenticate with the ServiceNow api.
  • Select Create parameter at the bottom to save.

2. Creating the custom resource Lambda

To deploy the Lambda function, the code must be packaged as a zip and uploaded to an S3 bucket in the shared services Account.

Package the Lambda function code following these instructions:

Make a build directory to store the files that must be packaged:

mkdir -p src/build/

Copy the python files to the build directory:

cd src/functions
cp aws_client.py ../build
cp snow_client.py ../build
cp lambda_function.py ../build

Install the Python dependencies targeting the build directory:

pip install -r requirements.txt -t ../build

Linux:

cd ../build
zip -r snowregister-v1.zip .

Windows:

  • Navigate to the build folder.
  • Select all -> Send to compressed file.
  • Name the zip file as snowregister-v1.zip.

Upload the zip file to the S3 bucket through AWS Command Line Interface (AWS CLI):

aws s3 cp snowregister-v1.zip s3://<bucket-name>/ --region us-east-1
cd ../..
rm -rf src/build

Via Console:

  • Log in to the AWS Console.
  • Navigate to the Amazon S3 Service console.
  • Select the bucket to upload the zip file.
  • Choose
  • Select the snowregister-v1.zip and upload.

3. Creating the required stacks and StackSets

3.1 Create the Lambda function stack

Create a CloudFormation stack named servicenow-automation in the shared services account via AWS CLI. Update the following command by replacing the parameters with the correct values for S3CodeBucket, VpcId, SubnetIdList, ManagementAccountId, OrganizationID, AssumrRoleName, and AssumeRoleAccountID.

aws cloudformation deploy --stack-name servicenow-automation \
--template-file src/templates/servicenow_connector_auto_register.yaml \
--parameter-overrides AssumeRoleArn=None \
S3CodeBucket='<S3 Bucket Name>' \
VpcId='vpc-id-1' \
SubnetIdList='subnet-1,subnet-2' \
ManagementAccountId='111111111111' \
OrganizationID='o-xxxxxx' \
--region us-east-1 --capabilities CAPABILITY_NAMED_IAM

3.2 Setup the assume role

The Lambda function needs access to the Management or Delegated admin account to query the Organizations service to get the account name using the account ID. To achieve this, a role must be created in the Management or Delegated admin account. Run the following command after updating the values for SourceRoleArn and ManagementAccountId.

aws cloudformation deploy --stack-name servicenow-lambda-assume-role-stack \
--template-file src/templates/servicenow_assume_role.yaml –parameter-
overrides SourceRoleArn=<Lambda Role ARN> ManagementAccountId =’11111111111’ --region us-east-1

3.3 Deploy the IAM User Stackset (Delegated Admin or Management Account)

The IAM stack invokes the Lambda as a Custom Resource to insert/update the IAM User access tokens into ServiceNow. The custom resource properties manages the service integrations configuration of the connector.

The highlighted properties in the custom resource properties in the following CloudFormation snippet enable or disable the connector integration with the AWS Services. Update the template src/templates/servicenow_connector_global_config.yaml with the desired settings for the service integrations before creating the stackset.

RegisterSerNow:
    Type: Custom::ServiceNowReg
    Properties:
      ServiceToken: !Ref LambdaArn
      Region: !Ref "AWS::Region"
      AccountId: !Ref AWS::AccountId
      KeyVersion: !Ref KeyVersion
      ServiceNowUrl: !Ref ServiceNowUrl
      SCEndUser:
        UserName: !Ref SCEndUserName
        AccessKey: !Ref 'SCEndUserAccessKeys'
        SecretAccessKey: !GetAtt 'SCEndUserAccessKeys.SecretAccessKey'
      SCSyncUser:
        UserName: !Ref SCSyncUserName
        AccessKey: !Ref 'SCSyncUserAccessKeys'
        SecretAccessKey: !GetAtt 'SCSyncUserAccessKeys.SecretAccessKey'
      
      EnableSystemsManager: False    
      EnableChangeManager: False    
      EnableOpsCenter: False        
      EnableServiceCatalog: False    
      EnableConfig: False            
      EnableAwsSupport: False        
      EnableSecurityHub: False       
      EnableHealthDashboard: False  
      EnableIncidentManager: False  
      EnableRegions:                
        - us-east-1
      Tags:
        - Key: App_Name
          Value: Service_Now_connector

Run the following command after updating the values for

LambdaArn – This is the ARN of the Lambda function deployed in the Shared Service Account.

KeyVersion – Starts from 1.

ServiceNowUrl – The ServiceNow instance URL (<ServiceNow instance name>.servicenow.com).

aws cloudformation create-stack-set --stack-set-name service-snow-config --description "Deploys IAM User in the target OU and calls the custom resource to store the keys in service now" --template-body file://src/templates/servicenow_connector_global_config.yaml \
--parameters ParameterKey=LambdaArn,ParameterValue='<Lambda Function ARN>' \
ParameterKey=KeyVersion,ParameterValue=1 \
ParameterKey=ServiceNowUrl,ParameterValue='XXXXX.servicenow.com' \
--capabilities CAPABILITY_NAMED_IAM \
--permission-model SERVICE_MANAGED \
--auto-deployment Enabled=true,RetainStacksOnAccountRemoval=false \
--call-as DELEGATED_ADMIN \
--managed-execution Active=false \
--region us-east-1

Create stack instances in the target Organization or OU.

aws cloudformation create-stack-instances --stack-set-name service-snow-config \
--deployment-targets OrganizationalUnitIds='ou-XXXXXXX' \
--regions us-east-1 \
--call-as DELEGATED_ADMIN \
--region us-east-1

3.4 Deploy Stackset to create an SQS queue for Security hub and Health Dashboard

aws cloudformation create-stack-set --stack-set-name servicenow-config-regional \
--description "Deploys IAM User in the target OU and calls the custom resource to store the keys in ServiceNow" \
--template-body file://src/templates/servicenow_connector_regional_config.yaml \
--capabilities CAPABILITY_NAMED_IAM \
--permission-model SERVICE_MANAGED \
--auto-deployment Enabled=true,RetainStacksOnAccountRemoval=false \
--call-as DELEGATED_ADMIN \
--managed-execution Active=false \
--region us-east-1

Add Target to the above Stackset. The Stackset name should match the above.

aws cloudformation create-stack-instances --stack-set-name service-snow-config-regional \
--deployment-targets OrganizationalUnitIds='ou-XXXXXXX' \
--regions us-east-1 \
--call-as DELEGATED_ADMIN \
--region us-east-1

3.5 To integrate the AWS Support, deploy another Stackset for the Support Queue as required by the connector (4.5.0)

aws cloudformation create-stack-set --stack-set-name service-snow-config-support \
--description "Deploys SQS queue for AWS Support integration" \
--template-body file://src/templates/servicenow_connector_support_queue.yaml \
--capabilities CAPABILITY_NAMED_IAM \
--permission-model SERVICE_MANAGED \
--auto-deployment Enabled=true,RetainStacksOnAccountRemoval=false \
--call-as DELEGATED_ADMIN \
--managed-execution Active=false \
--region us-east-1

Add Target to the regional Stackset. The Stackset name should match the above.

aws cloudformation create-stack-instances --stack-set-name servicenow-aws-support \
--deployment-targets OrganizationalUnitIds='ou-XXXXXXX' \
--regions us-east-1 \
--call-as DELEGATED_ADMIN \
--region us-east-1

4. Key rotation

As a security best practice, the IAM User Access and Secret access tokens should be changed on a set schedule to minimize the impact if the keys get compromised.

To rotate the keys, increment the KeyVersion parameter and update the StackSet. The update action forces the CloudFormation AWS::IAM::AccessKey to recreate the keys. The custom resource gets called with the new keys and the Lambda function updates the existing account in the ServiceNow with a new set of keys.

aws cloudformation update-stack-set --stack-set-name servicenow-iam-users --description "Deploys IAM User in the target OU and calls the custom resource to store the keys in ServiceNow" --template-body file://src/templates/servicenow_connector_global_config.yaml \
--parameters ParameterKey=LambdaArn,ParameterValue='<Lambda Function ARN>' \
ParameterKey=KeyVersion,ParameterValue=1 \
ParameterKey=ServiceNowUrl,ParameterValue='<ServiceNow instance name>.servicenow.com' \
--capabilities CAPABILITY_NAMED_IAM \
--permission-model SERVICE_MANAGED \
--auto-deployment Enabled=true,RetainStacksOnAccountRemoval=false \
--call-as DELEGATED_ADMIN \
--managed-execution Active=false \
--region us-east-1

Use cases

For existing AWS accounts within the Organization

The above solution will deploy and create the stack instances and StackSets to all of the accounts within the target OUs.

New AWS account creation

The stackset is set to deploy instances targeting an OU. The deployment permission model is SERVICE_MANAGED. This makes sure that anytime a new account gets added to the target OUs, the stackset will automatically create a new stack-instance in the new account.

Deleting an AWS account

Removing an account from an OU automatically triggers the StackSet to delete the stack instance from the account. The account entry from ServiceNow is NOT removed automatically to preserve existing synched resources in ServiceNow.

Cleanup

To clean up the deployed solution, remove the stack instances from the CloudFormation StackSets. You can use the CloudFormation console or the AWS CLI to remove the instances from the StackSet. Wait for all of the instances to be removed before attempting to delete the StackSet. Delete the StackSets after all of the instances are removed. The solution doesn’t handle the deletion of the account from the Service Management Connector on the ServiceNow platform. Log in to the ServiceNow portal to manually remove the AWS account from the connector.

Summary

This post demonstrates how a customer can implement an automated solution for SMC configuration with multiple AWS accounts and ServiceNow instances. Using this approach, customers can eliminate the manual effort of onboarding AWS Account integration with ServiceNow using the SMC.  You can fork the GitHub solution repository and use it as-is or customize it further to your liking.

The AWS Service Management Connector for ServiceNow application is available at no charge to all AWS customers. Please try the above solution with the connector and If you have feedback about this post, submit comments in the Comments section below.

About the authors:

Sivasankar Achin Jayapal

Sivasankar Achin Jayapal is a Cloud Infrastructure Architect with AWS. He specializes in developing solutions to automate Infrastructure deployments and writing Infrastructure as Code. In his free time, he likes to spend time with family and friends, bingee-watch TV shows, take road trips, and explore new things.

Joe Thomas

Joe Thomas is a Systems Development Engineer with the AWS Service Management Connectors team. He is passionate about driving operational excellence, troubleshooting customer issues, and enjoys building product features and enhancements that drive customer adoption and satisfaction. Outside of work, Joe enjoys spending time with his family on short summer hikes or traveling across the country exploring various food cultures.

Khurram Nizami

Khurram Nizami is a Senior Consultant with AWS. Khurram is passionate about helping people build innovative solutions using technology. In his free time, Khurram enjoys hiking, nature, DIY projects, and travel.