provider/aws: Convert AWS DB Instance over to awslabs/aws-sdk-go

- Remove check on password for AWS RDS Instance
- Update documentation on AWS RDS Instance regarding DB Security Groups
- Change error handling to check error code from AWS API [ci skip]
This commit is contained in:
Clint Shryock 2015-02-23 15:22:52 -06:00
parent 39e8f15752
commit d79b0d7fd1
4 changed files with 83 additions and 94 deletions

View File

@ -15,6 +15,7 @@ import (
awsGo "github.com/awslabs/aws-sdk-go/aws"
awsAutoScaling "github.com/awslabs/aws-sdk-go/gen/autoscaling"
awsRDS "github.com/awslabs/aws-sdk-go/gen/rds"
"github.com/awslabs/aws-sdk-go/gen/route53"
"github.com/awslabs/aws-sdk-go/gen/s3"
)
@ -34,6 +35,7 @@ type AWSClient struct {
r53conn *route53.Route53
region string
awsAutoScalingconn *awsAutoScaling.AutoScaling
awsRDSconn *awsRDS.RDS
}
// Client configures and returns a fully initailized AWSClient
@ -80,6 +82,8 @@ func (c *Config) Client() (interface{}, error) {
client.r53conn = route53.New(creds, "us-east-1", nil)
log.Println("[INFO] Initializing AWS Go AutoScaling connection")
client.awsAutoScalingconn = awsAutoScaling.New(creds, c.Region, nil)
log.Println("[INFO] Initializing AWS Go RDS connection")
client.awsRDSconn = awsRDS.New(creds, c.Region, nil)
}
if len(errs) > 0 {

View File

@ -3,13 +3,14 @@ package aws
import (
"fmt"
"log"
"strings"
"time"
"github.com/awslabs/aws-sdk-go/aws"
"github.com/awslabs/aws-sdk-go/gen/rds"
"github.com/hashicorp/terraform/helper/hashcode"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/helper/schema"
"github.com/mitchellh/goamz/rds"
)
func resourceAwsDbInstance() *schema.Resource {
@ -184,64 +185,60 @@ func resourceAwsDbInstance() *schema.Resource {
}
func resourceAwsDbInstanceCreate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).rdsconn
opts := rds.CreateDBInstance{
AllocatedStorage: d.Get("allocated_storage").(int),
SetAllocatedStorage: true,
DBInstanceClass: d.Get("instance_class").(string),
DBInstanceIdentifier: d.Get("identifier").(string),
DBName: d.Get("name").(string),
MasterUsername: d.Get("username").(string),
MasterUserPassword: d.Get("password").(string),
Engine: d.Get("engine").(string),
EngineVersion: d.Get("engine_version").(string),
conn := meta.(*AWSClient).awsRDSconn
opts := rds.CreateDBInstanceMessage{
AllocatedStorage: aws.Integer(d.Get("allocated_storage").(int)),
DBInstanceClass: aws.String(d.Get("instance_class").(string)),
DBInstanceIdentifier: aws.String(d.Get("identifier").(string)),
DBName: aws.String(d.Get("name").(string)),
MasterUsername: aws.String(d.Get("username").(string)),
MasterUserPassword: aws.String(d.Get("password").(string)),
Engine: aws.String(d.Get("engine").(string)),
EngineVersion: aws.String(d.Get("engine_version").(string)),
}
if attr, ok := d.GetOk("storage_type"); ok {
opts.StorageType = attr.(string)
opts.StorageType = aws.String(attr.(string))
}
if attr, ok := d.GetOk("backup_retention_period"); ok {
opts.BackupRetentionPeriod = attr.(int)
opts.SetBackupRetentionPeriod = true
opts.BackupRetentionPeriod = aws.Integer(attr.(int))
}
if attr, ok := d.GetOk("iops"); ok {
opts.Iops = attr.(int)
opts.SetIops = true
opts.IOPS = aws.Integer(attr.(int))
}
if attr, ok := d.GetOk("port"); ok {
opts.Port = attr.(int)
opts.SetPort = true
opts.Port = aws.Integer(attr.(int))
}
if attr, ok := d.GetOk("multi_az"); ok {
opts.MultiAZ = attr.(bool)
opts.MultiAZ = aws.Boolean(attr.(bool))
}
if attr, ok := d.GetOk("availability_zone"); ok {
opts.AvailabilityZone = attr.(string)
opts.AvailabilityZone = aws.String(attr.(string))
}
if attr, ok := d.GetOk("maintenance_window"); ok {
opts.PreferredMaintenanceWindow = attr.(string)
opts.PreferredMaintenanceWindow = aws.String(attr.(string))
}
if attr, ok := d.GetOk("backup_window"); ok {
opts.PreferredBackupWindow = attr.(string)
opts.PreferredBackupWindow = aws.String(attr.(string))
}
if attr, ok := d.GetOk("publicly_accessible"); ok {
opts.PubliclyAccessible = attr.(bool)
opts.PubliclyAccessible = aws.Boolean(attr.(bool))
}
if attr, ok := d.GetOk("db_subnet_group_name"); ok {
opts.DBSubnetGroupName = attr.(string)
opts.DBSubnetGroupName = aws.String(attr.(string))
}
if attr, ok := d.GetOk("parameter_group_name"); ok {
opts.DBParameterGroupName = attr.(string)
opts.DBParameterGroupName = aws.String(attr.(string))
}
if attr := d.Get("vpc_security_group_ids").(*schema.Set); attr.Len() > 0 {
@ -249,7 +246,7 @@ func resourceAwsDbInstanceCreate(d *schema.ResourceData, meta interface{}) error
for _, v := range attr.List() {
s = append(s, v.(string))
}
opts.VpcSecurityGroupIds = s
opts.VPCSecurityGroupIDs = s
}
if attr := d.Get("security_group_names").(*schema.Set); attr.Len() > 0 {
@ -257,7 +254,7 @@ func resourceAwsDbInstanceCreate(d *schema.ResourceData, meta interface{}) error
for _, v := range attr.List() {
s = append(s, v.(string))
}
opts.DBSecurityGroupNames = s
opts.DBSecurityGroups = s
}
log.Printf("[DEBUG] DB Instance create configuration: %#v", opts)
@ -302,24 +299,28 @@ func resourceAwsDbInstanceRead(d *schema.ResourceData, meta interface{}) error {
return nil
}
d.Set("name", v.DBName)
d.Set("username", v.MasterUsername)
d.Set("engine", v.Engine)
d.Set("engine_version", v.EngineVersion)
d.Set("allocated_storage", v.AllocatedStorage)
d.Set("storage_type", v.StorageType)
d.Set("instance_class", v.DBInstanceClass)
d.Set("availability_zone", v.AvailabilityZone)
d.Set("backup_retention_period", v.BackupRetentionPeriod)
d.Set("backup_window", v.PreferredBackupWindow)
d.Set("maintenance_window", v.PreferredMaintenanceWindow)
d.Set("multi_az", v.MultiAZ)
d.Set("port", v.Port)
d.Set("db_subnet_group_name", v.DBSubnetGroup.Name)
d.Set("parameter_group_name", v.DBParameterGroupName)
d.Set("address", v.Address)
d.Set("endpoint", fmt.Sprintf("%s:%d", v.Address, v.Port))
d.Set("status", v.DBInstanceStatus)
d.Set("name", *v.DBName)
d.Set("username", *v.MasterUsername)
d.Set("engine", *v.Engine)
d.Set("engine_version", *v.EngineVersion)
d.Set("allocated_storage", *v.AllocatedStorage)
d.Set("storage_type", *v.StorageType)
d.Set("instance_class", *v.DBInstanceClass)
d.Set("availability_zone", *v.AvailabilityZone)
d.Set("backup_retention_period", *v.BackupRetentionPeriod)
d.Set("backup_window", *v.PreferredBackupWindow)
d.Set("maintenance_window", *v.PreferredMaintenanceWindow)
d.Set("multi_az", *v.MultiAZ)
d.Set("port", *v.Endpoint.Port)
d.Set("db_subnet_group_name", *v.DBSubnetGroup.DBSubnetGroupName)
if len(v.DBParameterGroups) > 0 {
d.Set("parameter_group_name", *v.DBParameterGroups[0].DBParameterGroupName)
}
d.Set("address", *v.Endpoint.Port)
d.Set("endpoint", fmt.Sprintf("%s:%d", *v.Endpoint.Address, *v.Endpoint.Port))
d.Set("status", *v.DBInstanceStatus)
// Create an empty schema.Set to hold all vpc security group ids
ids := &schema.Set{
@ -327,8 +328,8 @@ func resourceAwsDbInstanceRead(d *schema.ResourceData, meta interface{}) error {
return hashcode.String(v.(string))
},
}
for _, v := range v.VpcSecurityGroupIds {
ids.Add(v)
for _, v := range v.VPCSecurityGroups {
ids.Add(*v.VPCSecurityGroupID)
}
d.Set("vpc_security_group_ids", ids)
@ -338,8 +339,8 @@ func resourceAwsDbInstanceRead(d *schema.ResourceData, meta interface{}) error {
return hashcode.String(v.(string))
},
}
for _, v := range v.DBSecurityGroupNames {
sgn.Add(v)
for _, v := range v.DBSecurityGroups {
sgn.Add(*v.DBSecurityGroupName)
}
d.Set("security_group_names", sgn)
@ -347,17 +348,17 @@ func resourceAwsDbInstanceRead(d *schema.ResourceData, meta interface{}) error {
}
func resourceAwsDbInstanceDelete(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).rdsconn
conn := meta.(*AWSClient).awsRDSconn
log.Printf("[DEBUG] DB Instance destroy: %v", d.Id())
opts := rds.DeleteDBInstance{DBInstanceIdentifier: d.Id()}
opts := rds.DeleteDBInstanceMessage{DBInstanceIdentifier: aws.String(d.Id())}
finalSnapshot := d.Get("final_snapshot_identifier").(string)
if finalSnapshot == "" {
opts.SkipFinalSnapshot = true
opts.SkipFinalSnapshot = aws.Boolean(true)
} else {
opts.FinalDBSnapshotIdentifier = finalSnapshot
opts.FinalDBSnapshotIdentifier = aws.String(finalSnapshot)
}
log.Printf("[DEBUG] DB Instance destroy configuration: %v", opts)
@ -385,10 +386,10 @@ func resourceAwsDbInstanceDelete(d *schema.ResourceData, meta interface{}) error
func resourceAwsBbInstanceRetrieve(
d *schema.ResourceData, meta interface{}) (*rds.DBInstance, error) {
conn := meta.(*AWSClient).rdsconn
conn := meta.(*AWSClient).awsRDSconn
opts := rds.DescribeDBInstances{
DBInstanceIdentifier: d.Id(),
opts := rds.DescribeDBInstancesMessage{
DBInstanceIdentifier: aws.String(d.Id()),
}
log.Printf("[DEBUG] DB Instance describe configuration: %#v", opts)
@ -396,14 +397,15 @@ func resourceAwsBbInstanceRetrieve(
resp, err := conn.DescribeDBInstances(&opts)
if err != nil {
if strings.Contains(err.Error(), "DBInstanceNotFound") {
dbinstanceerr, ok := err.(aws.APIError)
if ok && dbinstanceerr.Code == "DBInstanceNotFound" {
return nil, nil
}
return nil, fmt.Errorf("Error retrieving DB Instances: %s", err)
}
if len(resp.DBInstances) != 1 ||
resp.DBInstances[0].DBInstanceIdentifier != d.Id() {
*resp.DBInstances[0].DBInstanceIdentifier != d.Id() {
if err != nil {
return nil, nil
}
@ -428,6 +430,6 @@ func resourceAwsDbInstanceStateRefreshFunc(
return nil, "", nil
}
return v, v.DBInstanceStatus, nil
return v, *v.DBInstanceStatus, nil
}
}

View File

@ -6,7 +6,9 @@ import (
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
"github.com/mitchellh/goamz/rds"
"github.com/awslabs/aws-sdk-go/aws"
"github.com/awslabs/aws-sdk-go/gen/rds"
)
func TestAccAWSDBInstance(t *testing.T) {
@ -34,13 +36,8 @@ func TestAccAWSDBInstance(t *testing.T) {
"aws_db_instance.bar", "instance_class", "db.t1.micro"),
resource.TestCheckResourceAttr(
"aws_db_instance.bar", "name", "baz"),
resource.TestCheckResourceAttr(
// Shouldn't save password to state
"aws_db_instance.bar", "password", ""),
resource.TestCheckResourceAttr(
"aws_db_instance.bar", "username", "foo"),
resource.TestCheckResourceAttr(
"aws_db_instance.bar", "security_group_names.3322503515", "secfoobarbaz-test-terraform"),
resource.TestCheckResourceAttr(
"aws_db_instance.bar", "parameter_group_name", "default.mysql5.6"),
),
@ -50,7 +47,7 @@ func TestAccAWSDBInstance(t *testing.T) {
}
func testAccCheckAWSDBInstanceDestroy(s *terraform.State) error {
conn := testAccProvider.Meta().(*AWSClient).rdsconn
conn := testAccProvider.Meta().(*AWSClient).awsRDSconn
for _, rs := range s.RootModule().Resources {
if rs.Type != "aws_db_instance" {
@ -59,19 +56,19 @@ func testAccCheckAWSDBInstanceDestroy(s *terraform.State) error {
// Try to find the Group
resp, err := conn.DescribeDBInstances(
&rds.DescribeDBInstances{
DBInstanceIdentifier: rs.Primary.ID,
&rds.DescribeDBInstancesMessage{
DBInstanceIdentifier: aws.String(rs.Primary.ID),
})
if err == nil {
if len(resp.DBInstances) != 0 &&
resp.DBInstances[0].DBInstanceIdentifier == rs.Primary.ID {
*resp.DBInstances[0].DBInstanceIdentifier == rs.Primary.ID {
return fmt.Errorf("DB Instance still exists")
}
}
// Verify the error
newerr, ok := err.(*rds.Error)
newerr, ok := err.(*aws.APIError)
if !ok {
return err
}
@ -86,15 +83,11 @@ func testAccCheckAWSDBInstanceDestroy(s *terraform.State) error {
func testAccCheckAWSDBInstanceAttributes(v *rds.DBInstance) resource.TestCheckFunc {
return func(s *terraform.State) error {
if len(v.DBSecurityGroupNames) == 0 {
return fmt.Errorf("no sec names: %#v", v.DBSecurityGroupNames)
}
if v.Engine != "mysql" {
if *v.Engine != "mysql" {
return fmt.Errorf("bad engine: %#v", v.Engine)
}
if v.EngineVersion != "5.6.21" {
if *v.EngineVersion != "5.6.21" {
return fmt.Errorf("bad engine_version: %#v", v.EngineVersion)
}
@ -113,10 +106,10 @@ func testAccCheckAWSDBInstanceExists(n string, v *rds.DBInstance) resource.TestC
return fmt.Errorf("No DB Instance ID is set")
}
conn := testAccProvider.Meta().(*AWSClient).rdsconn
conn := testAccProvider.Meta().(*AWSClient).awsRDSconn
opts := rds.DescribeDBInstances{
DBInstanceIdentifier: rs.Primary.ID,
opts := rds.DescribeDBInstancesMessage{
DBInstanceIdentifier: aws.String(rs.Primary.ID),
}
resp, err := conn.DescribeDBInstances(&opts)
@ -126,7 +119,7 @@ func testAccCheckAWSDBInstanceExists(n string, v *rds.DBInstance) resource.TestC
}
if len(resp.DBInstances) != 1 ||
resp.DBInstances[0].DBInstanceIdentifier != rs.Primary.ID {
*resp.DBInstances[0].DBInstanceIdentifier != rs.Primary.ID {
return fmt.Errorf("DB Instance not found")
}
@ -137,15 +130,6 @@ func testAccCheckAWSDBInstanceExists(n string, v *rds.DBInstance) resource.TestC
}
const testAccAWSDBInstanceConfig = `
resource "aws_db_security_group" "bar" {
name = "secfoobarbaz-test-terraform"
description = "just cuz"
ingress {
cidr = "10.0.0.1/24"
}
}
resource "aws_db_instance" "bar" {
identifier = "foobarbaz-test-terraform"
@ -157,7 +141,6 @@ resource "aws_db_instance" "bar" {
password = "barbarbarbar"
username = "foo"
security_group_names = ["${aws_db_security_group.bar.name}"]
parameter_group_name = "default.mysql5.6"
}
`

View File

@ -22,7 +22,6 @@ resource "aws_db_instance" "default" {
name = "mydb"
username = "foo"
password = "bar"
security_group_names = ["${aws_db_security_group.bar.name}"]
db_subnet_group_name = "my_database_subnet_group"
parameter_group_name = "default.mysql5.6"
}
@ -58,7 +57,8 @@ The following arguments are supported:
* `port` - (Optional) The port on which the DB accepts connections.
* `publicly_accessible` - (Optional) Bool to control if instance is publicly accessible.
* `vpc_security_group_ids` - (Optional) List of VPC security groups to associate.
* `security_group_names` - (Optional) List of DB Security Groups to associate.
* `security_group_names` - (Optional/Deprecated) List of DB Security Groups to associate.
Only used for [DB Instances on the _EC2-Classic_ Platform](http://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_VPC.html#USER_VPC.FindDefaultVPC).
* `db_subnet_group_name` - (Optional) Name of DB subnet group
* `parameter_group_name` - (Optional) Name of the DB parameter group to associate.