provider:aws: Add support for updating aws_emr_cluster parameters (#11008)

* provider:aws: Add support for updating aws_emr_cluster parameters

Fixes #10962

We now support the update of `visibile_to_add_users` and
`termination_protected` parameters

```
make testacc TEST=./builtin/providers/aws TESTARGS='-run=TestAccAWSEMRCluster_'
==> Checking that code complies with gofmt requirements...
go generate $(go list ./... | grep -v /terraform/vendor/)
2017/01/03 18:45:20 Generated command/internal_plugin_list.go
TF_ACC=1 go test ./builtin/providers/aws -v -run=TestAccAWSEMRCluster_ -timeout 120m
=== RUN   TestAccAWSEMRCluster_basic
--- PASS: TestAccAWSEMRCluster_basic (551.98s)
=== RUN   TestAccAWSEMRCluster_terminationProtected
--- PASS: TestAccAWSEMRCluster_terminationProtected (545.52s)
=== RUN   TestAccAWSEMRCluster_visibleToAllUsers
--- PASS: TestAccAWSEMRCluster_visibleToAllUsers (552.09s)
=== RUN   TestAccAWSEMRCluster_tags
--- PASS: TestAccAWSEMRCluster_tags (598.91s)
PASS
ok	github.com/hashicorp/terraform/builtin/providers/aws	2248.537s
```

* Update resource_aws_emr_cluster_test.go
This commit is contained in:
Paul Stack 2017-01-03 22:15:44 +00:00 committed by GitHub
parent d5408bc2e4
commit 8ff44d0056
2 changed files with 685 additions and 34 deletions

View File

@ -24,121 +24,120 @@ func resourceAwsEMRCluster() *schema.Resource {
Update: resourceAwsEMRClusterUpdate, Update: resourceAwsEMRClusterUpdate,
Delete: resourceAwsEMRClusterDelete, Delete: resourceAwsEMRClusterDelete,
Schema: map[string]*schema.Schema{ Schema: map[string]*schema.Schema{
"name": &schema.Schema{ "name": {
Type: schema.TypeString, Type: schema.TypeString,
ForceNew: true, ForceNew: true,
Required: true, Required: true,
}, },
"release_label": &schema.Schema{ "release_label": {
Type: schema.TypeString, Type: schema.TypeString,
ForceNew: true, ForceNew: true,
Required: true, Required: true,
}, },
"master_instance_type": &schema.Schema{ "master_instance_type": {
Type: schema.TypeString, Type: schema.TypeString,
Required: true, Required: true,
ForceNew: true, ForceNew: true,
}, },
"core_instance_type": &schema.Schema{ "core_instance_type": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
ForceNew: true, ForceNew: true,
Computed: true, Computed: true,
}, },
"core_instance_count": &schema.Schema{ "core_instance_count": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: true,
Default: 1, Default: 1,
}, },
"cluster_state": &schema.Schema{ "cluster_state": {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,
}, },
"log_uri": &schema.Schema{ "log_uri": {
Type: schema.TypeString, Type: schema.TypeString,
ForceNew: true, ForceNew: true,
Optional: true, Optional: true,
}, },
"master_public_dns": &schema.Schema{ "master_public_dns": {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,
}, },
"applications": &schema.Schema{ "applications": {
Type: schema.TypeSet, Type: schema.TypeSet,
Optional: true, Optional: true,
ForceNew: true, ForceNew: true,
Elem: &schema.Schema{Type: schema.TypeString}, Elem: &schema.Schema{Type: schema.TypeString},
Set: schema.HashString, Set: schema.HashString,
}, },
"termination_protection": &schema.Schema{ "termination_protection": {
Type: schema.TypeBool,
Optional: true,
Computed: true,
},
"keep_job_flow_alive_when_no_steps": {
Type: schema.TypeBool, Type: schema.TypeBool,
ForceNew: true, ForceNew: true,
Optional: true, Optional: true,
Computed: true, Computed: true,
}, },
"keep_job_flow_alive_when_no_steps": &schema.Schema{ "ec2_attributes": {
Type: schema.TypeBool,
ForceNew: true,
Optional: true,
Computed: true,
},
"ec2_attributes": &schema.Schema{
Type: schema.TypeList, Type: schema.TypeList,
MaxItems: 1, MaxItems: 1,
Optional: true, Optional: true,
ForceNew: true, ForceNew: true,
Elem: &schema.Resource{ Elem: &schema.Resource{
Schema: map[string]*schema.Schema{ Schema: map[string]*schema.Schema{
"key_name": &schema.Schema{ "key_name": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
}, },
"subnet_id": &schema.Schema{ "subnet_id": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
}, },
"additional_master_security_groups": &schema.Schema{ "additional_master_security_groups": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
}, },
"additional_slave_security_groups": &schema.Schema{ "additional_slave_security_groups": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
}, },
"emr_managed_master_security_group": &schema.Schema{ "emr_managed_master_security_group": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
}, },
"emr_managed_slave_security_group": &schema.Schema{ "emr_managed_slave_security_group": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
}, },
"instance_profile": &schema.Schema{ "instance_profile": {
Type: schema.TypeString, Type: schema.TypeString,
Required: true, Required: true,
}, },
"service_access_security_group": &schema.Schema{ "service_access_security_group": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
}, },
}, },
}, },
}, },
"bootstrap_action": &schema.Schema{ "bootstrap_action": {
Type: schema.TypeSet, Type: schema.TypeSet,
Optional: true, Optional: true,
ForceNew: true, ForceNew: true,
Elem: &schema.Resource{ Elem: &schema.Resource{
Schema: map[string]*schema.Schema{ Schema: map[string]*schema.Schema{
"name": &schema.Schema{ "name": {
Type: schema.TypeString, Type: schema.TypeString,
Required: true, Required: true,
}, },
"path": &schema.Schema{ "path": {
Type: schema.TypeString, Type: schema.TypeString,
Required: true, Required: true,
}, },
"args": &schema.Schema{ "args": {
Type: schema.TypeSet, Type: schema.TypeSet,
Optional: true, Optional: true,
Elem: &schema.Schema{Type: schema.TypeString}, Elem: &schema.Schema{Type: schema.TypeString},
@ -148,20 +147,19 @@ func resourceAwsEMRCluster() *schema.Resource {
}, },
}, },
"tags": tagsSchema(), "tags": tagsSchema(),
"configurations": &schema.Schema{ "configurations": {
Type: schema.TypeString, Type: schema.TypeString,
ForceNew: true, ForceNew: true,
Optional: true, Optional: true,
}, },
"service_role": &schema.Schema{ "service_role": {
Type: schema.TypeString, Type: schema.TypeString,
ForceNew: true, ForceNew: true,
Required: true, Required: true,
}, },
"visible_to_all_users": &schema.Schema{ "visible_to_all_users": {
Type: schema.TypeBool, Type: schema.TypeBool,
Optional: true, Optional: true,
ForceNew: true,
Default: true, Default: true,
}, },
}, },
@ -430,6 +428,30 @@ func resourceAwsEMRClusterUpdate(d *schema.ResourceData, meta interface{}) error
} }
} }
if d.HasChange("visible_to_all_users") {
d.SetPartial("visible_to_all_users")
_, errModify := conn.SetVisibleToAllUsers(&emr.SetVisibleToAllUsersInput{
JobFlowIds: []*string{aws.String(d.Id())},
VisibleToAllUsers: aws.Bool(d.Get("visible_to_all_users").(bool)),
})
if errModify != nil {
log.Printf("[ERROR] %s", errModify)
return errModify
}
}
if d.HasChange("termination_protection") {
d.SetPartial("termination_protection")
_, errModify := conn.SetTerminationProtection(&emr.SetTerminationProtectionInput{
JobFlowIds: []*string{aws.String(d.Id())},
TerminationProtected: aws.Bool(d.Get("termination_protection").(bool)),
})
if errModify != nil {
log.Printf("[ERROR] %s", errModify)
return errModify
}
}
if err := setTagsEMR(conn, d); err != nil { if err := setTagsEMR(conn, d); err != nil {
return err return err
} else { } else {

View File

@ -21,7 +21,7 @@ func TestAccAWSEMRCluster_basic(t *testing.T) {
Providers: testAccProviders, Providers: testAccProviders,
CheckDestroy: testAccCheckAWSEmrDestroy, CheckDestroy: testAccCheckAWSEmrDestroy,
Steps: []resource.TestStep{ Steps: []resource.TestStep{
resource.TestStep{ {
Config: testAccAWSEmrClusterConfig(r), Config: testAccAWSEmrClusterConfig(r),
Check: testAccCheckAWSEmrClusterExists("aws_emr_cluster.tf-test-cluster", &jobFlow), Check: testAccCheckAWSEmrClusterExists("aws_emr_cluster.tf-test-cluster", &jobFlow),
}, },
@ -29,6 +29,69 @@ func TestAccAWSEMRCluster_basic(t *testing.T) {
}) })
} }
func TestAccAWSEMRCluster_terminationProtected(t *testing.T) {
var jobFlow emr.RunJobFlowOutput
r := acctest.RandInt()
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAWSEmrDestroy,
Steps: []resource.TestStep{
{
Config: testAccAWSEmrClusterConfig(r),
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSEmrClusterExists("aws_emr_cluster.tf-test-cluster", &jobFlow),
resource.TestCheckResourceAttr(
"aws_emr_cluster.tf-test-cluster", "termination_protection", "false"),
),
},
{
Config: testAccAWSEmrClusterConfigTerminationPolicyUpdated(r),
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSEmrClusterExists("aws_emr_cluster.tf-test-cluster", &jobFlow),
resource.TestCheckResourceAttr(
"aws_emr_cluster.tf-test-cluster", "termination_protection", "true"),
),
},
{
//Need to turn off termination_protection to allow the job to be deleted
Config: testAccAWSEmrClusterConfig(r),
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSEmrClusterExists("aws_emr_cluster.tf-test-cluster", &jobFlow),
),
},
},
})
}
func TestAccAWSEMRCluster_visibleToAllUsers(t *testing.T) {
var jobFlow emr.RunJobFlowOutput
r := acctest.RandInt()
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAWSEmrDestroy,
Steps: []resource.TestStep{
{
Config: testAccAWSEmrClusterConfig(r),
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSEmrClusterExists("aws_emr_cluster.tf-test-cluster", &jobFlow),
resource.TestCheckResourceAttr(
"aws_emr_cluster.tf-test-cluster", "visible_to_all_users", "true"),
),
},
{
Config: testAccAWSEmrClusterConfigVisibleToAllUsersUpdated(r),
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSEmrClusterExists("aws_emr_cluster.tf-test-cluster", &jobFlow),
resource.TestCheckResourceAttr(
"aws_emr_cluster.tf-test-cluster", "visible_to_all_users", "false"),
),
},
},
})
}
func TestAccAWSEMRCluster_tags(t *testing.T) { func TestAccAWSEMRCluster_tags(t *testing.T) {
var jobFlow emr.RunJobFlowOutput var jobFlow emr.RunJobFlowOutput
r := acctest.RandInt() r := acctest.RandInt()
@ -414,6 +477,572 @@ EOT
`, r, r, r, r, r, r) `, r, r, r, r, r, r)
} }
func testAccAWSEmrClusterConfigTerminationPolicyUpdated(r int) string {
return fmt.Sprintf(`
provider "aws" {
region = "us-west-2"
}
resource "aws_emr_cluster" "tf-test-cluster" {
name = "emr-test-%d"
release_label = "emr-4.6.0"
applications = ["Spark"]
ec2_attributes {
subnet_id = "${aws_subnet.main.id}"
emr_managed_master_security_group = "${aws_security_group.allow_all.id}"
emr_managed_slave_security_group = "${aws_security_group.allow_all.id}"
instance_profile = "${aws_iam_instance_profile.emr_profile.arn}"
}
master_instance_type = "m3.xlarge"
core_instance_type = "m3.xlarge"
core_instance_count = 1
tags {
role = "rolename"
dns_zone = "env_zone"
env = "env"
name = "name-env"
}
keep_job_flow_alive_when_no_steps = true
termination_protection = true
bootstrap_action {
path = "s3://elasticmapreduce/bootstrap-actions/run-if"
name = "runif"
args = ["instance.isMaster=true", "echo running on master node"]
}
configurations = "test-fixtures/emr_configurations.json"
depends_on = ["aws_main_route_table_association.a"]
service_role = "${aws_iam_role.iam_emr_default_role.arn}"
}
resource "aws_security_group" "allow_all" {
name = "allow_all"
description = "Allow all inbound traffic"
vpc_id = "${aws_vpc.main.id}"
ingress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
depends_on = ["aws_subnet.main"]
lifecycle {
ignore_changes = ["ingress", "egress"]
}
tags {
name = "emr_test"
}
}
resource "aws_vpc" "main" {
cidr_block = "168.31.0.0/16"
enable_dns_hostnames = true
tags {
name = "emr_test"
}
}
resource "aws_subnet" "main" {
vpc_id = "${aws_vpc.main.id}"
cidr_block = "168.31.0.0/20"
tags {
name = "emr_test"
}
}
resource "aws_internet_gateway" "gw" {
vpc_id = "${aws_vpc.main.id}"
}
resource "aws_route_table" "r" {
vpc_id = "${aws_vpc.main.id}"
route {
cidr_block = "0.0.0.0/0"
gateway_id = "${aws_internet_gateway.gw.id}"
}
}
resource "aws_main_route_table_association" "a" {
vpc_id = "${aws_vpc.main.id}"
route_table_id = "${aws_route_table.r.id}"
}
###
# IAM things
###
# IAM role for EMR Service
resource "aws_iam_role" "iam_emr_default_role" {
name = "iam_emr_default_role_%d"
assume_role_policy = <<EOT
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "elasticmapreduce.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOT
}
resource "aws_iam_role_policy_attachment" "service-attach" {
role = "${aws_iam_role.iam_emr_default_role.id}"
policy_arn = "${aws_iam_policy.iam_emr_default_policy.arn}"
}
resource "aws_iam_policy" "iam_emr_default_policy" {
name = "iam_emr_default_policy_%d"
policy = <<EOT
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Resource": "*",
"Action": [
"ec2:AuthorizeSecurityGroupEgress",
"ec2:AuthorizeSecurityGroupIngress",
"ec2:CancelSpotInstanceRequests",
"ec2:CreateNetworkInterface",
"ec2:CreateSecurityGroup",
"ec2:CreateTags",
"ec2:DeleteNetworkInterface",
"ec2:DeleteSecurityGroup",
"ec2:DeleteTags",
"ec2:DescribeAvailabilityZones",
"ec2:DescribeAccountAttributes",
"ec2:DescribeDhcpOptions",
"ec2:DescribeInstanceStatus",
"ec2:DescribeInstances",
"ec2:DescribeKeyPairs",
"ec2:DescribeNetworkAcls",
"ec2:DescribeNetworkInterfaces",
"ec2:DescribePrefixLists",
"ec2:DescribeRouteTables",
"ec2:DescribeSecurityGroups",
"ec2:DescribeSpotInstanceRequests",
"ec2:DescribeSpotPriceHistory",
"ec2:DescribeSubnets",
"ec2:DescribeVpcAttribute",
"ec2:DescribeVpcEndpoints",
"ec2:DescribeVpcEndpointServices",
"ec2:DescribeVpcs",
"ec2:DetachNetworkInterface",
"ec2:ModifyImageAttribute",
"ec2:ModifyInstanceAttribute",
"ec2:RequestSpotInstances",
"ec2:RevokeSecurityGroupEgress",
"ec2:RunInstances",
"ec2:TerminateInstances",
"ec2:DeleteVolume",
"ec2:DescribeVolumeStatus",
"ec2:DescribeVolumes",
"ec2:DetachVolume",
"iam:GetRole",
"iam:GetRolePolicy",
"iam:ListInstanceProfiles",
"iam:ListRolePolicies",
"iam:PassRole",
"s3:CreateBucket",
"s3:Get*",
"s3:List*",
"sdb:BatchPutAttributes",
"sdb:Select",
"sqs:CreateQueue",
"sqs:Delete*",
"sqs:GetQueue*",
"sqs:PurgeQueue",
"sqs:ReceiveMessage"
]
}]
}
EOT
}
# IAM Role for EC2 Instance Profile
resource "aws_iam_role" "iam_emr_profile_role" {
name = "iam_emr_profile_role_%d"
assume_role_policy = <<EOT
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOT
}
resource "aws_iam_instance_profile" "emr_profile" {
name = "emr_profile_%d"
roles = ["${aws_iam_role.iam_emr_profile_role.name}"]
}
resource "aws_iam_role_policy_attachment" "profile-attach" {
role = "${aws_iam_role.iam_emr_profile_role.id}"
policy_arn = "${aws_iam_policy.iam_emr_profile_policy.arn}"
}
resource "aws_iam_policy" "iam_emr_profile_policy" {
name = "iam_emr_profile_policy_%d"
policy = <<EOT
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Resource": "*",
"Action": [
"cloudwatch:*",
"dynamodb:*",
"ec2:Describe*",
"elasticmapreduce:Describe*",
"elasticmapreduce:ListBootstrapActions",
"elasticmapreduce:ListClusters",
"elasticmapreduce:ListInstanceGroups",
"elasticmapreduce:ListInstances",
"elasticmapreduce:ListSteps",
"kinesis:CreateStream",
"kinesis:DeleteStream",
"kinesis:DescribeStream",
"kinesis:GetRecords",
"kinesis:GetShardIterator",
"kinesis:MergeShards",
"kinesis:PutRecord",
"kinesis:SplitShard",
"rds:Describe*",
"s3:*",
"sdb:*",
"sns:*",
"sqs:*"
]
}]
}
EOT
}
`, r, r, r, r, r, r)
}
func testAccAWSEmrClusterConfigVisibleToAllUsersUpdated(r int) string {
return fmt.Sprintf(`
provider "aws" {
region = "us-west-2"
}
resource "aws_emr_cluster" "tf-test-cluster" {
name = "emr-test-%d"
release_label = "emr-4.6.0"
applications = ["Spark"]
ec2_attributes {
subnet_id = "${aws_subnet.main.id}"
emr_managed_master_security_group = "${aws_security_group.allow_all.id}"
emr_managed_slave_security_group = "${aws_security_group.allow_all.id}"
instance_profile = "${aws_iam_instance_profile.emr_profile.arn}"
}
master_instance_type = "m3.xlarge"
core_instance_type = "m3.xlarge"
core_instance_count = 1
tags {
role = "rolename"
dns_zone = "env_zone"
env = "env"
name = "name-env"
}
keep_job_flow_alive_when_no_steps = true
visible_to_all_users = false
bootstrap_action {
path = "s3://elasticmapreduce/bootstrap-actions/run-if"
name = "runif"
args = ["instance.isMaster=true", "echo running on master node"]
}
configurations = "test-fixtures/emr_configurations.json"
depends_on = ["aws_main_route_table_association.a"]
service_role = "${aws_iam_role.iam_emr_default_role.arn}"
}
resource "aws_security_group" "allow_all" {
name = "allow_all"
description = "Allow all inbound traffic"
vpc_id = "${aws_vpc.main.id}"
ingress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
depends_on = ["aws_subnet.main"]
lifecycle {
ignore_changes = ["ingress", "egress"]
}
tags {
name = "emr_test"
}
}
resource "aws_vpc" "main" {
cidr_block = "168.31.0.0/16"
enable_dns_hostnames = true
tags {
name = "emr_test"
}
}
resource "aws_subnet" "main" {
vpc_id = "${aws_vpc.main.id}"
cidr_block = "168.31.0.0/20"
tags {
name = "emr_test"
}
}
resource "aws_internet_gateway" "gw" {
vpc_id = "${aws_vpc.main.id}"
}
resource "aws_route_table" "r" {
vpc_id = "${aws_vpc.main.id}"
route {
cidr_block = "0.0.0.0/0"
gateway_id = "${aws_internet_gateway.gw.id}"
}
}
resource "aws_main_route_table_association" "a" {
vpc_id = "${aws_vpc.main.id}"
route_table_id = "${aws_route_table.r.id}"
}
###
# IAM things
###
# IAM role for EMR Service
resource "aws_iam_role" "iam_emr_default_role" {
name = "iam_emr_default_role_%d"
assume_role_policy = <<EOT
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "elasticmapreduce.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOT
}
resource "aws_iam_role_policy_attachment" "service-attach" {
role = "${aws_iam_role.iam_emr_default_role.id}"
policy_arn = "${aws_iam_policy.iam_emr_default_policy.arn}"
}
resource "aws_iam_policy" "iam_emr_default_policy" {
name = "iam_emr_default_policy_%d"
policy = <<EOT
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Resource": "*",
"Action": [
"ec2:AuthorizeSecurityGroupEgress",
"ec2:AuthorizeSecurityGroupIngress",
"ec2:CancelSpotInstanceRequests",
"ec2:CreateNetworkInterface",
"ec2:CreateSecurityGroup",
"ec2:CreateTags",
"ec2:DeleteNetworkInterface",
"ec2:DeleteSecurityGroup",
"ec2:DeleteTags",
"ec2:DescribeAvailabilityZones",
"ec2:DescribeAccountAttributes",
"ec2:DescribeDhcpOptions",
"ec2:DescribeInstanceStatus",
"ec2:DescribeInstances",
"ec2:DescribeKeyPairs",
"ec2:DescribeNetworkAcls",
"ec2:DescribeNetworkInterfaces",
"ec2:DescribePrefixLists",
"ec2:DescribeRouteTables",
"ec2:DescribeSecurityGroups",
"ec2:DescribeSpotInstanceRequests",
"ec2:DescribeSpotPriceHistory",
"ec2:DescribeSubnets",
"ec2:DescribeVpcAttribute",
"ec2:DescribeVpcEndpoints",
"ec2:DescribeVpcEndpointServices",
"ec2:DescribeVpcs",
"ec2:DetachNetworkInterface",
"ec2:ModifyImageAttribute",
"ec2:ModifyInstanceAttribute",
"ec2:RequestSpotInstances",
"ec2:RevokeSecurityGroupEgress",
"ec2:RunInstances",
"ec2:TerminateInstances",
"ec2:DeleteVolume",
"ec2:DescribeVolumeStatus",
"ec2:DescribeVolumes",
"ec2:DetachVolume",
"iam:GetRole",
"iam:GetRolePolicy",
"iam:ListInstanceProfiles",
"iam:ListRolePolicies",
"iam:PassRole",
"s3:CreateBucket",
"s3:Get*",
"s3:List*",
"sdb:BatchPutAttributes",
"sdb:Select",
"sqs:CreateQueue",
"sqs:Delete*",
"sqs:GetQueue*",
"sqs:PurgeQueue",
"sqs:ReceiveMessage"
]
}]
}
EOT
}
# IAM Role for EC2 Instance Profile
resource "aws_iam_role" "iam_emr_profile_role" {
name = "iam_emr_profile_role_%d"
assume_role_policy = <<EOT
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOT
}
resource "aws_iam_instance_profile" "emr_profile" {
name = "emr_profile_%d"
roles = ["${aws_iam_role.iam_emr_profile_role.name}"]
}
resource "aws_iam_role_policy_attachment" "profile-attach" {
role = "${aws_iam_role.iam_emr_profile_role.id}"
policy_arn = "${aws_iam_policy.iam_emr_profile_policy.arn}"
}
resource "aws_iam_policy" "iam_emr_profile_policy" {
name = "iam_emr_profile_policy_%d"
policy = <<EOT
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Resource": "*",
"Action": [
"cloudwatch:*",
"dynamodb:*",
"ec2:Describe*",
"elasticmapreduce:Describe*",
"elasticmapreduce:ListBootstrapActions",
"elasticmapreduce:ListClusters",
"elasticmapreduce:ListInstanceGroups",
"elasticmapreduce:ListInstances",
"elasticmapreduce:ListSteps",
"kinesis:CreateStream",
"kinesis:DeleteStream",
"kinesis:DescribeStream",
"kinesis:GetRecords",
"kinesis:GetShardIterator",
"kinesis:MergeShards",
"kinesis:PutRecord",
"kinesis:SplitShard",
"rds:Describe*",
"s3:*",
"sdb:*",
"sns:*",
"sqs:*"
]
}]
}
EOT
}
`, r, r, r, r, r, r)
}
func testAccAWSEmrClusterConfigUpdatedTags(r int) string { func testAccAWSEmrClusterConfigUpdatedTags(r int) string {
return fmt.Sprintf(` return fmt.Sprintf(`
provider "aws" { provider "aws" {