Skip to content

How do I resolve "You don't have access to zero-ETL integrations" error when creating Aurora PostgreSQL to Amazon Redshift Zero ETL integration using Terraform?

1

Short Description

When creating an Aurora PostgreSQL zero-ETL integration with Amazon Redshift using Terraform or AWS CLI, you receive the following error:

InvalidParameterValue: You don't have access to zero-ETL integrations because the Amazon Redshift data warehouse doesn't exist or you don't have the required permissions. Check the resource policy of the data warehouse and make sure your user or role is specified as an authorized principal.

This article explains the root cause and provides the solution to resolve this error.

Problem

You are attempting to create a zero-ETL integration from Aurora PostgreSQL to Amazon Redshift using Terraform (aws_rds_integration resource) or AWS CLI. The Redshift cluster exists and is healthy, and you have already added your IAM role ARN as an authorized principal in the Redshift resource policy. However, the integration creation still fails with the "You don't have access to zero-ETL integrations" error.

Environment

  • Source: Aurora PostgreSQL cluster
  • Target: Amazon Redshift Provisioned cluster
  • Deployment method: Terraform via CI/CD pipeline (e.g., GitHub Actions)
  • Region: Same region for both source and target

What is missing?

When creating a zero-ETL integration using the AWS Console, there is a "Fix it for me" option that automatically configures the required resource policy on the Redshift namespace. However, when using Terraform or AWS CLI, you must manually configure the complete resource policy.

The resource policy requires two types of authorization:

  1. Authorized Principal - Identifies the user or role that can create zero-ETL integrations into the data warehouse.
  2. Authorized Integration Source - Identifies the source database that can update the data warehouse.

Most users only configure the first (Authorized Principal with their IAM role), but miss the second (Authorized Integration Source). The Authorized Integration Source is configured by adding a statement that allows the redshift.amazonaws.com service principal with the following actions:

  • redshift:AuthorizeInboundIntegration - Allows Amazon Redshift to continuously validate that the target data warehouse can receive data replicated from the source ARN.
  • redshift:CreateInboundIntegration - Allows the source principal to create an inbound integration for data to be replicated from the source into the target data warehouse.

The statement must also include an aws:SourceArn condition specifying the Aurora cluster ARN.

Resolution

Add the missing redshift.amazonaws.com service principal statement to your Redshift resource policy.

Please Note: The resource policy must be applied to the Redshift Namespace ARN, not the Cluster ARN.

Namespace ARN format:

arn:aws:redshift:region:account-id:namespace:namespace-uuid

Cluster ARN format (do not use for resource policy):

arn:aws:redshift:region:account-id:cluster:cluster-name

Solution using AWS CLI

First, get your Redshift namespace ARN:

aws redshift describe-clusters \
  --cluster-identifier your-cluster-name \
  --query 'Clusters[0].ClusterNamespaceArn' \
  --region your-region \
  --output text

Then, apply the complete resource policy:

aws redshift put-resource-policy \
  --resource-arn "arn:aws:redshift:your-region:your-account-id:namespace:your-namespace-uuid" \
  --policy '{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowRedshiftServiceToAuthorize",
      "Effect": "Allow",
      "Principal": {
        "Service": "redshift.amazonaws.com"
      },
      "Action": [
        "redshift:AuthorizeInboundIntegration",
        "redshift:CreateInboundIntegration"
      ],
      "Resource": "arn:aws:redshift:your-region:your-account-id:namespace:your-namespace-uuid",
      "Condition": {
        "StringEquals": {
          "aws:SourceArn": "arn:aws:rds:your-region:your-account-id:cluster:your-aurora-cluster-name"
        }
      }
    },
    {
      "Sid": "AllowIAMRolesToCreateIntegration",
      "Effect": "Allow",
      "Principal": {
        "AWS": [
          "arn:aws:iam::your-account-id:role/your-iam-role"
        ]
      },
      "Action": "redshift:CreateInboundIntegration",
      "Resource": "arn:aws:redshift:your-region:your-account-id:namespace:your-namespace-uuid"
    }
  ]
}' \
  --region your-region

Replace the following values:

  • your-region: Your AWS region (e.g., eu-central-1)
  • your-account-id: Your AWS account ID
  • your-namespace-uuid: Your Redshift namespace UUID
  • your-aurora-cluster-name: Your Aurora PostgreSQL cluster identifier
  • your-iam-role: Your IAM role name

Solution using Terraform

Add the following statement to your aws_redshift_resource_policy resource:

data "aws_redshift_cluster" "redshift" {
  cluster_identifier = "your-cluster-name"
}

data "aws_rds_cluster" "aurora" {
  cluster_identifier = "your-aurora-cluster-name"
}

resource "aws_redshift_resource_policy" "zero_etl" {
  resource_arn = data.aws_redshift_cluster.redshift.cluster_namespace_arn

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Sid    = "AllowRedshiftServiceToAuthorize"
        Effect = "Allow"
        Principal = {
          Service = "redshift.amazonaws.com"
        }
        Action = [
          "redshift:AuthorizeInboundIntegration",
          "redshift:CreateInboundIntegration"
        ]
        Resource = data.aws_redshift_cluster.redshift.cluster_namespace_arn
        Condition = {
          StringEquals = {
            "aws:SourceArn" = data.aws_rds_cluster.aurora.arn
          }
        }
      },
      {
        Sid    = "AllowIAMRolesToCreateIntegration"
        Effect = "Allow"
        Principal = {
          AWS = "arn:aws:iam::your-account-id:role/your-iam-role"
        }
        Action   = "redshift:CreateInboundIntegration"
        Resource = data.aws_redshift_cluster.redshift.cluster_namespace_arn
      }
    ]
  })
}

resource "time_sleep" "wait_for_policy" {
  depends_on      = [aws_redshift_resource_policy.zero_etl]
  create_duration = "60s"
}

resource "aws_rds_integration" "aurora_to_redshift" {
  integration_name = "your-integration-name"
  source_arn       = data.aws_rds_cluster.aurora.arn
  target_arn       = data.aws_redshift_cluster.redshift.cluster_namespace_arn

  depends_on = [time_sleep.wait_for_policy]
}

Note: The time_sleep resource is recommended to allow the resource policy to propagate before creating the integration. This requires the hashicorp/time provider.

Key Points

  1. The redshift.amazonaws.com service principal is required, not rds.amazonaws.com.
  2. Both redshift:AuthorizeInboundIntegration and redshift:CreateInboundIntegration actions should be included for the service principal.
  3. The aws:SourceArn condition must specify the Aurora cluster ARN to authorize it as an integration source.
  4. The resource policy must be applied to the Namespace ARN, not the Cluster ARN.
  5. When using Terraform, add a depends_on to ensure the resource policy is created before the integration.
  6. Allow 60 seconds for policy propagation before creating the integration.
  7. The AWS Console "Fix it for me" option automatically configures these settings, but Terraform and CLI require manual configuration.

Verify the Resource Policy

After applying the policy, verify it was configured correctly:

aws redshift get-resource-policy \
  --resource-arn "arn:aws:redshift:your-region:your-account-id:namespace:your-namespace-uuid" \
  --region your-region

The output should include both statements: one for the redshift.amazonaws.com service principal with the aws:SourceArn condition, and one for your IAM role.

Related Information

AWS

asked 8 months ago318 views

1 Answer
0

To resolve the "You don't have access to zero-ETL integrations" error when creating a Zero-ETL integration between Aurora PostgreSQL and Amazon Redshift using Terraform, you need to properly configure the Redshift resource policy with two key authorization components:

  1. Authorized Principals: The IAM roles/users allowed to create integrations
  2. Authorized Integration Sources: The source database (Aurora PostgreSQL) that can update the data warehouse

The most common cause of this error is missing the second part - the authorized integration source configuration.

Here's how to fix it using Terraform:

data "aws_redshift_cluster" "redshift" {
cluster_identifier = "your-cluster-name"
}

data "aws_rds_cluster" "aurora" {
cluster_identifier = "your-aurora-cluster-name"
}

resource "aws_redshift_resource_policy" "zero_etl" {
resource_arn = data.aws_redshift_cluster.redshift.cluster_namespace_arn

policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Sid    = "AllowRedshiftServiceToAuthorize"
Effect = "Allow"
Principal = {
Service = "redshift.amazonaws.com"
}
Action   = "redshift:CreateInboundIntegration"
Resource = data.aws_redshift_cluster.redshift.cluster_namespace_arn
Condition = {
StringEquals = {
"aws:SourceArn" = data.aws_rds_cluster.aurora.arn
}
}
},
{
Sid    = "AllowIAMRolesToCreateIntegration"
Effect = "Allow"
Principal = {
AWS = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/your-iam-role"
}
Action   = "redshift:CreateInboundIntegration"
Resource = data.aws_redshift_cluster.redshift.cluster_namespace_arn
}
]
})
}

# Add a delay to allow policy propagation
resource "time_sleep" "wait_for_policy" {
depends_on      = [aws_redshift_resource_policy.zero_etl]
create_duration = "60s"
}

resource "aws_rds_integration" "aurora_to_redshift" {
integration_name = "your-integration-name"
source_arn       = data.aws_rds_cluster.aurora.arn
target_arn       = data.aws_redshift_cluster.redshift.cluster_namespace_arn

depends_on = [time_sleep.wait_for_policy]
}

Important considerations:

  1. Make sure you're using the Redshift namespace ARN (not the cluster ARN) for the resource policy. The namespace ARN format is: arn:aws:redshift:region:account-id:namespace:namespace-uuid

  2. Include the redshift.amazonaws.com service principal with the aws:SourceArn condition pointing to your Aurora cluster ARN.

  3. Add a time_sleep resource with a depends_on to ensure the resource policy is fully propagated before creating the integration.

  4. Ensure your Aurora PostgreSQL cluster has the required parameters set:

  • rds.logical_replication=1
  • aurora.enhanced_logical_replication=1
  • aurora.logical_replication_backup=0
  • aurora.logical_replication_globaldb=0
  1. If you're using Lake Formation with your Redshift integration, ensure you've granted the necessary permissions to the Redshift service-linked role.

After applying these changes, your Zero-ETL integration should be created successfully.
Sources
Cross-account DynamoDB to Redshift Serverless Zero-ETL integration fails with “You don’t have access” error | AWS re:Post
Simplify data integration using zero-ETL from self-managed databases to Amazon Redshift | AWS Database Blog
Amazon Aurora MySQL zero-ETL integration with Amazon SageMaker Lakehouse | AWS Database Blog
Amazon Aurora PostgreSQL and Amazon DynamoDB zero-ETL integrations with Amazon Redshift now generally available | AWS News Blog

answered 8 months ago

EXPERT

reviewed 8 months ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.