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:
- Authorized Principal - Identifies the user or role that can create zero-ETL integrations into the data warehouse.
- 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
- The
redshift.amazonaws.com service principal is required, not rds.amazonaws.com.
- Both
redshift:AuthorizeInboundIntegration and redshift:CreateInboundIntegration actions should be included for the service principal.
- The
aws:SourceArn condition must specify the Aurora cluster ARN to authorize it as an integration source.
- The resource policy must be applied to the Namespace ARN, not the Cluster ARN.
- When using Terraform, add a
depends_on to ensure the resource policy is created before the integration.
- Allow 60 seconds for policy propagation before creating the integration.
- 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