User GuidesAPI ReferenceRelease Notes
Doc HomeHelp CenterLog In

Terraform IAM Principal Permissions for AWS

Guidelines for creating policies for the Terraform IAM principal user

Tamr maintains a collection of Terraform modules to provision and manage all resources required for an AWS cloud-native deployment. When using these Terraform modules, you must ensure that the IAM user or role with which Terraform commands are executed has the appropriate permissions. In this topic, this user or role is referred to as the Terraform IAM principal.

This topic provides a set of guidelines for creating policies for your Terraform IAM principal. These guidelines follow the principle of least privilege to ensure the Terraform IAM principal is granted only the minimum permissions required for managing Tamr Core infrastructure within your environment.

Note: The name of the Amazon Elasticsearch Service has changed to "Amazon OpenSearch Service". See Amazon's blog post for more information about this change.

Requirements for Configuring Terraform IAM Principal Permissions

Users configuring permissions for the Terraform IAM principal must understand IAM policies and permissions, and understand how IAM works.

Minimum Allowed Actions

The IAM policy below contains the minimal set of actions that your Terraform IAM principal must be allowed to perform in order to create, update, and destroy a Tamr Core AWS cloud-native deployment.

important Important: This policy is intended for reference purposes only.

This policy uses a wildcard (*) as the value for the Resource element, which means any IAM principal to which this policy is attached can potentially apply the listed actions on any resources that support them, not just Tamr Core resources. See the follow sections for different approaches to writing policies that restrict the resources on which the actions listed in the policy below can be performed:

{
    "Version": "2012-10-17",
    "Statement": [{
   	 "Effect": "Allow",
   	 "Action": [
   		 "ec2:AuthorizeSecurityGroupEgress",
   		 "ec2:AuthorizeSecurityGroupIngress",
   		 "ec2:CreateSecurityGroup",
   		 "ec2:CreateTags",
   		 "ec2:CreateNetworkInterface",
   		 "ec2:DeleteKeyPair",
   		 "ec2:DeleteNetworkInterface",
   		 "ec2:DeleteSecurityGroup",
   		 "ec2:DescribeAccountAttributes",
   		 "ec2:DescribeAddresses",
   		 "ec2:DescribeImages",
   		 "ec2:DescribeInstanceAttribute",
   		 "ec2:DescribeInstanceCreditSpecifications",
   		 "ec2:DescribeInstances",
   		 "ec2:DescribeKeyPairs",
   		 "ec2:DescribeNetworkInterfaces",
   		 "ec2:DescribeSecurityGroups",
   		 "ec2:DescribeTags",
   		 "ec2:DescribeVolumes",
   		 "ec2:DescribeVpcAttribute",
   		 "ec2:DescribeVpcs",
   		 "ec2:DetachNetworkInterface",
   		 "ec2:ModifyInstanceAttribute",
   		 "ec2:ModifyVolume",
   		 "ec2:RevokeSecurityGroupEgress",
   		 "ec2:RevokeSecurityGroupIngress",
   		 "ec2:RunInstances",
   		 "ec2:StartInstances",
   		 "ec2:StopInstances",
   		 "ec2:TerminateInstances",
   		 "elasticmapreduce:DescribeCluster",
   		 "elasticmapreduce:ListBootstrapActions",
   		 "elasticmapreduce:ListInstanceFleets",
   		 "elasticmapreduce:ListInstanceGroups",
   		 "elasticmapreduce:ListInstances",
   		 "elasticmapreduce:ListSteps",
   		 "elasticmapreduce:ModifyInstanceGroups",
   		 "elasticmapreduce:RunJobFlow",
   		 "elasticmapreduce:TerminateJobFlows",
   		 "es:AddTags",
   		 "es:CreateElasticsearchDomain",
   		 "es:DeleteElasticsearchDomain",
   		 "es:DescribeElasticsearchDomain",
   		 "es:GetUpgradeStatus",
   		 "es:ListTags",
   		 "es:RemoveTags",
   		 "es:UpdateElasticsearchDomainConfig",
   		 "es:UpgradeElasticsearchDomain",
   		 "iam:AddRoleToInstanceProfile",
   		 "iam:AttachRolePolicy",
   		 "iam:CreateInstanceProfile",
   		 "iam:CreatePolicy",
   		 "iam:CreatePolicyVersion",
   		 "iam:CreateRole",
   		 "iam:DeleteInstanceProfile",
   		 "iam:DeletePolicy",
   		 "iam:DeletePolicyVersion",
   		 "iam:DeleteRole",
   		 "iam:DetachRolePolicy",
   		 "iam:GetInstanceProfile",
   		 "iam:GetPolicy",
   		 "iam:GetPolicyVersion",
   		 "iam:GetRole",
   		 "iam:ListAttachedRolePolicies",
   		 "iam:ListInstanceProfilesForRole",
   		 "iam:ListInstanceProfileTags",
   		 "iam:ListPolicyVersions",
   		 "iam:ListRolePolicies",
   		 "iam:PassRole",
   		 "iam:PutRolePermissionsBoundary",
   		 "iam:RemoveRoleFromInstanceProfile",
   		 "iam:TagInstanceProfile",
   		 "iam:TagPolicy",
   		 "iam:TagRole",
   		 "iam:UntagInstanceProfile",
   		 "iam:UntagPolicy",
   		 "iam:UntagRole",
   		 "rds:AddTagsToResource",
   		 "rds:CreateDBInstance",
   		 "rds:CreateDBParameterGroup",
   		 "rds:CreateDBSubnetGroup",
   		 "rds:DeleteDBSubnetGroup",
   		 "rds:DeleteDBInstance",
   		 "rds:DeleteDBParameterGroup",
   		 "rds:DescribeDBInstances",
   		 "rds:DescribeDBParameterGroups",
   		 "rds:DescribeDBParameters",
   		 "rds:DescribeDBSubnetGroups",
   		 "rds:ModifyDBParameterGroup",
   		 "rds:ModifyDBSubnetGroup",
   		 "rds:ListTagsForResource",
   		 "rds:RemoveTagsFromResource",
   		 "s3:CreateBucket",
   		 "s3:DeleteBucket",
   		 "s3:DeleteBucketPolicy",
   		 "s3:DeleteObject",
   		 "s3:DeleteObjectVersion",
   		 "s3:GetAccelerateConfiguration",
   		 "s3:GetBucketAcl",
   		 "s3:GetBucketCORS",
   		 "s3:GetBucketLogging",
   		 "s3:GetBucketObjectLockConfiguration",
   		 "s3:GetBucketOwnershipControls",
   		 "s3:GetBucketRequestPayment",
   		 "s3:GetBucketTagging",
   		 "s3:GetBucketVersioning",
   		 "s3:GetBucketWebsite",
   		 "s3:GetEncryptionConfiguration",
   		 "s3:GetLifecycleConfiguration",
   		 "s3:GetMetricsConfiguration",
   		 "s3:GetObject",
   		 "s3:GetObjectTagging",
   		 "s3:GetObjectVersion",
   		 "s3:GetReplicationConfiguration",
   		 "s3:ListBucket",
   		 "s3:ListBucketVersions",
   		 "s3:PutBucketPolicy",
   		 "s3:PutBucketTagging",
   		 "s3:PutEncryptionConfiguration",
   		 "s3:PutObject",
   		 "s3:PutObjectTagging"
   	 ],
   	 "Resource": "*"
    }]
}

Required Actions for Managing Network Resources

If you are using the Tamr AWS Networking Module to provision the necessary VPC resources for a Tamr Core cloud-native deployment, you need to grant the Terraform principal permissions to perform the actions shown in the example policy below.

{
    "Version": "2012-10-17",
    "Statement": [{
        "Effect": "Allow",
        "Resource": "*",
        "Action": [
            "ec2:AllocateAddress",
            "ec2:AssociateAddress",
            "ec2:AssociateRouteTable",
            "ec2:AttachInternetGateway",
            "ec2:CreateInternetGateway",
            "ec2:CreateNatGateway",
            "ec2:CreateNetworkAcl",
            "ec2:CreateNetworkAclEntry",
            "ec2:CreateRoute",
            "ec2:CreateRouteTable",
            "ec2:CreateSubnet",
            "ec2:CreateTags",
            "ec2:CreateVpc",
            "ec2:CreateVpcEndpoint",
            "ec2:DeleteInternetGateway",
            "ec2:DeleteNatGateway",
            "ec2:DeleteNetworkAcl",
            "ec2:DeleteNetworkAclEntry",
            "ec2:DeleteRoute",
            "ec2:DeleteRouteTable",
            "ec2:DeleteSubnet",
            "ec2:DeleteTags",
            "ec2:DeleteVpc",
            "ec2:DeleteVpcEndpoints",
            "ec2:DescribeAddresses",
            "ec2:DescribeInternetGateways",
            "ec2:DescribeNatGateways",
            "ec2:DescribeNetworkAcls",
            "ec2:DescribeNetworkInterfaces",
            "ec2:DescribePrefixLists",
            "ec2:DescribeRouteTables",
            "ec2:DescribeSubnets",
            "ec2:DescribeSubnets",
            "ec2:DescribeVpcAttribute",
            "ec2:DescribeVpcClassicLink",
            "ec2:DescribeVpcClassicLinkDnsSupport",
            "ec2:DescribeVpcEndpointServices",
            "ec2:DescribeVpcEndpoints",
            "ec2:DescribeVpcs",
            "ec2:DetachInternetGateway",
            "ec2:DisassociateAddress",
            "ec2:DisassociateRouteTable",
            "ec2:ModifySubnetAttribute",
            "ec2:ModifyVpcAttribute",
            "ec2:ReleaseAddress",
            "ec2:ReplaceNetworkAclAssociation",
            "ec2:ReplaceRouteTableAssociation",
            "route53:AssociateVPCWithHostedZone"
        ]
    }]
}

Additionally, if you are using the Tamr AWS ALB Submodule to provision an Application Load Balancer (ALB) and its associated resources, you need to allow the actions included in the following example policy:

{
    "Version": "2012-10-17",
    "Statement": [{
        "Effect": "Allow",
        "Action": [
            "ec2:AuthorizeSecurityGroupEgress",
            "ec2:AuthorizeSecurityGroupIngress",
            "ec2:CreateSecurityGroup",
            "ec2:CreateTags",
            "ec2:DeleteSecurityGroup",
            "ec2:DeleteTags",
            "ec2:DescribeAccountAttributes",
            "ec2:DescribeInstanceAttribute",
            "ec2:DescribeInstances",
            "ec2:DescribeNetworkInterfaces",
            "ec2:DescribeSecurityGroupRules",
            "ec2:DescribeSecurityGroups",
            "ec2:DescribeVolumes",
            "ec2:ModifySecurityGroupRules",
            "ec2:RevokeSecurityGroupEgress",
            "ec2:RevokeSecurityGroupIngress",
            "ec2:UpdateSecurityGroupRuleDescriptionsEgress",
            "ec2:UpdateSecurityGroupRuleDescriptionsIngress",
            "elasticloadbalancing:AddListenerCertificates",
            "elasticloadbalancing:AddTags",
            "elasticloadbalancing:CreateListener",
            "elasticloadbalancing:CreateLoadBalancer",
            "elasticloadbalancing:CreateRule",
            "elasticloadbalancing:CreateTargetGroup",
            "elasticloadbalancing:DeleteListener",
            "elasticloadbalancing:DeleteListener",
            "elasticloadbalancing:DeleteLoadBalancer",
            "elasticloadbalancing:DeleteRule",
            "elasticloadbalancing:DeleteTargetGroup",
            "elasticloadbalancing:DeregisterTargets",
            "elasticloadbalancing:DescribeListenerCertificates",
            "elasticloadbalancing:DescribeListeners",
            "elasticloadbalancing:DescribeLoadBalancerAttributes",
            "elasticloadbalancing:DescribeLoadBalancers",
            "elasticloadbalancing:DescribeRules",
            "elasticloadbalancing:DescribeTags",
            "elasticloadbalancing:DescribeTargetGroupAttributes",
            "elasticloadbalancing:DescribeTargetGroups",
            "elasticloadbalancing:DescribeTargetHealth",
            "elasticloadbalancing:ModifyListener",
            "elasticloadbalancing:ModifyLoadBalancerAttributes",
            "elasticloadbalancing:ModifyTargetGroup",
            "elasticloadbalancing:ModifyTargetGroupAttributes",
            "elasticloadbalancing:RegisterTargets",
            "elasticloadbalancing:RemoveListenerCertificates",
            "elasticloadbalancing:RemoveTags",
            "elasticloadbalancing:SetIpAddressType",
            "elasticloadbalancing:SetSecurityGroups",
            "elasticloadbalancing:SetSubnets"
        ],
        "Resource": "*"
    }]
}

Complementary Actions

When provisioning infrastructure for some of the examples in Tamr's Terraform AWS module repositories, as well as in real-life scenarios where you need to deploy Tamr Core within a larger AWS environment whose resources are also managed with Terraform, you may need to grant the Terraform IAM principal additional permissions that are not strictly required by the Tamr modules themselves. This section provides example policies for granting additional permissions.

Allowing EC2 Key Pair Management

You might need your Terraform IAM principal to be able to manage EC2 key pairs, as show in the following example policy.

{
	"Version": "2012-10-17",
	"Statement":[{
	   "Effect":"Allow",
	   "Action": [
             "ec2:CreateKeyPair",
             "ec2:DeleteKeyPair",
             "ec2:DescribeKeyPairs"
         ]
	   "Resource":"*"
	}]
}

Service-Linked Roles

Some AWS services in the Tamr Core deployment make use of service-linked roles, which are special type of predefined IAM roles that grant all the permissions a service requires to call other AWS services to perform certain tasks on your behalf.

Service-linked roles are usually set up automatically by the service the first time specific resources (for example, an RDS database instance) are created in an AWS account, or they might be created manually. (See AWS using service-linked roles documentation).

important Important: When provisioning Tamr Core infrastructure using the Terraform modules, you must ensure that the service-linked roles for Elastic Map Reduce (EMR), Relational Database Service (RDS) and OpenSearch Service already exist in your account. Alternatively, you can grant the Terraform IAM principal the necessary permissions to create them, as shown in the following policy.

{
    "Version": "2012-10-17",
    "Statement": [{
   		 "Sid": "AllowCreateEMRCleanupServiceLinkedRole",
   		 "Effect": "Allow",
   		 "Action": [
   			 "iam:CreateServiceLinkedRole",
   			 "iam:PutRolePolicy"
   		 ],
   		 "Resource": "arn:aws:iam::*:role/aws-service-role/elasticmapreduce.amazonaws.com*/AWSServiceRoleForEMRCleanup*",
   		 "Condition": {
   			 "StringLike": {
   				 "iam:AWSServiceName": [
   					 "elasticmapreduce.amazonaws.com",
   					 "elasticmapreduce.amazonaws.com.cn"
   				 ]
   			 }
   		 }
   	 },
   	 {
   		 "Sid": "AllowCreateRDSServiceLinkedRole",
   		 "Action": "iam:CreateServiceLinkedRole",
   		 "Effect": "Allow",
   		 "Resource": "arn:aws:iam::*:role/aws-service-role/rds.amazonaws.com/AWSServiceRoleForRDS",
   		 "Condition": {
   			 "StringLike": {
   				 "iam:AWSServiceName": "rds.amazonaws.com"
   			 }
   		 }
   	 },
   	 {
   		 "Sid": "AllowManageESServiceLinkedRole",
   		 "Action": [
   			 "es:CreateElasticsearchServiceRole",
   			 "iam:CreateServiceLinkedRole",
   			 "iam:DeleteServiceLinkedRole",
   			 "iam:GetServiceLinkedRoleDeletionStatus"
   		 ],
   		 "Effect": "Allow",
   		 "Resource": "arn:aws:iam::*:role/aws-service-role/es.amazonaws.com/AWSServiceRoleForAmazonElasticsearchService",
   		 "Condition": {
   			 "StringLike": {
   				 "iam:AWSServiceName": "es.amazonaws.com"
   			 }
   		 }
   	 }
    ]
}

Terraform implicitly triggers the creation of EMR and RDS service-linked roles if they do not exist. However, for the OpenSearch Service, Terraform must explicitly manage the role as a resource; the policy therefore includes allowed actions in the AllowManageESServiceLinkedRole statement.

Here is an example of explicitly creating the OpenSearch service linked role with Terraform. For more information, see the module's documentation.

resource "aws_iam_service_linked_role" "es" {
  aws_service_name = "es.amazonaws.com"
}

Implementing Tag-Based Access Control

You can use conditions based on tags in your IAM policy to further restrict which AWS resources the Terraform IAM principal can manage.

You can use tag condition keys in any of the following ways:

  1. Use the ResourceTag/<*key-name*> condition key to control access to AWS service resources based on the tags applied to those resources.
  2. Use the aws:RequestTag/<*key-name*> condition key to specify what tag key-value pairs can be passed in a request to tag or untag a resource.
  3. Use the aws:TagKeys condition key to control what specific tag keys can be used in a request, enforcing case sensitivity.

When implementing authorization based on tags for the Terraform IAM principal, you must ensure that your Terraform code defines the appropriate tags and passes them to the Tamr modules as well as any other resources it declares.

Note: Not all AWS services support access control using tags. To learn which AWS services support controlling access using tags, see the AWS documentation on services that work with IAM.

The following example policies show how to use tag-based authorization for managing EC2 instances.

important Important: These example policies alone do not grant the Terraform principal enough permissions to provision and manage all the required EC2 resources in the Tamr deployment. For a full list of EC2 actions that need to be allowed on the Terraform principal, see the section on minimum allowed actions. When creating fine-grained policies for EC2 resources, Tamr recommends that you have a thorough understanding of the IAM actions, resources and condition keys defined by EC2.

Example: Restricting Permissions on IAM Resources Based on Tags

The following policy shows how you can allow the Terraform IAM principal to create IAM policies, roles and instance profiles on the condition that they are tagged "Author": "Tamr". The policy also shows how you might grant the principal permission on various actions to retrieve, modify, and delete only on those IAM resources that have been tagged with the "Author": "Tamr" tag key and value.

{
    "Version": "2012-10-17",
    "Statement": [{
   		 "Sid": "AllowIAMCreate",
   		 "Effect": "Allow",
   		 "Action": [
   			 "iam:CreateInstanceProfile",
   			 "iam:CreatePolicy",
   			 "iam:CreateRole"
   		 ],
   		 "Resource": "*",
   		 "Condition": {
   			 "StringEquals": {
   				 "aws:RequestTag/Author": "Tamr"
   			 }
   		 }
   	 },
   	 {
   		 "Sid": "AllowIAMGetUpdateDelete",
   		 "Effect": "Allow",
   		 "Action": [
   			 "iam:AddRoleToInstanceProfile",
   			 "iam:AttachRolePolicy",
   			 "iam:CreatePolicyVersion",
   			 "iam:DeleteInstanceProfile",
   			 "iam:DeletePolicy",
   			 "iam:DeletePolicyVersion",
   			 "iam:DeleteRole",
   			 "iam:DetachRolePolicy",
   			 "iam:GetInstanceProfile",
   			 "iam:GetPolicy",
   			 "iam:GetPolicyVersion",
   			 "iam:GetRole",
   			 "iam:ListAttachedRolePolicies",
   			 "iam:ListInstanceProfilesForRole",
   			 "iam:ListInstanceProfileTags",
   			 "iam:ListPolicyVersions",
   			 "iam:ListRolePolicies",
   			 "iam:PutRolePermissionsBoundary",
   			 "iam:RemoveRoleFromInstanceProfile",
   			 "iam:TagInstanceProfile",
   			 "iam:TagPolicy",
   			 "iam:TagRole",
   			 "iam:UntagInstanceProfile",
   			 "iam:UntagPolicy",
   			 "iam:UntagRole"
   		 ],
   		 "Resource": "*",
   		 "Condition": {
   			 "StringEquals": {
   				 "aws:ResourceTag/Author": "Tamr"
   			 }
   		 }
   	 }
    ]
}

Example: Restricting Permissions on EC2 Resources Based on Tags

The policy below allows instances to be launched in the specified AWS account and region on the condition that they are tagged "Author": "Tamr".

{
    "Version": "2012-10-17",
    "Statement": [{
   		 "Sid": "AllowEC2RunInstances",
   		 "Effect": "Allow",
   		 "Action": "ec2:RunInstances",
   		 "Resource": "arn:aws:ec2:<region>:<account-id>:instance/*",
   		 "Condition": {
   			 "StringEquals": {
   				 "aws:RequestTag/Author": "Tamr"
   			 }
   		 }
   	 },
   	 {
   		 "Sid": "AllowEC2RunInstancesMiscResources",
   		 "Effect": "Allow",
   		 "Action": "ec2:RunInstances",
   		 "Resource": [
   			 "arn:aws:ec2:<region>::image/*"
   			 "arn:aws:ec2:<region>:<account-id>:key-pair/*"
   			 "arn:aws:ec2:<region>:<account-id>:network-interface/*"
   			 "arn:aws:ec2:<region>:<account-id>:subnet/*"
   			 "arn:aws:ec2:<region>:<account-id>:security-group/*"
   			 "arn:aws:ec2:<region>:<account-id>:volume/*"
   		 ]
   	 }
    ]
}

To complement the policy above, the following policy allows the creation of tags for EC2 resources when launching an instance, and allows the modification the tags if the resources are already tagged Author: Tamr (and remain that way).

{
    "Version": "2012-10-17",
    "Statement": [{
   		 "Sid": "AllowEC2CreateTags",
   		 "Effect": "Allow",
   		 "Action": "ec2:CreateTags",
   		 "Resource": "arn:aws:ec2:<region>:<account-id>:instance/*",
   		 "Condition": {
   			 "StringEquals": {
   				 "ec2:CreateAction": "RunInstances"
   			 }
   		 }
   	 },
   	 {
   		 "Sid": "AllowEC2CreateTagsExisting",
   		 "Effect": "Allow",
   		 "Action": "ec2:CreateTags",
   		 "Resource": "arn:aws:ec2:<region>:<account-id>:instance/*",
   		 "Condition": {
   		       "StringEquals": {
   		           "ec2:ResourceTag/Author": "Tamr"
   		       },
                    "ForAnyValues:StringEquals": {
                       "aws:TagKeys": ["Author"]
                    }
   		 }
   	 }
    ]
}

Finally, the policy below grants permissions to manage instances that are tagged Author: Tamr.

{
    "Version": "2012-10-17",
    "Statement": [{
   	 {
   		 "Sid": "AllowManageTaggedInstances",
   		 "Effect": "Allow",
   		 "Action": [
                 "ec2:ModifyInstanceAttribute",
                 "ec2:StartInstances",
                 "ec2:StopInstances",
                 "ec2:TerminateInstances"
             ]
   		 "Resource": "arn:aws:ec2:<region>:<account-id>:instance/*",
   		 "Condition": {
   			 "StringEquals": {
   		           "ec2:ResourceTag/Author": "Tamr"
   			 }
   		 }
   	 }
    ]
}

Implementing Resource-Level Permissions

You can pass individual ARNs in the Resource element of an IAM policy statement to specify the resources on which the actions defined in the statement are allowed. When creating policies for the Terraform IAM principal, you can use resource-level permissions to ensure that the Terraform IAM principal is only allowed to manage the resources that are part of the Tamr Core deployment.

Limitations of Resource-Level Permissions

Before implementing resource-level permissions, it is important to understand their limitations. Resource-level permissions create tight coupling between the policies and the Terraform code; you must be able to predict what the ARNs of the resources created by Terraform will be. In their current format, ARNs have a resource portion, which for most resources is a friendly name that you define and control. For some resources, however, the resource portion is an identifier dynamically generated and assigned by AWS on creation. Implementing strict resource-level permissions for the latter requires that you update the Terraform IAM Principal policies after the resources have been provisioned.

Additionally, not all AWS services and actions support resource-level permissions. To understand which AWS services support this feature, see the AWS services that work with IAM documentation.

Due to these limitations, Tamr recommends using resource-level permissions only to restrict operations for which tag-based authorization is not supported. This section describes two situations in which resource-level permissions are advised.

Example: Restricting Roles that Can be Passed to AWS Services

To configure some of the AWS services involved in the Tamr Core deployment, the Terraform IAM principal must be able to pass an IAM role to the services via the iam:PassRole action.

Tamr highly recommends that you specify only allowed ARNs in the Resource element of the statement containing the iam:PassRole action. Additionally, always restrict the services to which the Tamr IAM Principal can pass roles by using the iam:PassedToService condition key.

important Important: Do not allow iam:PassRole using a wildcard (*) in the Resource element, as this allows the Terraform IAM Principal to pass any existing role in the AWS account, potentially granting access to more services or features than required by the Tamr deployment. You cannot limit permissions to pass a role based on tags attached to the role using the ResourceTag/<key-name> condition key.

The example policy shown below allows the Terraform IAM principal to pass only the tamr_emr_service_role role to the Elastic Map Reduce (EMR) service, and assumes that the IAM role for EMR will be created by Terraform with the name tamr_emr_service_role in the given AWS account. When using the Tamr EMR Terraform Module, the name of the role is determined by the value of the variable emr_service_role_name.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "iam:PassRole",
            "Resource": "arn:aws:iam::<account-id>:role/tamr_emr_service_role",
            "Condition": {
              "StringEquals": {
                "iam:PassedToService": "elasticmapreduce.amazonaws.com"
              }
            }
        }
    ]
}

Example: Restricting S3 Bucket Operations

Amazon S3 does not support conditional permissions based on tags for bucket operations. You can create a policy that leverages resource-level permissions to grant the Terraform IAM principal the required permissions only on the data and logs buckets that are part of the Tamr deployment, as show in the example below. The example policy assumes that the S3 buckets will be created by Terraform with the names myorg-tamr-data and myorg-tamr-logs, respectively. When using the Tamr AWS S3 Terraform Module, the name of the bucket is determined by the value of the variable bucket_name.

{
    "Version": "2012-10-17",
    "Statement": [{
   	 "Effect": "Allow",
   	 "Action": [
           "s3:CreateBucket",
           "s3:DeleteBucket",
           "s3:DeleteBucketPolicy",
           "s3:DeleteObject",
           "s3:DeleteObjectVersion",
           "s3:GetAccelerateConfiguration",
           "s3:GetBucketAcl",
           "s3:GetBucketCORS",
           "s3:GetBucketLogging",
           "s3:GetBucketObjectLockConfiguration",
           "s3:GetBucketOwnershipControls",
           "s3:GetBucketRequestPayment",
           "s3:GetBucketTagging",
           "s3:GetBucketVersioning",
           "s3:GetBucketWebsite",
           "s3:GetEncryptionConfiguration",
           "s3:GetLifecycleConfiguration",
           "s3:GetMetricsConfiguration",
           "s3:GetObject",
           "s3:GetObjectTagging",
           "s3:GetObjectVersion",
           "s3:GetReplicationConfiguration",
           "s3:ListBucket",
           "s3:ListBucketVersions",
           "s3:PutBucketPolicy",
           "s3:PutBucketTagging",
           "s3:PutEncryptionConfiguration",
           "s3:PutObject",
           "s3:PutObjectTagging"
   	 ],
   	 "Resource": [
           "arn:aws:s3:::myorg-tamr-data",
           "arn:aws:s3:::myorg-tamr-data/*",
           "arn:aws:s3:::myorg-tamr-logs",
           "arn:aws:s3:::myorg-tamr-logs/*"
       ]
    }]
}

Using Permissions Boundaries

You can use permissions boundaries, an advanced feature of IAM, to restrict the permissions that the Terraform IAM principal can delegate to the IAM roles it creates as part of the Tamr Core deployment. These boundaries prevent Terraform from granting arbitrary permissions to roles.

For more information about permissions boundaries, see the AWS permissions boundaries documentation.

The Tamr Core cloud-native deployment creates the following roles:

  • IAM Role for EMR Cluster
  • IAM Role for EMR Cluster Nodes (EC2 Instances)
  • IAM Role for EC2 Instances

The follow examples illustrate how you might use permissions boundaries to restrict the permissions the Terraform principal can delegate to the above roles.

The first step is to create a permissions boundary policy (for example, TamrBoundaryPolicy) for the Tamr deployment. When creating a policy to use as a permissions boundary, ensure that it minimally allows all the operations required by the three roles that are created as part of the Tamr Core deployment. (An excessively restrictive permissions boundary prevents some components from working properly.)

{
    "Version": "2012-10-17",
    "Statement": [{
   		 "Effect": "Allow",
   		 "Action": [
   			 "cloudwatch:PutMetricAlarm",
   			 "cloudwatch:DescribeAlarms",
   			 "cloudwatch:DeleteAlarms",
   			 "ec2:AuthorizeSecurityGroupEgress",
   			 "ec2:AuthorizeSecurityGroupIngress",
   			 "ec2:CancelSpotInstanceRequests",
   			 "ec2:CreateFleet",
   			 "ec2:CreateLaunchTemplate",
   			 "ec2:CreateNetworkInterface",
   			 "ec2:CreateTags",
   			 "ec2:DeleteLaunchTemplate",
   			 "ec2:DeleteNetworkInterface",
   			 "ec2:DeleteTags",
   			 "ec2:DeleteVolume",
   			 "ec2:DetachVolume",
   			 "ec2:DetachNetworkInterface",
   			 "ec2:DescribeAccountAttributes",
   			 "ec2:DescribeCapacityReservations",
   			 "ec2:DescribeDhcpOptions",
   			 "ec2:DescribeInstances",
   			 "ec2:DescribeLaunchTemplates",
   			 "ec2:DescribeNetworkAcls",
   			 "ec2:DescribeNetworkInterfaces",
   			 "ec2:DescribePlacementGroups",
   			 "ec2:DescribeRouteTables",
   			 "ec2:DescribeSecurityGroups",
   			 "ec2:DescribeSubnets",
   			 "ec2:DescribeVolumes",
   			 "ec2:DescribeVolumeStatus",
   			 "ec2:DescribeVpcAttribute",
   			 "ec2:DescribeVpcEndpoints",
   			 "ec2:DescribeVpcs",
   			 "ec2:ModifyImageAttribute",
   			 "ec2:ModifyInstanceAttribute",
   			 "ec2:RequestSpotInstances",
   			 "ec2:RevokeSecurityGroupEgress",
   			 "ec2:RevokeSecurityGroupIngress",
   			 "ec2:RunInstances",
   			 "ec2:TerminateInstances",
   			 "elasticmapreduce:AddInstanceGroups",
   			 "elasticmapreduce:AddJobFlowSteps",
   			 "elasticmapreduce:DescribeCluster",
   			 "elasticmapreduce:DescribeJobFlows",
   			 "elasticmapreduce:DescribeRepository",
   			 "elasticmapreduce:DescribeSecurityConfiguration",
   			 "elasticmapreduce:DescribeStep",
   			 "elasticmapreduce:ListBootstrapActions",
   			 "elasticmapreduce:ListInstanceGroups",
   			 "elasticmapreduce:ListInstances",
   			 "elasticmapreduce:ListSteps",
   			 "elasticmapreduce:RunJobFlow",
   			 "elasticmapreduce:TerminateJobFlows",
   			 "iam:GetRole",
   			 "iam:GetRolePolicy",
   			 "iam:ListInstanceProfiles",
   			 "iam:ListRolePolicies",
   			 "iam:PassRole",
   			 "s3:DeleteObject",
   			 "s3:Get*",
   			 "s3:List*",
   			 "s3:PutObject",
   			 "s3:PutObjectTagging"
   		 ],
   		 "Resource": ["*"]
   	 },
   	 {
   		 "Effect": "Allow",
   		 "Action": "iam:PassRole",
   		 "Resource": "arn:aws:iam::<account-id>:role/tamr_emr_service_role",
   		 "Condition": {
   			 "StringEquals": {
   				 "iam:PassedToService": "elasticmapreduce.amazonaws.com"
   			 }
   		 }
   	 }
    ]
}

Next, allow the Terraform IAM principal to perform the IAM actions necessary to provision a Tamr Core deployment. Only allow the Terraform IAM Principal to create and manage IAM roles on the condition that the roles are assigned the permissions boundaries defined above, as shown in the following example.

{
    "Version": "2012-10-17",
    "Statement": [{
   	 "Sid": "IAMRolesCreateOrChangeOnlyWithBoundary",
   	 "Effect": "Allow",
   	 "Action": [
            "iam:AttachRolePolicy",
            "iam:CreateRole",
            "iam:DetachRolePolicy",
            "iam:PutRolePermissionsBoundary"
   	 ],
   	 "Resource": "*",
   	 "Condition": {
          "StringEquals": {
   		"iam:PermissionsBoundary": [
   		    "arn:aws:iam::<account-id>:policy/TamrBoundaryPolicy"

   		 ]
   	   }
   	 }
    }]
}

Finally, do not allow the Terraform IAM principal to edit TamrBoundaryPolicy or to detach permissions boundaries from existing roles. Attach the Terraform IAM principal to a policy, as show in the following example.

{
    "Version": "2012-10-17",
    "Statement": [{
   		 "Sid": "DenyBoundaryPolicyEdit",
   		 "Effect": "Deny",
   		 "Action": [
   			 "iam:CreatePolicyVersion",
   			 "iam:DeletePolicy",
   			 "iam:DeletePolicyVersion",
   			 "iam:SetDefaultPolicyVersion"
   		 ],
   		 "Resource": [
                     "arn:aws:iam::<account-id>:policy/TamrBoundaryPolicy"
   		 ]
   	 },
   	 {
   		 "Sid": "DenyRoleBoundaryDelete",
   		 "Effect": "Deny",
   		 "Action": "iam:DeleteRolePermissionsBoundary",
   		 "Resource": "*"
   	 }
    ]
}

Terraform Module Support for Authorization Strategies

The following table indicates what versions of the Tamr AWS Terraform modules support each of the authorization strategies described in this topic (if applicable).

Module Authorization Based on Tags1 Resource-level Permissions Permission Boundaries
terraform-aws-emr >=5.2.0 All versions >=5.1.0
terraform-aws-es No2 All versions N/A
terraform-aws-rds-postgres >=2.1.0 All versions N/A
terraform-aws-s3 >=1.1.0 (Partial)3 All versions N/A
terraform-aws-security-groups >=0.1.0 All versions N/A
terraform-aws-tamr-config N/A N/A N/A
terraform-aws-tamr-vm >=4.0.0 All versions >=3.1.0

1 Versions prior to those listed in this column may provide support for tag-based authorization, but only for a subset of resources.

2 Amazon OpenSearch Service does not support authorization based on tags.

3 Tag-based authorization support is limited to IAM resources created by the terraform-aws-s3 module. Amazon S3 buckets do not support authorization based on tags for bucket operations.