provider/aws: Add support to `aws_redshift_cluster` for ``iam_roles`` (#6647)

This commit is contained in:
Paul Stack 2016-05-24 22:44:46 +01:00
parent 33a72099de
commit ce4841e6a6
3 changed files with 141 additions and 15 deletions

View File

@ -196,6 +196,14 @@ func resourceAwsRedshiftCluster() *schema.Resource {
Computed: true, Computed: true,
}, },
"iam_roles": &schema.Schema{
Type: schema.TypeSet,
Optional: true,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
Set: schema.HashString,
},
"tags": tagsSchema(), "tags": tagsSchema(),
}, },
} }
@ -263,6 +271,10 @@ func resourceAwsRedshiftClusterCreate(d *schema.ResourceData, meta interface{})
createOpts.ElasticIp = aws.String(v.(string)) createOpts.ElasticIp = aws.String(v.(string))
} }
if v, ok := d.GetOk("iam_roles"); ok {
createOpts.IamRoles = expandStringList(v.(*schema.Set).List())
}
log.Printf("[DEBUG] Redshift Cluster create options: %s", createOpts) log.Printf("[DEBUG] Redshift Cluster create options: %s", createOpts)
resp, err := conn.CreateCluster(createOpts) resp, err := conn.CreateCluster(createOpts)
if err != nil { if err != nil {
@ -359,6 +371,14 @@ func resourceAwsRedshiftClusterRead(d *schema.ResourceData, meta interface{}) er
return fmt.Errorf("[DEBUG] Error saving Cluster Security Group Names to state for Redshift Cluster (%s): %s", d.Id(), err) return fmt.Errorf("[DEBUG] Error saving Cluster Security Group Names to state for Redshift Cluster (%s): %s", d.Id(), err)
} }
var iamRoles []string
for _, i := range rsc.IamRoles {
iamRoles = append(iamRoles, *i.IamRoleArn)
}
if err := d.Set("iam_roles", iamRoles); err != nil {
return fmt.Errorf("[DEBUG] Error saving IAM Roles to state for Redshift Cluster (%s): %s", d.Id(), err)
}
d.Set("cluster_public_key", rsc.ClusterPublicKey) d.Set("cluster_public_key", rsc.ClusterPublicKey)
d.Set("cluster_revision_number", rsc.ClusterRevisionNumber) d.Set("cluster_revision_number", rsc.ClusterRevisionNumber)
d.Set("tags", tagsToMapRedshift(rsc.Tags)) d.Set("tags", tagsToMapRedshift(rsc.Tags))
@ -461,6 +481,41 @@ func resourceAwsRedshiftClusterUpdate(d *schema.ResourceData, meta interface{})
if err != nil { if err != nil {
return fmt.Errorf("[WARN] Error modifying Redshift Cluster (%s): %s", d.Id(), err) return fmt.Errorf("[WARN] Error modifying Redshift Cluster (%s): %s", d.Id(), err)
} }
}
if d.HasChange("iam_roles") {
o, n := d.GetChange("iam_roles")
if o == nil {
o = new(schema.Set)
}
if n == nil {
n = new(schema.Set)
}
os := o.(*schema.Set)
ns := n.(*schema.Set)
removeIams := os.Difference(ns).List()
addIams := ns.Difference(os).List()
log.Printf("[INFO] Building Redshift Modify Cluster IAM Role Options")
req := &redshift.ModifyClusterIamRolesInput{
ClusterIdentifier: aws.String(d.Id()),
AddIamRoles: expandStringList(addIams),
RemoveIamRoles: expandStringList(removeIams),
}
log.Printf("[INFO] Modifying Redshift Cluster IAM Roles: %s", d.Id())
log.Printf("[DEBUG] Redshift Cluster Modify IAM Role options: %s", req)
_, err := conn.ModifyClusterIamRoles(req)
if err != nil {
return fmt.Errorf("[WARN] Error modifying Redshift Cluster IAM Roles (%s): %s", d.Id(), err)
}
d.SetPartial("iam_roles")
}
if requestUpdate || d.HasChange("iam_roles") {
stateConf := &resource.StateChangeConf{ stateConf := &resource.StateChangeConf{
Pending: []string{"creating", "deleting", "rebooting", "resizing", "renaming", "modifying"}, Pending: []string{"creating", "deleting", "rebooting", "resizing", "renaming", "modifying"},
@ -471,7 +526,7 @@ func resourceAwsRedshiftClusterUpdate(d *schema.ResourceData, meta interface{})
} }
// Wait, catching any errors // Wait, catching any errors
_, err = stateConf.WaitForState() _, err := stateConf.WaitForState()
if err != nil { if err != nil {
return fmt.Errorf("[WARN] Error Modifying Redshift Cluster (%s): %s", d.Id(), err) return fmt.Errorf("[WARN] Error Modifying Redshift Cluster (%s): %s", d.Id(), err)
} }

View File

@ -38,6 +38,39 @@ func TestAccAWSRedshiftCluster_basic(t *testing.T) {
}) })
} }
func TestAccAWSRedshiftCluster_iamRoles(t *testing.T) {
var v redshift.Cluster
ri := rand.New(rand.NewSource(time.Now().UnixNano())).Int()
preConfig := fmt.Sprintf(testAccAWSRedshiftClusterConfig_iamRoles, ri, ri, ri)
postConfig := fmt.Sprintf(testAccAWSRedshiftClusterConfig_updateIamRoles, ri, ri, ri)
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAWSRedshiftClusterDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: preConfig,
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSRedshiftClusterExists("aws_redshift_cluster.default", &v),
resource.TestCheckResourceAttr(
"aws_redshift_cluster.default", "iam_roles.#", "2"),
),
},
resource.TestStep{
Config: postConfig,
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSRedshiftClusterExists("aws_redshift_cluster.default", &v),
resource.TestCheckResourceAttr(
"aws_redshift_cluster.default", "iam_roles.#", "1"),
),
},
},
})
}
func TestAccAWSRedshiftCluster_publiclyAccessible(t *testing.T) { func TestAccAWSRedshiftCluster_publiclyAccessible(t *testing.T) {
var v redshift.Cluster var v redshift.Cluster
@ -376,7 +409,6 @@ resource "aws_redshift_cluster" "default" {
node_type = "dc1.large" node_type = "dc1.large"
automated_snapshot_retention_period = 7 automated_snapshot_retention_period = 7
allow_version_upgrade = false allow_version_upgrade = false
tags { tags {
environment = "Production" environment = "Production"
cluster = "reader" cluster = "reader"
@ -394,7 +426,6 @@ resource "aws_redshift_cluster" "default" {
node_type = "dc1.large" node_type = "dc1.large"
automated_snapshot_retention_period = 7 automated_snapshot_retention_period = 7
allow_version_upgrade = false allow_version_upgrade = false
tags { tags {
environment = "Production" environment = "Production"
} }
@ -404,14 +435,12 @@ var testAccAWSRedshiftClusterConfig_notPubliclyAccessible = `
resource "aws_vpc" "foo" { resource "aws_vpc" "foo" {
cidr_block = "10.1.0.0/16" cidr_block = "10.1.0.0/16"
} }
resource "aws_internet_gateway" "foo" { resource "aws_internet_gateway" "foo" {
vpc_id = "${aws_vpc.foo.id}" vpc_id = "${aws_vpc.foo.id}"
tags { tags {
foo = "bar" foo = "bar"
} }
} }
resource "aws_subnet" "foo" { resource "aws_subnet" "foo" {
cidr_block = "10.1.1.0/24" cidr_block = "10.1.1.0/24"
availability_zone = "us-west-2a" availability_zone = "us-west-2a"
@ -420,7 +449,6 @@ resource "aws_subnet" "foo" {
Name = "tf-dbsubnet-test-1" Name = "tf-dbsubnet-test-1"
} }
} }
resource "aws_subnet" "bar" { resource "aws_subnet" "bar" {
cidr_block = "10.1.2.0/24" cidr_block = "10.1.2.0/24"
availability_zone = "us-west-2b" availability_zone = "us-west-2b"
@ -429,7 +457,6 @@ resource "aws_subnet" "bar" {
Name = "tf-dbsubnet-test-2" Name = "tf-dbsubnet-test-2"
} }
} }
resource "aws_subnet" "foobar" { resource "aws_subnet" "foobar" {
cidr_block = "10.1.3.0/24" cidr_block = "10.1.3.0/24"
availability_zone = "us-west-2c" availability_zone = "us-west-2c"
@ -438,13 +465,11 @@ resource "aws_subnet" "foobar" {
Name = "tf-dbsubnet-test-3" Name = "tf-dbsubnet-test-3"
} }
} }
resource "aws_redshift_subnet_group" "foo" { resource "aws_redshift_subnet_group" "foo" {
name = "foo" name = "foo"
description = "foo description" description = "foo description"
subnet_ids = ["${aws_subnet.foo.id}", "${aws_subnet.bar.id}", "${aws_subnet.foobar.id}"] subnet_ids = ["${aws_subnet.foo.id}", "${aws_subnet.bar.id}", "${aws_subnet.foobar.id}"]
} }
resource "aws_redshift_cluster" "default" { resource "aws_redshift_cluster" "default" {
cluster_identifier = "tf-redshift-cluster-%d" cluster_identifier = "tf-redshift-cluster-%d"
availability_zone = "us-west-2a" availability_zone = "us-west-2a"
@ -462,14 +487,12 @@ var testAccAWSRedshiftClusterConfig_updatePubliclyAccessible = `
resource "aws_vpc" "foo" { resource "aws_vpc" "foo" {
cidr_block = "10.1.0.0/16" cidr_block = "10.1.0.0/16"
} }
resource "aws_internet_gateway" "foo" { resource "aws_internet_gateway" "foo" {
vpc_id = "${aws_vpc.foo.id}" vpc_id = "${aws_vpc.foo.id}"
tags { tags {
foo = "bar" foo = "bar"
} }
} }
resource "aws_subnet" "foo" { resource "aws_subnet" "foo" {
cidr_block = "10.1.1.0/24" cidr_block = "10.1.1.0/24"
availability_zone = "us-west-2a" availability_zone = "us-west-2a"
@ -478,7 +501,6 @@ resource "aws_subnet" "foo" {
Name = "tf-dbsubnet-test-1" Name = "tf-dbsubnet-test-1"
} }
} }
resource "aws_subnet" "bar" { resource "aws_subnet" "bar" {
cidr_block = "10.1.2.0/24" cidr_block = "10.1.2.0/24"
availability_zone = "us-west-2b" availability_zone = "us-west-2b"
@ -487,7 +509,6 @@ resource "aws_subnet" "bar" {
Name = "tf-dbsubnet-test-2" Name = "tf-dbsubnet-test-2"
} }
} }
resource "aws_subnet" "foobar" { resource "aws_subnet" "foobar" {
cidr_block = "10.1.3.0/24" cidr_block = "10.1.3.0/24"
availability_zone = "us-west-2c" availability_zone = "us-west-2c"
@ -496,13 +517,11 @@ resource "aws_subnet" "foobar" {
Name = "tf-dbsubnet-test-3" Name = "tf-dbsubnet-test-3"
} }
} }
resource "aws_redshift_subnet_group" "foo" { resource "aws_redshift_subnet_group" "foo" {
name = "foo" name = "foo"
description = "foo description" description = "foo description"
subnet_ids = ["${aws_subnet.foo.id}", "${aws_subnet.bar.id}", "${aws_subnet.foobar.id}"] subnet_ids = ["${aws_subnet.foo.id}", "${aws_subnet.bar.id}", "${aws_subnet.foobar.id}"]
} }
resource "aws_redshift_cluster" "default" { resource "aws_redshift_cluster" "default" {
cluster_identifier = "tf-redshift-cluster-%d" cluster_identifier = "tf-redshift-cluster-%d"
availability_zone = "us-west-2a" availability_zone = "us-west-2a"
@ -515,3 +534,53 @@ resource "aws_redshift_cluster" "default" {
cluster_subnet_group_name = "${aws_redshift_subnet_group.foo.name}" cluster_subnet_group_name = "${aws_redshift_subnet_group.foo.name}"
publicly_accessible = true publicly_accessible = true
}` }`
var testAccAWSRedshiftClusterConfig_iamRoles = `
resource "aws_iam_role" "ec2-role" {
name = "test-role-ec2-%d"
path = "/"
assume_role_policy = "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"Service\":[\"ec2.amazonaws.com\"]},\"Action\":[\"sts:AssumeRole\"]}]}"
}
resource "aws_iam_role" "lambda-role" {
name = "test-role-lambda-%d"
path = "/"
assume_role_policy = "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"Service\":[\"lambda.amazonaws.com\"]},\"Action\":[\"sts:AssumeRole\"]}]}"
}
resource "aws_redshift_cluster" "default" {
cluster_identifier = "tf-redshift-cluster-%d"
availability_zone = "us-west-2a"
database_name = "mydb"
master_username = "foo_test"
master_password = "Mustbe8characters"
node_type = "dc1.large"
automated_snapshot_retention_period = 0
allow_version_upgrade = false
iam_roles = ["${aws_iam_role.ec2-role.arn}", "${aws_iam_role.lambda-role.arn}"]
}`
var testAccAWSRedshiftClusterConfig_updateIamRoles = `
resource "aws_iam_role" "ec2-role" {
name = "test-role-ec2-%d"
path = "/"
assume_role_policy = "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"Service\":[\"ec2.amazonaws.com\"]},\"Action\":[\"sts:AssumeRole\"]}]}"
}
resource "aws_iam_role" "lambda-role" {
name = "test-role-lambda-%d"
path = "/"
assume_role_policy = "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"Service\":[\"lambda.amazonaws.com\"]},\"Action\":[\"sts:AssumeRole\"]}]}"
}
resource "aws_redshift_cluster" "default" {
cluster_identifier = "tf-redshift-cluster-%d"
availability_zone = "us-west-2a"
database_name = "mydb"
master_username = "foo_test"
master_password = "Mustbe8characters"
node_type = "dc1.large"
automated_snapshot_retention_period = 0
allow_version_upgrade = false
iam_roles = ["${aws_iam_role.ec2-role.arn}"]
}`

View File

@ -56,8 +56,10 @@ string.
* `elastic_ip` - (Optional) The Elastic IP (EIP) address for the cluster. * `elastic_ip` - (Optional) The Elastic IP (EIP) address for the cluster.
* `skip_final_snapshot` - (Optional) Determines whether a final snapshot of the cluster is created before Amazon Redshift deletes the cluster. If true , a final cluster snapshot is not created. If false , a final cluster snapshot is created before the cluster is deleted. Default is true. * `skip_final_snapshot` - (Optional) Determines whether a final snapshot of the cluster is created before Amazon Redshift deletes the cluster. If true , a final cluster snapshot is not created. If false , a final cluster snapshot is created before the cluster is deleted. Default is true.
* `final_snapshot_identifier` - (Optional) The identifier of the final snapshot that is to be created immediately before deleting the cluster. If this parameter is provided, `skip_final_snapshot` must be false. * `final_snapshot_identifier` - (Optional) The identifier of the final snapshot that is to be created immediately before deleting the cluster. If this parameter is provided, `skip_final_snapshot` must be false.
* `iam_roles` - (Optional) A list of IAM Role ARNs to associate with the cluster. A Maximum of 10 can be associated to the cluster at any time.
* `tags` - (Optional) A mapping of tags to assign to the resource. * `tags` - (Optional) A mapping of tags to assign to the resource.
## Attributes Reference ## Attributes Reference
The following attributes are exported: The following attributes are exported: