AWS CloudTrail

AWS CloudTrail is a comprehensive audit log of every action taken in your AWS account. FireHydrant's CloudTrail integration imports these changes to your AWS infrastructure and links them with your environments. This lets you see changes to your system alongside GitHub pull requests, deploy events, PagerDuty alerts, and more.

Setting up the integration

Start by going to your FireHydrant integration page and clicking the card for AWS. You are prompted to create a role in your AWS account allowing FireHydrant access to your resources, but without exchanging credentials.

We provide a Terraform module, a CloudFormation template, and documentation with raw policies to create the role and necessary policies. Specific examples customized to your account are available on the Edit Connection page.

Terraform Module

Our Terraform Module is available on GitHub and can be used as-is or imported into your infrastructure module repository. 

The only part of this example that you need to modify is the firehydrant_external_id parameter, which you can find on the Edit Connection page. More details about the external ID parameter can be found under Authentication Workflow.

module "firehydrant-cloudtrail" {
  source = "github.com/firehydrant/aws-changelog-terraform"
  firehydrant_external_id = "c0ffeec0ffeec0ffee"
}

output "firehydrant-readonly-role-arn" {
  value = "${module.firehydrant-cloudtrail.firehydrant-readonly-role-arn}"
}

Once you create this resource, the ARN for the new role will be returned as output. Update your AWS CloudTrail connection with that ARN to begin importing events.

CloudFormation Template

Our CloudFormation Template is available on Github and can be used through the AWS Console or as part of your existing CloudFormation infrastructure.
Click the Quick Create CloudFormation Stack button on the Connection Edit page. This redirects you to the AWS Console, where you're prompted to accept the new role.

To create this stack from the command line, include the ExternalId parameter when creating the stack (as in the Terraform example above). When you call create-stack, AWS starts creating the resources in the background.

$ aws cloudformation create-stack --stack-name firehydrant-read-only \
  --template-url=https://raw.githubusercontent.com/firehydrant/aws-changelog-cloudformation/master/firehydrant-readonly-role.yaml \
  --capabilities CAPABILITY_IAM \
  --parameters ParameterKey=ExternalId,ParameterValue=c0ffeec0ffeec0ffee

$ watch aws cloudformation describe-stacks \
  --stack-name firehydrant-read-only \
  --query 'Stacks[0].StackStatus' \
  --output=text

# ...misc. output until eventually:
CREATE_COMPLETE

$ aws cloudformation describe-stacks \
  --stack-name firehydrant-read-only \
  --query "Stacks[0].Outputs[0].OutputValue" \
  --output=text

arn:aws:iam::123456789012:role/firehydrant-read-only-6-FireHydrantCloudTrailReadO-C0FFEEC0FFEE

Wait until the status of the newly created stack is CREATE_COMPLETE, then run the last describe-stacks command to get the ARN for your new role. Update your AWS CloudTrail connection with that ARN to begin importing events.

Authentication

Thanks to the powerful IAM capabilities of AWS, you can consume CloudTrail events from your account without exchanging credentials. Three elements are involved in this connection:

  • IAM Role: the actor we'll be assuming in your account
  • Trust Relationship: the document restricting who can assume that role
  • IAM Policy: the specific permissions granted to the new role

Amazon has a document explaining the process of granting another AWS account access to your resources. The following documents are examples of the trust relationship and IAM policy FireHydrant requires to read your CloudTrail events. The documents can be found on the Edit Connection page on your CloudTrail connection.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam:123456789012:role/FireHydrant"
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "StringEquals": {
          "sts:ExternalId": "c0ffeec0ffeec0ffee"
        }
      }
    }
  ]
}

This trust policy says that only the FireHydrant role in account 123456789012 is allowed to assume the new role. The ExternalId parameter provides extra security to guard against the "confused deputy" problem; AWS provides a  summary of it in their documentation. We generate this parameter for each connection; it is not configurable.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "cloudtrail:GetTrailStatus",
        "cloudtrail:DescribeTrails",
        "cloudtrail:LookupEvents",
        "cloudtrail:ListTags",
        "cloudtrail:ListPublicKeys",
        "cloudtrail:GetEventSelectors",
        "sts:GetCallerIdentity"
      ],
      "Resource": "*"
    }
  ]
}

This IAM policy restricts FireHydrant's actions in your account; most are self-explanatory regarding reading CloudTrail resources. The last one on the list, sts:GetCallerIdentityallows our API to confirm the role name that we're using. 

After these resources are created in your account, your events are imported on a regular schedule.

📘

Note:

AWS CloudTrail events are batched and made available through their API approximately ten minutes after the action is taken.