# AWS

{% hint style="info" %}
Cortex connects to many third-party vendors whose system interfaces frequently change. As a result, integration behavior or configuration steps may shift without notice. If you encounter unexpected issues, check with your system administrator or refer to the vendor's documentation for the most current information. Additionally, integration sync times vary and are subject to scheduling overrides and timing variance.
{% endhint %}

[Amazon Web Services (AWS)](https://aws.amazon.com/) provides on-demand cloud computing platforms and APIs.

Integrating Cortex with AWS allows you to:

* Track AWS entities in the catalog
* Automatically discover and track ownership of AWS entities and dependencies
  * You can also [enable auto-import](#enable-automatic-discovery-of-aws-entities) of any discovered entities of known types.
* Create [Scorecards](#scorecards-and-cql) that track progress and drive alignment on projects involving your AWS resources

If you are on a self-hosted Cortex instance, see the [self-managed AWS setup](/self-managed/features/integrations/aws.md) page.

## How to configure AWS with Cortex

### Step 1: Configure the integration in Cortex

1. In Cortex, navigate to the [AWS settings page](https://app.getcortexapp.com/admin/integrations/aws).
   * Click **Integrations** from the main nav. Search for and select **AWS**.
2. Click **Add configuration**.
3. In the modal, the JSON configuration, Cortex AWS account ID, and External ID are displayed. In the configuration side bar instructions, you will also see the option to copy a starting "Read Only Access" JSON policy. Keep this browser window open, as you will need these in the next steps.

### Step 2: Set up an IAM policy in AWS

{% hint style="info" %}
When using Cloud Control, the role Cortex assumes to get access into your account needs to have read access to all the selected types. This access is included by default in the Read Only Access policy in Cortex, or it can be configured manually for each type.
{% endhint %}

For each account:

1. Log in to your AWS Management Console and open the [IAM console](https://console.aws.amazon.com/iam/).
2. Click **Policies**, then choose **Create policy**.
3. Switch to the JSON editor. In Cortex while configuring AWS, copy the JSON "Read Only Access" starting policy that appears in the in-app instructions. Paste it into the JSON editor.
   * This policy allows Cortex to list all resources, resource types, and resource tags.
   * If you choose to configure this manually, rather than using the starting policy provided, insert a valid IAM policy depending on the resource types you'd like to import. For example, if you want to import resources of type `AWS::IAM::role`, we'll need to have permission to `iam:ListRoles`, `iam:ListAttachedRolePolicies`, `iam:GetRole`, `iam:ListAccountAliases` and `iam:ListRolePolicies`.
     * For manual configurations, make sure to add the `cloudformation:ListTypes`, `cloudformation:ListResources`, and `cloudformation:GetResource` permissions so that we can pull the list of types available from AWS.
4. Click **Review Policy**, enter a name, then click **Create Policy**.

See the AWS documentation for more information: [Create IAM policies](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_create-console.html).

### Step 3: Create a role in AWS

This section is specific to cloud-based Cortex accounts. If you are on a self-hosted Cortex instance, please see the AWS account setup guide for self-hosted Cortex.

1. In AWS, navigate to **Roles > Create Role**.
2. For the trusted entity type, select **Another AWS account**.
3. In the **Account ID** field, enter the Cortex AWS account ID that was displayed in Cortex in the earlier steps.
4. Click **Require External ID**, then enter the Cortex external ID that was displayed in Cortex in the earlier steps.
5. Click **Next**.
6. Select your newly created policy, and click **Next**.
7. Enter a name for your role. Optionally, configure tags. When you are finished, click **Create Role**.
8. Search for your new role in the list and copy its name. You will need this in the next steps.
9. In the upper right corner of AWS, click your name. In the dropdown that appears, copy your AWS account ID. You will need these in the next steps.

Note that if you use multiple AWS accounts, they will share a common rotatable `externalId`.

### Step 4: Finish the configuration in Cortex

1. Navigate back to the browser window containing your [Cortex AWS settings page](https://app.getcortexapp.com/admin/settings/aws).
2. Configure the AWS integration form:
   * **Account ID**: Enter the AWS account ID you obtained in the previous steps.
   * **IAM role**: Enter the role name you obtained in the previous steps.
3. Click **Save**.

### Step 5: Select AWS resource types

In your [AWS integration settings page](https://app.getcortexapp.com/admin/settings/aws?activeTab=settings) in Cortex, Cortex will pull all the types you included in the IAM policy into the **Cloud Control types** dropdown.

{% hint style="warning" %}
If any resource types do not appear in the list, ensure that `cloudformation:ListTypes`, `cloudformation:ListResources`, and `cloudformation:GetResource` are added to the IAM policy so Cortex can pull the list of all available types from AWS.
{% endhint %}

To select your cloud control types:

1. In the **Cloud control types** field, select the types you want Cortex to discover.
   * If [automatic import](#enable-automatic-import-of-aws-entities) is enabled, then these types will automatically be imported into Cortex.
     * If you later need to remove any auto-imported cloud control types, see [the FAQ below](#if-i-have-auto-import-enabled-how-can-i-remove-cloud-control-types-that-i-no-longer-want-to-be-impor).
2. Click **Save cloud control types**.

If the type you're looking to import is in the list below, please reach out to <support@cortex.io> to submit a feature request.

The following Cloud Control types are not currently supported:

```
AWS::ApiGateway::DocumentationVersion
AWS::ApiGateway::Step
AWS::CloudFormation::ResourceVersion
AWS::CustomerProfiles::Integration
AWS::CustomerProfiles::ObjectType
AWS::EC2::TransitGatewayMulticastGroupMember
AWS::EC2::TransitGatewayMulticastGroupSource
AWS::ECS::TaskSet
AWS::Glue::Attach::SchemaVersion
AWS::Glue::Attach::SchemaVersionMetadata
AWS::IoTSiteWise::AccessPolicy
AWS::IoTSiteWise::Dashboard
AWS::IoTSiteWise::Project
AWS::Kendra::DataSource
AWS::Kendra::Faq
AWS::MediaConnect::FlowEntitlement
AWS::MediaConnect::FlowOutput
AWS::MediaConnect::FlowSource
AWS::MediaConnect::FlowVpcInterface
AWS::MediaPackage::Asset
AWS::MediaPackage::PackagingConfiguration
AWS::NetworkFirewall::LoggingConfiguration
AWS::QuickSight::Analysis
AWS::QuickSight::Dashboard
AWS::QuickSight::DataSet
AWS::QuickSight::DataSource
AWS::QuickSight::Template
AWS::QuickSight::Theme
AWS::RDS::DBProxyTargetGroup
AWS::S3Outposts::AccessPoint
AWS::S3Outposts::Bucket
AWS::SSO::Assignment
AWS::SSO::InstanceAccessControlAttributeConfiguration
AWS::SSO::PermissionSet
```

To modify the integration configuration, see [Modifying an existing integration configuration](/ingesting-data-into-cortex/integrations.md#modifying-an-existing-integration-configuration).

## How to connect Cortex entities to AWS

{% hint style="info" %}
For AWS, Cortex replaces non-alphanumeric characters in entity names with a space. For example, `resource_1` would become `resource 1`.

For the [Cortex tag](/ingesting-data-into-cortex/entities-overview/entities.md#cortex-tag), Cortex replaces non-alphanumeric characters with `-` and lowercases the letters. If multiple special characters appear together in a tag, Cortex replaces the group of characters with only one `-`. For example, `mY_e%ntity#$_tag` would become `my-e-ntity-tag`.
{% endhint %}

### Enable automatic import of AWS entities

You can configure automatic import from AWS:

1. In Cortex, navigate to the [Entities Settings page](https://app.getcortexapp.com/admin/settings/entities/general).
2. Next to **Auto import from AWS, Azure, and/or Google Cloud**, click the toggle to enable the import.\\

   <figure><img src="/files/p4fNmdV0qFSbUMX1YwGD" alt=""><figcaption></figcaption></figure>

If you do not have automatic import enabled, you can [manually import](#import-entities-from-aws).

### Limit discovery to specific regions

By default, Cortex will search for resources across all AWS regions, but you can limit that to specific regions in the [Cortex AWS settings page](https://app.getcortexapp.com/admin/settings/aws).

### Import entities from AWS

See the [Create services documentation](/ingesting-data-into-cortex/entities-overview/entities/adding-entities/add-services.md#creating-services) for instructions on importing entities.

### Discover dependencies for AWS

Cortex automatically discovers dependencies between your services and resources by scanning for resources with specific AWS tags. By default, a service will have dependencies on any Cortex resource that has a corresponding AWS resource with [AWS tag](https://docs.aws.amazon.com/tag-editor/latest/userguide/tagging.html) key = "service" and tag value = the service's Cortex tag.

#### Customize AWS tag names

In Cortex under the [AWS integration page](https://app.getcortexapp.com/admin/settings/aws?activeTab=settings), you can customize the tag key names. Expand the **Dependencies sync from AWS** section, then select tags from the dropdown menu. Note that an `AND` operator is used when you select multiple tags; the resource will need to have all specified tags in order to be recognized by Cortex.

If you do not specify tag names, Cortex will use "service" as the key name.

#### AWS dependency sync

Cortex syncs AWS tags daily at 8 a.m. UTC. To manually refresh the tags, navigate to the [relationship graph](https://app.getcortexapp.com/admin/graph) in your workspace, click the menu in the upper right corner, then click **Sync dependencies**.

<div align="left"><figure><img src="/files/oRNSrQmLhBxgzXa8Mpii" alt=""><figcaption><p>Sync dependencies in the relationship graph.</p></figcaption></figure></div>

**Use key/value pairs in the entity descriptor for discovery**

You can also use explicit tag key/value pairs in the `x-cortex-dependency` block for AWS dependency discovery. Instead of making a service depend on a resource based on service tags, Cortex will make a service depend on a resource if any of the resource's AWS tags match the explicitly defined key/value pairs in the service's `x-cortex-dependency` block. For example, the service below will have dependencies on any AWS resource with tag (key = `aws:cloudformation:my-key-1`, value = `arn:aws:cloudformation:my-region:my-value-1`) or tag (key = `aws:cloudformation:my-key-2`, value = `arn:aws:cloudformation:my-region:my-value-2`).

```yaml
x-cortex-dependency:
  aws:
    tags:
      - key: my-key-1
        value: my-value-1
      - key: my-key-2
        value: my-value-2
      - key: "aws:cloudformation:my-key-1"
        value: "arn:aws:cloudformation:my-region:my-value-1"
      - key: "aws:cloudformation:my-key-2"
        value: "arn:aws:cloudformation:my-region:my-value-2"
```

For more information on dependencies, see the [Dependencies documentation](/ingesting-data-into-cortex/entities-overview/entities/adding-entities/dependencies.md).

### Discover ownership for AWS

Cortex can automatically discover ownership for your AWS resources. To enable this, make sure that your AWS resources have a tag matching the `x-cortex-tag` of the corresponding Cortex team and enable the “Sync ownership from AWS” toggle in the Settings page. By default, we look for the `owner` tag. You can also customize the tag key name.

Cortex syncs ownership from AWS every day at 6 am UTC.

### Editing the entity descriptor

We recommend [automatically importing your AWS entities](#enable-automatic-import-of-aws-entities) for the fastest and most efficient experience connecting your data. If you need to manually edit entity descriptors, see the information below.

You can associate a Cortex entity with one or more AWS entities. For certain AWS resource types, Cortex will display those AWS entities' metadata on the Cortex entity page.

```yaml
x-cortex-infra:
  aws:
    cloudControl:
    - type: AWS::RDS::DBInstance
      region: us-west-2
      accountId: "123456123456"
      identifier: rds-example
```

**Multiple ECS services on a single entity**

You can associate a Cortex entity with multiple ECS services.

If you are using the Cloud Control resource types, use the format below:

```yaml
x-cortex-infra:
  aws:
    cloudControl:
    - type: AWS::ECS::Service
      region: us-west-2
      accountId: "123456123456"
      identifier: ecs-example
    - type: AWS::ECS::Service
      region: us-west-2
      accountID: "34567345673"
      identifier: ecs-example-2
```

If you are not using Cloud Control types or if you imported your entity prior to Cortex supporting Cloud Control types, you can use the format shown below:

```yaml
x-cortex-infra:
  aws:
    ecs:
      - clusterArn: abcd
        serviceArn: efgh
      - clusterArn: stuv
        serviceArn: wxyz
```

The values for `clusterArn` and `serviceArn` are defined in [ECS](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html).

#### Discovery audit

Cortex will pull recent changes from your AWS environment into the [discovered entities list](/ingesting-data-into-cortex/entities-overview/entities/discovery-audit.md). Here, you can find new entities in AWS that have not been imported into the catalog - these will have the tag **New AWS Resource** - as well as entities in the catalog that no longer exist in AWS - these will have the tag **AWS Resource Not Detected**.

## Using the AWS integration

### Searching AWS entities in Cortex

The following keys are supported when searching for your AWS entities in Cortex under **Catalogs > All Entities**:

* `aws-account-id` - Account ID number
* `aws-account-name` - Account alias
* `aws-region` - AWS region of the resource
* `aws-type` - AWS type of the resource
* `aws-name` - AWS name of the resource
* `aws-identifier` - The primary identifier of a resource
* `aws-secondary-identifier` - The secondary identifier of a resouce

#### Example search queries

* `aws-type:"AWS::EC2" AND aws-region:"us-west"`: Search for entities of category EC2 in the any of us-west regions
* `aws-account-id: "234512324"`: Search for all entities from the account 234512324
* `aws-name:"aws-identifier-of-resource" AND aws-account-name:"test-account"`: Search for entity with identifier aws-identifier-of-resource in the account with alias test-account

<figure><img src="/files/CLuDs2PpIvHDOx2mlqxl" alt=""><figcaption></figcaption></figure>

### Scorecards and CQL

With the AWS integration, you can create Scorecard rules and write CQL queries based on AWS resources.

See more examples in the [CQL Explorer](https://app.getcortexapp.com/admin/cql-explorer) in Cortex.

<details>

<summary>AWS details</summary>

Get the AWS details for an entity

**Definition:** `aws.details(): Object`

**Example**

In a Scorecard, you can create a rule to verify that an entity of type `lamda` has a correct function name:

```
aws.details().resources.filter((resource) => resource.typeName == "AWS::Lambda::Function").length > 0
```

You could also create a rule to verify that an entity is not using deprecated runtimes:

```
aws.details().resources.filter((resource) => resource.typeName == "AWS::Lambda::Function" and resource?.metadata?.get("Runtime")?.matchesIn("(python3\\.6|python2\\.7|dotnetcore2\\.1|ruby2\\.5|nodejs12\\.|nodejs10\\.|nodejs8\\.10|nodejs4\\.3|nodejs6\\.10|dotnetcore1\\.0|dotnetcore2\\.0|nodejs4\\.3-edge|nodejs$)")).length == 0    
```

</details>

### View integration logs <a href="#still-need-help" id="still-need-help"></a>

### Background sync

Cortex conducts the following background syncs for AWS:

* Ownership sync daily at 6 a.m. UTC
* AWS tag sync (dependencies) daily at 8 a.m. UTC
  * You can [sync dependencies manually](/ingesting-data-into-cortex/entities-overview/entities/adding-entities/dependencies.md#sync-dependencies) via the Relationship Graph.
* Integration details daily at 10 a.m. UTC

## Troubleshooting and FAQ <a href="#still-need-help" id="still-need-help"></a>

#### If I have auto-import enabled, how can I remove cloud control types that I no longer want to be imported?

If you want to remove any of the cloud control types after importing them: Disable the [automatic import](#enable-automatic-import-of-aws-entities) setting, remove the cloud control types from your [AWS integration settings](#step-5-select-aws-resource-types), then enable [auto-archival](/configure/settings/entity-settings/auto-archive.md). This will cause the removed cloud control types to be archived during the next sync.

#### Why am I seeing the AWS account ID instead of the AWS account alias?

We've recently added support for pulling in the AWS account alias. The required permission is `iam:ListAccountAliases` (see the AWS documentation [here](https://000001.awsstudygroup.com/1-create-new-aws-account/1.3-aws-account-alias/#create-or-edit-an-account-alias)). Once this permission is added, the we will persist the account alias everywhere instead of the ID.<br>

## Still need help?[​](https://docs.cortex.io/docs/reference/integrations/aws#still-need-help) <a href="#still-need-help" id="still-need-help"></a>

The following options are available to get assistance from the Cortex Customer Engineering team:

* **Email**: <help@cortex.io>, or open a support ticket in the in app Resource Center
* **Slack**: Users with a connected Slack channel will have a workflow added to their account. From here, you can either @CortexTechnicalSupport or add a `:ticket:` reaction to a question in Slack, and the team will respond directly.

Don’t have a Slack channel? Talk with your Customer Success Manager.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.cortex.io/ingesting-data-into-cortex/integrations/aws.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
