Custom IAM roles for Amazon Redshift🔗
This guide outlines the procedure for configuring an AWS EC2 instance with an IAM role that can assume other roles for accessing Amazon Redshift. This two-role approach enhances security by separating the instance's primary permissions from the specific permissions required for Redshift authentication.
Note
This guide assumes familiarity with AWS EC2 instances, the EC2 console, and AWS IAM roles. It also assumes that you have the necessary permissions to create and manage IAM roles in your AWS account.
Configure the primary EC2 instance IAM role🔗
Begin by configuring the IAM role that will serve as the primary role. This role will be able to assume other roles for Redshift access, as you will configure later.
Note
We recommend that you create a dedicated IAM role to ensure precise control over its permissions, rather than using an existing role with broader permissions.
Create the role🔗
- In your EC2 console, select your running instance.
- Navigate to Actions → Security → Modify IAM role.
- Click Create new IAM role to open the IAM console in a new tab and create a new role for your EC2 instance. Give it a suitable descriptive name.
Configure the Trust Policy🔗
Establish a Trust Policy for the EC2 service. The instance role must trust the EC2 service, allowing the service to assume this role on behalf of the instance.
- In the IAM console, navigate to the newly created role for your EC2 instance.
-
In the Trust relationships tab, edit the Trusted entities policy to include
ec2.amazonaws.comas a trusted service principal:{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "ec2.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
Attach the permissions policy🔗
Create and attach a permissions policy to this instance role. This policy grants three key capabilities:
-
List and Read IAM Roles: Allows the Matillion ETL application on the EC2 instance to list and inspect other IAM roles, which is necessary for Matillion ETL to display them and allow role selection.
{ "Sid": "AllowIamRoleReadAndList", "Effect": "Allow", "Action": [ "iam:GetRole", "iam:ListAttachedRolePolicies", "iam:ListRolePolicies", "iam:GetRolePolicy", "iam:GetPolicy", "iam:GetPolicyVersion" ], "Resource": "*" } -
Assume Specific Roles: Explicitly permits the instance role to assume the designated Redshift access roles. You can create as many roles as you want, which can be consumed by the instance role.
{ "Sid": "AllowAssumingPreferredRoles", "Effect": "Allow", "Action": "sts:AssumeRole", "Resource": [ "arn:aws:iam::<your-aws-account-id>:role/Redshift-Access-Role-1", "arn:aws:iam::<your-aws-account-id>:role/Redshift-Access-Role-2" ] }Replace
<your-aws-account-id>with your actual account ID. ReplaceRedshift-Access-Role-1andRedshift-Access-Role-2with the actual roles you intend to assume. Add as many different roles as needed, each as a separate element of theResourcearray. -
General Redshift Access: Provides Redshift permissions directly to the instance role, to allow connection to Redshift.
{ "Sid": "BroadRedshiftAccess", "Effect": "Allow", "Action": "redshift:*", "Resource": "*" }Warning
This example uses broad permissions,
"Resource": "*", for demonstration purposes. For production use, you should scope down the permissions to only those necessary for your specific use case, following the principle of least privilege.
The combined policy should be structured as follows:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowIamRoleReadAndList",
"Effect": "Allow",
"Action": [
"iam:GetRole",
"iam:ListAttachedRolePolicies",
"iam:ListRolePolicies",
"iam:GetRolePolicy",
"iam:GetPolicy",
"iam:GetPolicyVersion"
],
"Resource": "*"
},
{
"Sid": "BroadRedshiftAccess",
"Effect": "Allow",
"Action": "redshift:*",
"Resource": "*"
},
{
"Sid": "AllowAssumingPreferredRoles",
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": [
"arn:aws:iam::<your-aws-account-id>:role/Redshift-Access-Role-1",
"arn:aws:iam::<your-aws-account-id>:role/Redshift-Access-Role-2"
]
}
]
}
Configure the assumable Redshift IAM roles🔗
Next, configure the custom roles (for example, Redshift-Access-Role-1) that will be assumed by the EC2 instance role to get temporary credentials for Redshift.
Establish the trust policy for the instance role🔗
Each custom Redshift role must have a trust policy that allows the primary EC2 instance role (created above) to assume it.
- Navigate to the custom Redshift access role in the IAM console.
- Click the Trust relationships tab and edit the Trusted entities policy.
-
Set the
Principalto the ARN of the EC2 instance role:{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::<your-aws-account-id>:role/EC2-Redshift-Initiator-Role" }, "Action": "sts:AssumeRole" } ] }Ensure the ARN in the Principal field exactly matches the ARN of the EC2 instance role.
Attach Redshift permissions🔗
Attach a permissions policy to this custom role that grants the specific permissions required to interact with Amazon Redshift:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "GrantRedshiftPermissions",
"Effect": "Allow",
"Action": "redshift:*",
"Resource": "*"
}
]
}
!!! warning
This example uses broad permissions, `"redshift:*"` and `"Resource": "*"`, for demonstration purposes. For production use, you should scope down the permissions to only those necessary for your specific use case, following the principle of least privilege.
Select the role in Matillion ETL🔗
Your EC2 instance is now securely configured to assume a dedicated role for Redshift operations. To select the role in Matillion ETL:
- Open the Create Project dialog.
- Select IAM-based authentication as the Auth Method.
- Select the ARN of the role in the IAM Arn drop-down, or paste in the ARN from the IAM console.
If you have multiple roles configured, you can select any of the roles that are assumable by the instance role. Matillion ETL will use the permissions of the selected role when connecting to Redshift.
Troubleshooting connection issues🔗
- If you already connected once with one custom role and later want to connect with a different role, you need to pass
IAMDisableCache:truein Advanced Connection Settings. This is because once a connection is created it's cached and needs to be cleared before a new connection can be made. - If you change something in the role and you don't see that change instantly reflected in Matillion ETL, this can be due to connection caching. Use
IAMDisableCache:truein Advanced Connection Settings to disable the caching for the connection that you have already created. - If you change something in the policies of the IAM role, you may need to restart the server as some policies are cached.