π«EMR SaaS Installation
Last updated
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowEmrContainersBasicAccess",
"Effect": "Allow",
"Action": [
"emr-containers:ListVirtualClusters",
"emr-containers:DescribeVirtualCluster",
"emr-containers:ListJobRuns",
"emr-containers:DescribeJobRun",
"elasticmapreduce:CreatePersistentAppUI",
"elasticmapreduce:DescribePersistentAppUI",
"elasticmapreduce:GetPersistentAppUIPresignedURL",
"elasticmapreduce:DescribeCluster",
"elasticmapreduce:DescribeEditor",
"elasticmapreduce:DescribeJobFlows",
"elasticmapreduce:DescribeSecurityConfiguration",
"elasticmapreduce:DescribeStep",
"elasticmapreduce:DescribeReleaseLabel",
"elasticmapreduce:GetBlockPublicAccessConfiguration",
"elasticmapreduce:GetManagedScalingPolicy",
"elasticmapreduce:GetAutoTerminationPolicy",
"elasticmapreduce:ListBootstrapActions",
"elasticmapreduce:ListClusters",
"elasticmapreduce:ListEditors",
"elasticmapreduce:ListInstanceFleets",
"elasticmapreduce:ListInstanceGroups",
"elasticmapreduce:ListInstances",
"elasticmapreduce:ListSecurityConfigurations",
"elasticmapreduce:ListSteps",
"elasticmapreduce:ListSupportedInstanceTypes",
"elasticmapreduce:ViewEventsFromAllClustersInConsole"
],
"Resource": "*"
}
]
}{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::DATAFLINT_ACCOUNT_ID:role/eks-dataflint-service-role"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"sts:ExternalId": "CUSTOMER_EXTERNAL_ID"
}
}
}
]
}aws sts get-caller-identity{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::DATAFLINT_ACCOUNT_ID:role/eks-dataflint-service-role"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"sts:ExternalId": "CUSTOMER_EXTERNAL_ID"
}
}
}
]
}{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowEmrContainersBasicAccess",
"Effect": "Allow",
"Action": [
"emr-containers:ListVirtualClusters",
"emr-containers:DescribeVirtualCluster",
"emr-containers:ListJobRuns",
"emr-containers:DescribeJobRun",
"elasticmapreduce:CreatePersistentAppUI",
"elasticmapreduce:DescribePersistentAppUI",
"elasticmapreduce:GetPersistentAppUIPresignedURL",
"elasticmapreduce:DescribeCluster",
"elasticmapreduce:DescribeEditor",
"elasticmapreduce:DescribeJobFlows",
"elasticmapreduce:DescribeSecurityConfiguration",
"elasticmapreduce:DescribeStep",
"elasticmapreduce:DescribeReleaseLabel",
"elasticmapreduce:GetBlockPublicAccessConfiguration",
"elasticmapreduce:GetManagedScalingPolicy",
"elasticmapreduce:GetAutoTerminationPolicy",
"elasticmapreduce:ListBootstrapActions",
"elasticmapreduce:ListClusters",
"elasticmapreduce:ListEditors",
"elasticmapreduce:ListInstanceFleets",
"elasticmapreduce:ListInstanceGroups",
"elasticmapreduce:ListInstances",
"elasticmapreduce:ListSecurityConfigurations",
"elasticmapreduce:ListSteps",
"elasticmapreduce:ListSupportedInstanceTypes",
"elasticmapreduce:ViewEventsFromAllClustersInConsole"
],
"Resource": "*"
}
]
}ROLE_NAME="dataflint-emr-read-only-role"
POLICY_NAME="DataflintEmrContainersReadOnly"
aws iam create-role \
--role-name "${ROLE_NAME}" \
--assume-role-policy-document file://trust-policy.json \
--description "Role for DataFlint to access EMR in read-only mode"
POLICY_ARN="$(aws iam create-policy \
--policy-name "${POLICY_NAME}" \
--policy-document file://permissions-policy.json \
--query 'Policy.Arn' \
--output text)"
aws iam attach-role-policy \
--role-name "${ROLE_NAME}" \
--policy-arn "${POLICY_ARN}"
aws iam get-role --role-name "${ROLE_NAME}" --query 'Role.Arn' --output textterraform {
required_version = ">= 1.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {}
variable "dataflint_account_id" {
description = "AWS account ID of DataFlint (provided by DataFlint)"
type = string
default = "975050001706"
}
variable "customer_external_id" {
description = "External ID (provided by DataFlint)"
type = string
sensitive = true
}
variable "dataflint_service_role_name" {
description = "Role name in the DataFlint account that will assume this role"
type = string
default = "eks-dataflint-service-role"
}
resource "aws_iam_role" "dataflint_emr_read_only" {
name = "dataflint-emr-read-only-role"
description = "Role for DataFlint to access EMR / EMR Containers in read-only mode"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Principal = {
AWS = "arn:aws:iam::${var.dataflint_account_id}:role/${var.dataflint_service_role_name}"
}
Action = "sts:AssumeRole"
Condition = {
StringEquals = {
"sts:ExternalId" = var.customer_external_id
}
}
}
]
})
tags = {
Name = "dataflint-emr-read-only-role"
Purpose = "DataFlint EMR Integration"
ManagedBy = "Terraform"
}
}
resource "aws_iam_policy" "emr_containers_read_only" {
name = "DataflintEmrContainersReadOnly"
description = "Policy granting read-only access to EMR / EMR Containers for DataFlint"
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Sid = "AllowEmrContainersBasicAccess"
Effect = "Allow"
Action = [
"emr-containers:ListVirtualClusters",
"emr-containers:DescribeVirtualCluster",
"emr-containers:ListJobRuns",
"emr-containers:DescribeJobRun",
"elasticmapreduce:CreatePersistentAppUI",
"elasticmapreduce:DescribePersistentAppUI",
"elasticmapreduce:GetPersistentAppUIPresignedURL",
"elasticmapreduce:DescribeCluster",
"elasticmapreduce:DescribeEditor",
"elasticmapreduce:DescribeJobFlows",
"elasticmapreduce:DescribeSecurityConfiguration",
"elasticmapreduce:DescribeStep",
"elasticmapreduce:DescribeReleaseLabel",
"elasticmapreduce:GetBlockPublicAccessConfiguration",
"elasticmapreduce:GetManagedScalingPolicy",
"elasticmapreduce:GetAutoTerminationPolicy",
"elasticmapreduce:ListBootstrapActions",
"elasticmapreduce:ListClusters",
"elasticmapreduce:ListEditors",
"elasticmapreduce:ListInstanceFleets",
"elasticmapreduce:ListInstanceGroups",
"elasticmapreduce:ListInstances",
"elasticmapreduce:ListSecurityConfigurations",
"elasticmapreduce:ListSteps",
"elasticmapreduce:ListSupportedInstanceTypes",
"elasticmapreduce:ViewEventsFromAllClustersInConsole"
]
Resource = "*"
}
]
})
tags = {
Name = "DataflintEmrContainersReadOnly"
Purpose = "DataFlint EMR Integration"
ManagedBy = "Terraform"
}
}
resource "aws_iam_role_policy_attachment" "dataflint_emr_policy_attachment" {
role = aws_iam_role.dataflint_emr_read_only.name
policy_arn = aws_iam_policy.emr_containers_read_only.arn
}
output "role_arn" {
description = "Provide this ARN to DataFlint"
value = aws_iam_role.dataflint_emr_read_only.arn
}terraform init
terraform applyAWSTemplateFormatVersion: "2010-09-09"
Description: "DataFlint - EMR / EMR Containers read-only cross-account role"
Parameters:
RoleName:
Type: String
Default: dataflint-emr-read-only-role
Description: "Name of the IAM role to create"
DataflintAccountId:
Type: String
Default: "975050001706"
Description: "AWS account ID of DataFlint"
DataflintServiceRoleName:
Type: String
Default: eks-dataflint-service-role
Description: "Role name in the DataFlint account that will assume this role"
CustomerExternalId:
Type: String
NoEcho: true
Description: "External ID (provided by DataFlint)"
Resources:
DataflintEmrReadOnlyRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Ref RoleName
Description: "Role for DataFlint to access EMR / EMR Containers in read-only mode"
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
AWS: !Sub "arn:aws:iam::${DataflintAccountId}:role/${DataflintServiceRoleName}"
Action: "sts:AssumeRole"
Condition:
StringEquals:
sts:ExternalId: !Ref CustomerExternalId
Policies:
- PolicyName: DataflintEmrContainersReadOnly
PolicyDocument:
Version: "2012-10-17"
Statement:
- Sid: AllowEmrContainersBasicAccess
Effect: Allow
Action:
- emr-containers:ListVirtualClusters
- emr-containers:DescribeVirtualCluster
- emr-containers:ListJobRuns
- emr-containers:DescribeJobRun
- elasticmapreduce:CreatePersistentAppUI
- elasticmapreduce:DescribePersistentAppUI
- elasticmapreduce:GetPersistentAppUIPresignedURL
- elasticmapreduce:DescribeCluster
- elasticmapreduce:DescribeEditor
- elasticmapreduce:DescribeJobFlows
- elasticmapreduce:DescribeSecurityConfiguration
- elasticmapreduce:DescribeStep
- elasticmapreduce:DescribeReleaseLabel
- elasticmapreduce:GetBlockPublicAccessConfiguration
- elasticmapreduce:GetManagedScalingPolicy
- elasticmapreduce:GetAutoTerminationPolicy
- elasticmapreduce:ListBootstrapActions
- elasticmapreduce:ListClusters
- elasticmapreduce:ListEditors
- elasticmapreduce:ListInstanceFleets
- elasticmapreduce:ListInstanceGroups
- elasticmapreduce:ListInstances
- elasticmapreduce:ListSecurityConfigurations
- elasticmapreduce:ListSteps
- elasticmapreduce:ListSupportedInstanceTypes
- elasticmapreduce:ViewEventsFromAllClustersInConsole
Resource: "*"
Outputs:
RoleArn:
Description: "Provide this ARN to DataFlint"
Value: !GetAtt DataflintEmrReadOnlyRole.Arnaws cloudformation create-stack \
--stack-name dataflint-emr-read-only \
--template-body file://dataflint-emr-read-only-role.yaml \
--capabilities CAPABILITY_NAMED_IAM \
--parameters \
ParameterKey=DataflintAccountId,ParameterValue=DATAFLINT_ACCOUNT_ID \
ParameterKey=CustomerExternalId,ParameterValue=CUSTOMER_EXTERNAL_ID \
ParameterKey=RoleName,ParameterValue=dataflint-emr-read-only-roleaws iam get-role --role-name dataflint-emr-read-only-role
aws iam list-attached-role-policies --role-name dataflint-emr-read-only-roleROLE_ARN="$(aws iam get-role --role-name dataflint-emr-read-only-role --query 'Role.Arn' --output text)"
aws iam simulate-principal-policy \
--policy-source-arn "${ROLE_ARN}" \
--action-names emr-containers:ListVirtualClusters elasticmapreduce:ListClusters \
--output text