How To

Turbot custom resources in CloudFormation

Turbot Guardrails Resources can be managed as Custom Resources in CloudFormation. Managing Turbot Guardrails through CloudFormation supports a wide range of scenarios like: managing Turbot Guardrails Resource Groups and Policies, managing Turbot Guardrails Policies (particularly exceptions) in code with the AWS Resources, and automatic cleanup of Turbot-modified resources to prevent CloudFormation conflicts.

Turbot Team
3 min. read - Apr 10, 2018
Turbot Guardrails Resources can be managed as Custom Resources in CloudFormation. Managing Turbot Guardrails through CloudFormation supports a wide range of scenarios like: managing Turbot Guardrails Resource Groups and Policies, managing Turbot Guardrails Policies (particularly exceptions) in code with the AWS Resources, and automatic cleanup of Turbot-modified resources to prevent CloudFormation conflicts.

Overview

Turbot Guardrails Resources can be managed as Custom Resources in CloudFormation.

Managing Turbot Guardrails through CloudFormation supports a wide range of scenarios like:

  • Managing Turbot Guardrails Resource Groups and Policies.
  • Managing Turbot Guardrails Policies (particularly exceptions) in code with the AWS Resources.
  • Automatic cleanup of Turbot-modified resources to prevent CloudFormation conflicts.

Turbot Guardrails Custom Resources use Turbot APIs

Internally, Turbot Guardrails Custom Resources are implemented as API calls to Turbot Guardrails. All aspects of authentication, data validation and audit trail logging are identical.

Authentication

Turbot Guardrails Custom Resources are implemented as API calls to Turbot Guardrails. Each Turbot Guardrails Resource must specify a Turbot Guardrails Access Key and Secret Key pair for authentication.

The basic format is:

MyTurbotResource:
Type: "Custom::Turbot{ResourceType}"
Properties:
Turbot:
AccessKey: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
SecretKey: yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy

Typically this will be implemented through Parameters:

MyTurbotResource:
Type: "Custom::Turbot{ResourceType}"
Properties:
Turbot:
AccessKey: !Ref TurbotAccessKey
SecretKey: !Ref TurbotSecretKey

Note: CloudFormation does not pass any information to the Custom Resource about the AWS identity running the CloudFormation stack. As such, the only identity information available to Turbot Guardrails is provided by the authentication information passed in the Custom Resource definition.

Resource Data, API Endpoints and Field Name Format

The Custom Resource defines the data that will be used for Turbot Guardrails API calls related to the resource type. For example, a TurbotPolicy resource will work with the /api/{apiVersion}/resources/{resourceUrn}/policies endpoints for CREATE, GET, PATCH and DELETE.

Generally, valid resource data is defined by the CREATE endpoint - please refer to the appropriate API documentation for full details.

Data fields for Turbot Guardrails APIs are always defined in camel case and start with a lower case letter (e.g. resourceUrn). CloudFormation resources are typically defined in camel case and start with an upper case letter (e.g. ResourceUrn). To make Turbot Guardrails resources consistent with CloudFormation format, Turbot Guardrails accepts either format for fields and will automatically convert them to start with lower case. For example, using either resourceUrn or ResourceUrn in the Custom Resource makes no difference - both are passed to the API as resourceUrn.

ARN to URN Conversion

It's common to use both AWS resources (defined by ARNs) and Turbot Guardrails resources (defined by URNs) in the same CloudFormation stack. Turbot Guardrails makes this easy by allowing ARNs to be passed in Turbot Guardrails URN fields. For example, the following is valid:

ResourceUrn: !GetAtt TestRole.Arn

Output from Turbot Guardrails Custom Resources

Turbot Guardrails Custom Resources generally return the same results as the underlying API call. The result is not converted to uppercase camel, but always returned exactly as defined in the API (lowercase camel).

ServiceToken for Custom Resources

Custom Resources in CloudFormation must specify a ServiceToken, defining the handler for the resource. Turbot Guardrails Resources can be used from CloudFormation stacks in any region of any Turbot-managed AWS account. The ServiceToken is always set to be:

ServiceToken: !Sub 'arn:aws:sns:${AWS::Region}:${AWS::AccountId}:turbot_aws_api_handler'

Turbot Guardrails Custom Resources

Resource Group

MyPatchingRG:
Type: "Custom::TurbotResourceGroup"
Properties:
ServiceToken: !Sub 'arn:aws:sns:${AWS::Region}:${AWS::AccountId}:turbot_aws_api_handler'
Turbot: { AccessKey: !Ref TurbotAccessKey, SecretKey: !Ref TurbotSecretKey }
Id: my-patching-rg
Title: My Patching Resource Group
ResourceUrn: "urn:turbot:c1:abc"
Description: I am a RG to enforce patching.

Policy

EnforcePatchManagement:
Type: "Custom::TurbotPolicy"
Properties:
ServiceToken: !Sub 'arn:aws:sns:${AWS::Region}:${AWS::AccountId}:turbot_aws_api_handler'
Turbot: { AccessKey: !Ref TurbotAccessKey, SecretKey: !Ref TurbotSecretKey }
ResourceUrn: !GetAtt MyRG.urn
Requirement: MUST
Name: "AWS:EC2:InstancePatchManagement"
Value: "Enforce: Enabled with Target Patch Group"
Notes: |
Always use the patch group defined in AWS > EC2 > Instance Target Patch
Group. This ensures a common patch baseline across all servers unless
they have been explicitly granted an exception.

Resource Group Attachment

Attach a resource group to a resource. The resource group will be attached to the end of the list of resource groups for the resource.

PatchMyServer:
Type: "Custom::TurbotResourceGroupAttachment"
Properties:
ServiceToken: !Sub 'arn:aws:sns:${AWS::Region}:${AWS::AccountId}:turbot_aws_api_handler'
Turbot: { AccessKey: !Ref TurbotAccessKey, SecretKey: !Ref TurbotSecretKey }
ResourceUrn: !GetAtt MyServer.Arn
ResourceGroupUrn: !GetAtt MyPatchingRG.urn

Shadow

CloudFormation expects to manage the complete configuration and lifecycle of resources. Changes made outside CloudFormation often result in failure of further updates or deletions to the original stack.

In contrast, Turbot Guardrails is designed to detect and automatically correct the configuration of resources. For example, new IAM Roles may have lockdown policies added to them by Turbot Guardrails. Unfortunately, these changes can then cause the original CloudFormation stack to fail when operating on the IAM Role.

Turbot Guardrails Shadow resources provide a simple mechanism to resolve this conflict. When an AWS resource has dependencies managed by Turbot Guardrails, a Shadow should be created as a dependency. During deletion, the Shadow is deleted first which provides Turbot Guardrails with the opportunity to cleanup any dependencies before the AWS resource deletion is attempted.

TestRole:
Type: "AWS::IAM::Role"
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service:
- ec2.amazonaws.com
Action:
- sts:AssumeRole
Path: /
Policies:
- PolicyName: root
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action: "*"
Resource: "*"
RoleName: test_role
TestRoleShadow:
Type: "Custom::TurbotShadow"
Properties:
ServiceToken: !Sub 'arn:aws:sns:${AWS::Region}:${AWS::AccountId}:turbot_aws_api_handler'
Turbot: { AccessKey: !Ref TurbotAccessKey, SecretKey: !Ref TurbotSecretKey }
resourceArn: !GetAtt TestRole.Arn

Directory

dir:
Type: "Custom::TurbotDirectory"
Properties:
ServiceToken: !Sub 'arn:aws:sns:${AWS::Region}:${AWS::AccountId}:turbot_aws_api_handler'
Turbot: { AccessKey: !Ref TurbotAccessKey, SecretKey: !Ref TurbotSecretKey }
ResourceUrn: "urn:turbot:dev:aau"
Id: dir02
Type: turbot
Title: Dir 02
Description: "My test dir #02."
UrnTemplate: "urn:turbot:::profile:turbot:"
LoginNameTemplate: |
- default: ""

Lookup

test:
Type: "Custom::TurbotLookup"
Properties:
ServiceToken: !Sub 'arn:aws:sns:${AWS::Region}:${AWS::AccountId}:turbot_aws_api_handler'
Turbot: { AccessKey: !Ref TurbotAccessKey, SecretKey: !Ref TurbotSecretKey }
ResourceUrn: "arn:aws:iam::123456789012:role/test_role_1"

Contact us to learn more about managing Turbot Guardrails through Custom Resources in CloudFormation, or to understand how Turbot Guardrails can automate networking, operations, security, and compliance for your organization. Schedule a demo to see Turbot Guardrails in action.