Skip to content

Commit

Permalink
provider/aws: Add support to aws_redshift_cluster for iam_roles
Browse files Browse the repository at this point in the history
  • Loading branch information
stack72 committed May 18, 2016
1 parent 54df833 commit 415502a
Show file tree
Hide file tree
Showing 3 changed files with 144 additions and 2 deletions.
52 changes: 52 additions & 0 deletions builtin/providers/aws/resource_aws_redshift_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,14 @@ func resourceAwsRedshiftCluster() *schema.Resource {
Optional: true,
Computed: true,
},

"iam_roles": &schema.Schema{
Type: schema.TypeSet,
Optional: true,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
Set: schema.HashString,
},
},
}
}
Expand Down Expand Up @@ -259,6 +267,10 @@ func resourceAwsRedshiftClusterCreate(d *schema.ResourceData, meta interface{})
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)
resp, err := conn.CreateCluster(createOpts)
if err != nil {
Expand Down Expand Up @@ -355,6 +367,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)
}

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_revision_number", rsc.ClusterRevisionNumber)

Expand Down Expand Up @@ -444,6 +464,38 @@ func resourceAwsRedshiftClusterUpdate(d *schema.ResourceData, meta interface{})
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")
}

return resourceAwsRedshiftClusterRead(d, meta)
}

Expand Down
91 changes: 91 additions & 0 deletions builtin/providers/aws/resource_aws_redshift_cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
var v redshift.Cluster

Expand Down Expand Up @@ -339,6 +372,64 @@ resource "aws_redshift_cluster" "default" {
allow_version_upgrade = false
}`

var testAccAWSRedshiftClusterConfig_iamRoles = `
provider "aws" {
region = "us-west-2"
}
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 = `
provider "aws" {
region = "us-west-2"
}
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}"]
}`

var testAccAWSRedshiftClusterConfig_notPubliclyAccessible = `
provider "aws" {
region = "us-west-2"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ string.
* `kms_key_id` - (Optional) The KMS key ID 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.
* `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.

## Attributes Reference

Expand All @@ -79,4 +79,3 @@ The following attributes are exported:
* `cluster_subnet_group_name` - The name of a cluster subnet group to be associated with this cluster
* `cluster_public_key` - The public key for the cluster
* `cluster_revision_number` - The specific revision number of the database in the cluster

0 comments on commit 415502a

Please sign in to comment.