func resourceAwsRoute53ZoneRead(d *schema.ResourceData, meta interface{}) error {
	r53 := meta.(*AWSClient).r53conn
	_, err := r53.GetHostedZone(&route53.GetHostedZoneRequest{ID: aws.String(d.Id())})
	if err != nil {
		// Handle a deleted zone
		if r53err, ok := err.(aws.APIError); ok && r53err.Code == "NoSuchHostedZone" {
			d.SetId("")
			return nil
		}
		return err
	}

	// get tags
	req := &route53.ListTagsForResourceRequest{
		ResourceID:   aws.String(d.Id()),
		ResourceType: aws.String("hostedzone"),
	}

	resp, err := r53.ListTagsForResource(req)
	if err != nil {
		return err
	}

	var tags []route53.Tag
	if resp.ResourceTagSet != nil {
		tags = resp.ResourceTagSet.Tags
	}

	if err := d.Set("tags", tagsToMapR53(tags)); err != nil {
		return err
	}

	return nil
}
func resourceAwsS3BucketCreate(d *schema.ResourceData, meta interface{}) error {
	s3conn := meta.(*AWSClient).s3conn
	awsRegion := meta.(*AWSClient).region

	// Get the bucket and acl
	bucket := d.Get("bucket").(string)
	acl := d.Get("acl").(string)

	log.Printf("[DEBUG] S3 bucket create: %s, ACL: %s", bucket, acl)

	req := &s3.CreateBucketRequest{
		Bucket: aws.String(bucket),
		ACL:    aws.String(acl),
	}

	// Special case us-east-1 region and do not set the LocationConstraint.
	// See "Request Elements: http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUT.html
	if awsRegion != "us-east-1" {
		req.CreateBucketConfiguration = &s3.CreateBucketConfiguration{
			LocationConstraint: aws.String(awsRegion),
		}
	}

	_, err := s3conn.CreateBucket(req)
	if err != nil {
		return fmt.Errorf("Error creating S3 bucket: %s", err)
	}

	// Assign the bucket name as the resource ID
	d.SetId(bucket)

	return resourceAwsS3BucketUpdate(d, meta)
}
Exemple #3
0
// setTags is a helper to set the tags for a resource. It expects the
// tags field to be named "tags"
func setTagsR53(conn *route53.Route53, d *schema.ResourceData) error {
	if d.HasChange("tags") {
		oraw, nraw := d.GetChange("tags")
		o := oraw.(map[string]interface{})
		n := nraw.(map[string]interface{})
		create, remove := diffTagsR53(tagsFromMapR53(o), tagsFromMapR53(n))

		// Set tags
		r := make([]string, len(remove))
		for i, t := range remove {
			r[i] = *t.Key
		}
		log.Printf("[DEBUG] Changing tags: \n\tadding: %#v\n\tremoving:%#v", create, remove)
		req := &route53.ChangeTagsForResourceRequest{
			AddTags:       create,
			RemoveTagKeys: r,
			ResourceID:    aws.String(d.Id()),
			ResourceType:  aws.String("hostedzone"),
		}

		_, err := conn.ChangeTagsForResource(req)
		if err != nil {
			return err
		}
	}

	return nil
}
func testAccCheckRoute53RecordDestroy(s *terraform.State) error {
	conn := testAccProvider.Meta().(*AWSClient).r53conn
	for _, rs := range s.RootModule().Resources {
		if rs.Type != "aws_route53_record" {
			continue
		}

		parts := strings.Split(rs.Primary.ID, "_")
		zone := parts[0]
		name := parts[1]
		rType := parts[2]

		lopts := &route53.ListResourceRecordSetsRequest{
			HostedZoneID:    aws.String(cleanZoneID(zone)),
			StartRecordName: aws.String(name),
			StartRecordType: aws.String(rType),
		}

		resp, err := conn.ListResourceRecordSets(lopts)
		if err != nil {
			return err
		}
		if len(resp.ResourceRecordSets) == 0 {
			return nil
		}
		rec := resp.ResourceRecordSets[0]
		if FQDN(*rec.Name) == FQDN(name) && *rec.Type == rType {
			return fmt.Errorf("Record still exists: %#v", rec)
		}
	}
	return nil
}
func resourceAwsRoute53RecordBuildSet(d *schema.ResourceData, zoneName string) (*route53.ResourceRecordSet, error) {
	recs := d.Get("records").(*schema.Set).List()
	records := make([]route53.ResourceRecord, 0, len(recs))

	typeStr := d.Get("type").(string)
	for _, r := range recs {
		switch typeStr {
		case "TXT":
			str := fmt.Sprintf("\"%s\"", r.(string))
			records = append(records, route53.ResourceRecord{Value: aws.String(str)})
		default:
			records = append(records, route53.ResourceRecord{Value: aws.String(r.(string))})
		}
	}

	// get expanded name
	en := expandRecordName(d.Get("name").(string), zoneName)

	// Create the RecordSet request with the fully expanded name, e.g.
	// sub.domain.com. Route 53 requires a fully qualified domain name, but does
	// not require the trailing ".", which it will itself, so we don't call FQDN
	// here.
	rec := &route53.ResourceRecordSet{
		Name:            aws.String(en),
		Type:            aws.String(d.Get("type").(string)),
		TTL:             aws.Long(int64(d.Get("ttl").(int))),
		ResourceRecords: records,
	}
	return rec, nil
}
func resourceAwsVpnGatewayDetach(d *schema.ResourceData, meta interface{}) error {
	ec2conn := meta.(*AWSClient).ec2conn

	// Get the old VPC ID to detach from
	vpcID, _ := d.GetChange("vpc_id")

	if vpcID.(string) == "" {
		log.Printf(
			"[DEBUG] Not detaching VPN Gateway '%s' as no VPC ID is set",
			d.Id())
		return nil
	}

	log.Printf(
		"[INFO] Detaching VPN Gateway '%s' from VPC '%s'",
		d.Id(),
		vpcID.(string))

	wait := true
	err := ec2conn.DetachVPNGateway(&ec2.DetachVPNGatewayRequest{
		VPNGatewayID: aws.String(d.Id()),
		VPCID:        aws.String(d.Get("vpc_id").(string)),
	})
	if err != nil {
		ec2err, ok := err.(aws.APIError)
		if ok {
			if ec2err.Code == "InvalidVpnGatewayID.NotFound" {
				err = nil
				wait = false
			} else if ec2err.Code == "InvalidVpnGatewayAttachment.NotFound" {
				err = nil
				wait = false
			}
		}

		if err != nil {
			return err
		}
	}

	if !wait {
		return nil
	}

	// Wait for it to be fully detached before continuing
	log.Printf("[DEBUG] Waiting for VPN gateway (%s) to detach", d.Id())
	stateConf := &resource.StateChangeConf{
		Pending: []string{"attached", "detaching", "available"},
		Target:  "detached",
		Refresh: VpnGatewayAttachStateRefreshFunc(ec2conn, d.Id(), "detached"),
		Timeout: 1 * time.Minute,
	}
	if _, err := stateConf.WaitForState(); err != nil {
		return fmt.Errorf(
			"Error waiting for vpn gateway (%s) to detach: %s",
			d.Id(), err)
	}

	return nil
}
func expandNetworkAclEntries(configured []interface{}, entryType string) ([]ec2.NetworkACLEntry, error) {
	entries := make([]ec2.NetworkACLEntry, 0, len(configured))
	for _, eRaw := range configured {
		data := eRaw.(map[string]interface{})
		protocol := data["protocol"].(string)
		_, ok := protocolIntegers()[protocol]
		if !ok {
			return nil, fmt.Errorf("Invalid Protocol %s for rule %#v", protocol, data)
		}
		p := extractProtocolInteger(data["protocol"].(string))
		e := ec2.NetworkACLEntry{
			Protocol: aws.String(strconv.Itoa(p)),
			PortRange: &ec2.PortRange{
				From: aws.Integer(data["from_port"].(int)),
				To:   aws.Integer(data["to_port"].(int)),
			},
			Egress:     aws.Boolean((entryType == "egress")),
			RuleAction: aws.String(data["action"].(string)),
			RuleNumber: aws.Integer(data["rule_no"].(int)),
			CIDRBlock:  aws.String(data["cidr_block"].(string)),
		}
		entries = append(entries, e)
	}

	return entries, nil

}
func resourceAwsRouteTableAssociationUpdate(d *schema.ResourceData, meta interface{}) error {
	ec2conn := meta.(*AWSClient).ec2conn

	log.Printf(
		"[INFO] Creating route table association: %s => %s",
		d.Get("subnet_id").(string),
		d.Get("route_table_id").(string))

	req := &ec2.ReplaceRouteTableAssociationRequest{
		AssociationID: aws.String(d.Id()),
		RouteTableID:  aws.String(d.Get("route_table_id").(string)),
	}
	resp, err := ec2conn.ReplaceRouteTableAssociation(req)

	if err != nil {
		ec2err, ok := err.(aws.APIError)
		if ok && ec2err.Code == "InvalidAssociationID.NotFound" {
			// Not found, so just create a new one
			return resourceAwsRouteTableAssociationCreate(d, meta)
		}

		return err
	}

	// Update the ID
	d.SetId(*resp.NewAssociationID)
	log.Printf("[INFO] Association ID: %s", d.Id())

	return nil
}
func resourceAwsDbParameterGroupCreate(d *schema.ResourceData, meta interface{}) error {
	rdsconn := meta.(*AWSClient).rdsconn

	createOpts := rds.CreateDBParameterGroupMessage{
		DBParameterGroupName:   aws.String(d.Get("name").(string)),
		DBParameterGroupFamily: aws.String(d.Get("family").(string)),
		Description:            aws.String(d.Get("description").(string)),
	}

	log.Printf("[DEBUG] Create DB Parameter Group: %#v", createOpts)
	_, err := rdsconn.CreateDBParameterGroup(&createOpts)
	if err != nil {
		return fmt.Errorf("Error creating DB Parameter Group: %s", err)
	}

	d.Partial(true)
	d.SetPartial("name")
	d.SetPartial("family")
	d.SetPartial("description")
	d.Partial(false)

	d.SetId(*createOpts.DBParameterGroupName)
	log.Printf("[INFO] DB Parameter Group ID: %s", d.Id())

	return resourceAwsDbParameterGroupUpdate(d, meta)
}
// Authorizes the ingress rule on the db security group
func resourceAwsDbSecurityGroupAuthorizeRule(ingress interface{}, dbSecurityGroupName string, conn *rds.RDS) error {
	ing := ingress.(map[string]interface{})

	opts := rds.AuthorizeDBSecurityGroupIngressMessage{
		DBSecurityGroupName: aws.String(dbSecurityGroupName),
	}

	if attr, ok := ing["cidr"]; ok && attr != "" {
		opts.CIDRIP = aws.String(attr.(string))
	}

	if attr, ok := ing["security_group_name"]; ok && attr != "" {
		opts.EC2SecurityGroupName = aws.String(attr.(string))
	}

	if attr, ok := ing["security_group_id"]; ok && attr != "" {
		opts.EC2SecurityGroupID = aws.String(attr.(string))
	}

	if attr, ok := ing["security_group_owner_id"]; ok && attr != "" {
		opts.EC2SecurityGroupOwnerID = aws.String(attr.(string))
	}

	log.Printf("[DEBUG] Authorize ingress rule configuration: %#v", opts)

	_, err := conn.AuthorizeDBSecurityGroupIngress(&opts)

	if err != nil {
		return fmt.Errorf("Error authorizing security group ingress: %s", err)
	}

	return nil
}
func resourceAwsDbSubnetGroupCreate(d *schema.ResourceData, meta interface{}) error {
	rdsconn := meta.(*AWSClient).rdsconn

	subnetIdsSet := d.Get("subnet_ids").(*schema.Set)
	subnetIds := make([]string, subnetIdsSet.Len())
	for i, subnetId := range subnetIdsSet.List() {
		subnetIds[i] = subnetId.(string)
	}

	createOpts := rds.CreateDBSubnetGroupMessage{
		DBSubnetGroupName:        aws.String(d.Get("name").(string)),
		DBSubnetGroupDescription: aws.String(d.Get("description").(string)),
		SubnetIDs:                subnetIds,
	}

	log.Printf("[DEBUG] Create DB Subnet Group: %#v", createOpts)
	_, err := rdsconn.CreateDBSubnetGroup(&createOpts)
	if err != nil {
		return fmt.Errorf("Error creating DB Subnet Group: %s", err)
	}

	d.SetId(*createOpts.DBSubnetGroupName)
	log.Printf("[INFO] DB Subnet Group ID: %s", d.Id())
	return resourceAwsDbSubnetGroupRead(d, meta)
}
Exemple #12
0
func resourceAwsEipUpdate(d *schema.ResourceData, meta interface{}) error {
	ec2conn := meta.(*AWSClient).ec2conn

	domain := resourceAwsEipDomain(d)

	// Only register with an instance if we have one
	if v, ok := d.GetOk("instance"); ok {
		instanceId := v.(string)

		assocOpts := &ec2.AssociateAddressRequest{
			InstanceID: aws.String(instanceId),
			PublicIP:   aws.String(d.Id()),
		}

		// more unique ID conditionals
		if domain == "vpc" {
			assocOpts = &ec2.AssociateAddressRequest{
				InstanceID:   aws.String(instanceId),
				AllocationID: aws.String(d.Id()),
				PublicIP:     aws.String(""),
			}
		}

		log.Printf("[DEBUG] EIP associate configuration: %#v (domain: %v)", assocOpts, domain)
		_, err := ec2conn.AssociateAddress(assocOpts)
		if err != nil {
			return fmt.Errorf("Failure associating instances: %s", err)
		}
	}

	return resourceAwsEipRead(d, meta)
}
func testAccCheckAWSELBAttributes(conf *elb.LoadBalancerDescription) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		zones := []string{"us-west-2a", "us-west-2b", "us-west-2c"}
		sort.StringSlice(conf.AvailabilityZones).Sort()
		if !reflect.DeepEqual(conf.AvailabilityZones, zones) {
			return fmt.Errorf("bad availability_zones")
		}

		if *conf.LoadBalancerName != "foobar-terraform-test" {
			return fmt.Errorf("bad name")
		}

		l := elb.Listener{
			InstancePort:     aws.Integer(8000),
			InstanceProtocol: aws.String("HTTP"),
			LoadBalancerPort: aws.Integer(80),
			Protocol:         aws.String("HTTP"),
		}

		if !reflect.DeepEqual(conf.ListenerDescriptions[0].Listener, &l) {
			return fmt.Errorf(
				"Got:\n\n%#v\n\nExpected:\n\n%#v\n",
				conf.ListenerDescriptions[0].Listener,
				l)
		}

		if *conf.DNSName == "" {
			return fmt.Errorf("empty dns_name")
		}

		return nil
	}
}
func testAccCheckAWSSecurityGroupAttributes(group *ec2.SecurityGroup) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		p := ec2.IPPermission{
			FromPort:   aws.Integer(80),
			ToPort:     aws.Integer(8000),
			IPProtocol: aws.String("tcp"),
			IPRanges:   []ec2.IPRange{ec2.IPRange{aws.String("10.0.0.0/8")}},
		}

		if *group.GroupName != "terraform_acceptance_test_example" {
			return fmt.Errorf("Bad name: %s", *group.GroupName)
		}

		if *group.Description != "Used in the terraform acceptance tests" {
			return fmt.Errorf("Bad description: %s", *group.Description)
		}

		if len(group.IPPermissions) == 0 {
			return fmt.Errorf("No IPPerms")
		}

		// Compare our ingress
		if !reflect.DeepEqual(group.IPPermissions[0], p) {
			return fmt.Errorf(
				"Got:\n\n%#v\n\nExpected:\n\n%#v\n",
				group.IPPermissions[0],
				p)
		}

		return nil
	}
}
Exemple #15
0
func resourceAwsEipDelete(d *schema.ResourceData, meta interface{}) error {
	ec2conn := meta.(*AWSClient).ec2conn

	if err := resourceAwsEipRead(d, meta); err != nil {
		return err
	}
	if d.Id() == "" {
		// This might happen from the read
		return nil
	}

	// If we are attached to an instance, detach first.
	if d.Get("instance").(string) != "" {
		log.Printf("[DEBUG] Disassociating EIP: %s", d.Id())
		var err error
		switch resourceAwsEipDomain(d) {
		case "vpc":
			err = ec2conn.DisassociateAddress(&ec2.DisassociateAddressRequest{
				AssociationID: aws.String(d.Get("association_id").(string)),
			})
		case "standard":
			err = ec2conn.DisassociateAddress(&ec2.DisassociateAddressRequest{
				PublicIP: aws.String(d.Get("public_ip").(string)),
			})
		}
		if err != nil {
			return err
		}
	}

	domain := resourceAwsEipDomain(d)
	return resource.Retry(3*time.Minute, func() error {
		var err error
		switch domain {
		case "vpc":
			log.Printf(
				"[DEBUG] EIP release (destroy) address allocation: %v",
				d.Id())
			err = ec2conn.ReleaseAddress(&ec2.ReleaseAddressRequest{
				AllocationID: aws.String(d.Id()),
			})
		case "standard":
			log.Printf("[DEBUG] EIP release (destroy) address: %v", d.Id())
			err = ec2conn.ReleaseAddress(&ec2.ReleaseAddressRequest{
				PublicIP: aws.String(d.Id()),
			})
		}

		if err == nil {
			return nil
		}
		if _, ok := err.(aws.APIError); !ok {
			return resource.RetryError{Err: err}
		}

		return err
	})
}
func resourceAwsAutoscalingGroupCreate(d *schema.ResourceData, meta interface{}) error {
	autoscalingconn := meta.(*AWSClient).autoscalingconn

	var autoScalingGroupOpts autoscaling.CreateAutoScalingGroupType
	autoScalingGroupOpts.AutoScalingGroupName = aws.String(d.Get("name").(string))
	autoScalingGroupOpts.LaunchConfigurationName = aws.String(d.Get("launch_configuration").(string))
	autoScalingGroupOpts.MinSize = aws.Integer(d.Get("min_size").(int))
	autoScalingGroupOpts.MaxSize = aws.Integer(d.Get("max_size").(int))
	autoScalingGroupOpts.AvailabilityZones = expandStringList(
		d.Get("availability_zones").(*schema.Set).List())

	if v, ok := d.GetOk("tag"); ok {
		autoScalingGroupOpts.Tags = autoscalingTagsFromMap(
			setToMapByKey(v.(*schema.Set), "key"), d.Get("name").(string))
	}

	if v, ok := d.GetOk("default_cooldown"); ok {
		autoScalingGroupOpts.DefaultCooldown = aws.Integer(v.(int))
	}

	if v, ok := d.GetOk("health_check_type"); ok && v.(string) != "" {
		autoScalingGroupOpts.HealthCheckType = aws.String(v.(string))
	}

	if v, ok := d.GetOk("desired_capacity"); ok {
		autoScalingGroupOpts.DesiredCapacity = aws.Integer(v.(int))
	}

	if v, ok := d.GetOk("health_check_grace_period"); ok {
		autoScalingGroupOpts.HealthCheckGracePeriod = aws.Integer(v.(int))
	}

	if v, ok := d.GetOk("load_balancers"); ok && v.(*schema.Set).Len() > 0 {
		autoScalingGroupOpts.LoadBalancerNames = expandStringList(
			v.(*schema.Set).List())
	}

	if v, ok := d.GetOk("vpc_zone_identifier"); ok && v.(*schema.Set).Len() > 0 {
		exp := expandStringList(v.(*schema.Set).List())
		autoScalingGroupOpts.VPCZoneIdentifier = aws.String(strings.Join(exp, ","))
	}

	if v, ok := d.GetOk("termination_policies"); ok && v.(*schema.Set).Len() > 0 {
		autoScalingGroupOpts.TerminationPolicies = expandStringList(
			v.(*schema.Set).List())
	}

	log.Printf("[DEBUG] AutoScaling Group create configuration: %#v", autoScalingGroupOpts)
	err := autoscalingconn.CreateAutoScalingGroup(&autoScalingGroupOpts)
	if err != nil {
		return fmt.Errorf("Error creating Autoscaling Group: %s", err)
	}

	d.SetId(d.Get("name").(string))
	log.Printf("[INFO] AutoScaling Group ID: %s", d.Id())

	return resourceAwsAutoscalingGroupRead(d, meta)
}
func resourceAwsDbSecurityGroupCreate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).rdsconn

	var err error
	var errs []error

	opts := rds.CreateDBSecurityGroupMessage{
		DBSecurityGroupName:        aws.String(d.Get("name").(string)),
		DBSecurityGroupDescription: aws.String(d.Get("description").(string)),
	}

	log.Printf("[DEBUG] DB Security Group create configuration: %#v", opts)
	_, err = conn.CreateDBSecurityGroup(&opts)
	if err != nil {
		return fmt.Errorf("Error creating DB Security Group: %s", err)
	}

	d.SetId(d.Get("name").(string))

	log.Printf("[INFO] DB Security Group ID: %s", d.Id())

	sg, err := resourceAwsDbSecurityGroupRetrieve(d, meta)
	if err != nil {
		return err
	}

	ingresses := d.Get("ingress").(*schema.Set)
	for _, ing := range ingresses.List() {
		err := resourceAwsDbSecurityGroupAuthorizeRule(ing, *sg.DBSecurityGroupName, conn)
		if err != nil {
			errs = append(errs, err)
		}
	}

	if len(errs) > 0 {
		return &multierror.Error{Errors: errs}
	}

	log.Println(
		"[INFO] Waiting for Ingress Authorizations to be authorized")

	stateConf := &resource.StateChangeConf{
		Pending: []string{"authorizing"},
		Target:  "authorized",
		Refresh: resourceAwsDbSecurityGroupStateRefreshFunc(d, meta),
		Timeout: 10 * time.Minute,
	}

	// Wait, catching any errors
	_, err = stateConf.WaitForState()
	if err != nil {
		return err
	}

	return resourceAwsDbSecurityGroupRead(d, meta)
}
func resourceAwsNetworkInterfaceUpdate(d *schema.ResourceData, meta interface{}) error {
	ec2conn := meta.(*AWSClient).ec2conn
	d.Partial(true)

	if d.HasChange("attachment") {
		ec2conn := meta.(*AWSClient).ec2conn
		oa, na := d.GetChange("attachment")

		detach_err := resourceAwsNetworkInterfaceDetach(oa.(*schema.Set), meta, d.Id())
		if detach_err != nil {
			return detach_err
		}

		// if there is a new attachment, attach it
		if na != nil && len(na.(*schema.Set).List()) > 0 {
			new_attachment := na.(*schema.Set).List()[0].(map[string]interface{})
			attach_request := &ec2.AttachNetworkInterfaceRequest{
				DeviceIndex:        aws.Integer(new_attachment["device_index"].(int)),
				InstanceID:         aws.String(new_attachment["instance"].(string)),
				NetworkInterfaceID: aws.String(d.Id()),
			}
			_, attach_err := ec2conn.AttachNetworkInterface(attach_request)
			if attach_err != nil {
				return fmt.Errorf("Error attaching ENI: %s", attach_err)
			}
		}

		d.SetPartial("attachment")
	}

	if d.HasChange("security_groups") {
		request := &ec2.ModifyNetworkInterfaceAttributeRequest{
			NetworkInterfaceID: aws.String(d.Id()),
			Groups:             expandStringList(d.Get("security_groups").(*schema.Set).List()),
		}

		err := ec2conn.ModifyNetworkInterfaceAttribute(request)
		if err != nil {
			return fmt.Errorf("Failure updating ENI: %s", err)
		}

		d.SetPartial("security_groups")
	}

	if err := setTags(ec2conn, d); err != nil {
		return err
	} else {
		d.SetPartial("tags")
	}

	d.Partial(false)

	return resourceAwsNetworkInterfaceRead(d, meta)
}
Exemple #19
0
// tagsFromMap returns the tags for the given map of data.
func tagsFromMapELB(m map[string]interface{}) []elb.Tag {
	result := make([]elb.Tag, 0, len(m))
	for k, v := range m {
		result = append(result, elb.Tag{
			Key:   aws.String(k),
			Value: aws.String(v.(string)),
		})
	}

	return result
}
func updateNetworkAclEntries(d *schema.ResourceData, entryType string, ec2conn *ec2.EC2) error {

	o, n := d.GetChange(entryType)

	if o == nil {
		o = new(schema.Set)
	}
	if n == nil {
		n = new(schema.Set)
	}

	os := o.(*schema.Set)
	ns := n.(*schema.Set)

	toBeDeleted, err := expandNetworkAclEntries(os.Difference(ns).List(), entryType)
	if err != nil {
		return err
	}
	for _, remove := range toBeDeleted {
		// Delete old Acl
		err := ec2conn.DeleteNetworkACLEntry(&ec2.DeleteNetworkACLEntryRequest{
			NetworkACLID: aws.String(d.Id()),
			RuleNumber:   remove.RuleNumber,
			Egress:       remove.Egress,
		})
		if err != nil {
			return fmt.Errorf("Error deleting %s entry: %s", entryType, err)
		}
	}

	toBeCreated, err := expandNetworkAclEntries(ns.Difference(os).List(), entryType)
	if err != nil {
		return err
	}
	for _, add := range toBeCreated {
		// Add new Acl entry
		err := ec2conn.CreateNetworkACLEntry(&ec2.CreateNetworkACLEntryRequest{
			NetworkACLID: aws.String(d.Id()),
			CIDRBlock:    add.CIDRBlock,
			Egress:       add.Egress,
			PortRange:    add.PortRange,
			Protocol:     add.Protocol,
			RuleAction:   add.RuleAction,
			RuleNumber:   add.RuleNumber,
		})
		if err != nil {
			return fmt.Errorf("Error creating %s entry: %s", entryType, err)
		}
	}
	return nil
}
Exemple #21
0
// setTags is a helper to set the tags for a resource. It expects the
// tags field to be named "tags"
func setTagsS3(conn *s3.S3, d *schema.ResourceData) error {
	if d.HasChange("tags") {
		oraw, nraw := d.GetChange("tags")
		o := oraw.(map[string]interface{})
		n := nraw.(map[string]interface{})
		create, remove := diffTagsS3(tagsFromMapS3(o), tagsFromMapS3(n))

		// Set tags
		if len(remove) > 0 {
			log.Printf("[DEBUG] Removing tags: %#v", remove)
			err := conn.DeleteBucketTagging(&s3.DeleteBucketTaggingRequest{
				Bucket: aws.String(d.Get("bucket").(string)),
			})
			if err != nil {
				return err
			}
		}
		if len(create) > 0 {
			log.Printf("[DEBUG] Creating tags: %#v", create)
			tagging := s3.Tagging{
				TagSet: create,
				XMLName: xml.Name{
					Space: "http://s3.amazonaws.com/doc/2006-03-01/",
					Local: "Tagging",
				},
			}
			// AWS S3 API requires us to send a base64 encoded md5 hash of the
			// content, which we need to build ourselves since aws-sdk-go does not.
			b, err := xml.Marshal(tagging)
			if err != nil {
				return err
			}
			h := md5.New()
			h.Write(b)
			base := base64.StdEncoding.EncodeToString(h.Sum(nil))

			req := &s3.PutBucketTaggingRequest{
				Bucket:     aws.String(d.Get("bucket").(string)),
				ContentMD5: aws.String(base),
				Tagging:    &tagging,
			}

			err = conn.PutBucketTagging(req)
			if err != nil {
				return err
			}
		}
	}

	return nil
}
// tagsFromMap returns the tags for the given map of data.
func autoscalingTagsFromMap(m map[string]interface{}, resourceID string) []autoscaling.Tag {
	result := make([]autoscaling.Tag, 0, len(m))
	for k, v := range m {
		attr := v.(map[string]interface{})
		result = append(result, autoscaling.Tag{
			Key:               aws.String(k),
			Value:             aws.String(attr["value"].(string)),
			PropagateAtLaunch: aws.Boolean(attr["propagate_at_launch"].(bool)),
			ResourceID:        aws.String(resourceID),
			ResourceType:      aws.String("auto-scaling-group"),
		})
	}

	return result
}
func resourceAwsRoute53RecordRead(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).r53conn

	zone := d.Get("zone_id").(string)

	// get expanded name
	zoneRecord, err := conn.GetHostedZone(&route53.GetHostedZoneRequest{ID: aws.String(zone)})
	if err != nil {
		return err
	}
	en := expandRecordName(d.Get("name").(string), *zoneRecord.HostedZone.Name)

	lopts := &route53.ListResourceRecordSetsRequest{
		HostedZoneID:    aws.String(cleanZoneID(zone)),
		StartRecordName: aws.String(en),
		StartRecordType: aws.String(d.Get("type").(string)),
	}

	resp, err := conn.ListResourceRecordSets(lopts)
	if err != nil {
		return err
	}

	// Scan for a matching record
	found := false
	for _, record := range resp.ResourceRecordSets {
		name := cleanRecordName(*record.Name)
		if FQDN(name) != FQDN(*lopts.StartRecordName) {
			continue
		}
		if strings.ToUpper(*record.Type) != strings.ToUpper(*lopts.StartRecordType) {
			continue
		}

		found = true

		d.Set("records", record.ResourceRecords)
		d.Set("ttl", record.TTL)

		break
	}

	if !found {
		d.SetId("")
	}

	return nil
}
func resourceAwsDbSubnetGroupRead(d *schema.ResourceData, meta interface{}) error {
	rdsconn := meta.(*AWSClient).rdsconn

	describeOpts := rds.DescribeDBSubnetGroupsMessage{
		DBSubnetGroupName: aws.String(d.Id()),
	}

	describeResp, err := rdsconn.DescribeDBSubnetGroups(&describeOpts)
	if err != nil {
		if ec2err, ok := err.(aws.APIError); ok && ec2err.Code == "DBSubnetGroupNotFoundFault" {
			// Update state to indicate the db subnet no longer exists.
			d.SetId("")
			return nil
		}
		return err
	}

	if len(describeResp.DBSubnetGroups) != 1 ||
		*describeResp.DBSubnetGroups[0].DBSubnetGroupName != d.Id() {
		return fmt.Errorf("Unable to find DB Subnet Group: %#v", describeResp.DBSubnetGroups)
	}

	subnetGroup := describeResp.DBSubnetGroups[0]

	d.Set("name", *subnetGroup.DBSubnetGroupName)
	d.Set("description", *subnetGroup.DBSubnetGroupDescription)

	subnets := make([]string, 0, len(subnetGroup.Subnets))
	for _, s := range subnetGroup.Subnets {
		subnets = append(subnets, *s.SubnetIdentifier)
	}
	d.Set("subnet_ids", subnets)

	return nil
}
func resourceAwsDbSubnetGroupDeleteRefreshFunc(
	d *schema.ResourceData,
	meta interface{}) resource.StateRefreshFunc {
	rdsconn := meta.(*AWSClient).rdsconn

	return func() (interface{}, string, error) {

		deleteOpts := rds.DeleteDBSubnetGroupMessage{
			DBSubnetGroupName: aws.String(d.Id()),
		}

		if err := rdsconn.DeleteDBSubnetGroup(&deleteOpts); err != nil {
			rdserr, ok := err.(aws.APIError)
			if !ok {
				return d, "error", err
			}

			if rdserr.Code != "DBSubnetGroupNotFoundFault" {
				return d, "error", err
			}
		}

		return d, "destroyed", nil
	}
}
func resourceAwsNetworkInterfaceDetach(oa *schema.Set, meta interface{}, eniId string) error {
	// if there was an old attachment, remove it
	if oa != nil && len(oa.List()) > 0 {
		old_attachment := oa.List()[0].(map[string]interface{})
		detach_request := &ec2.DetachNetworkInterfaceRequest{
			AttachmentID: aws.String(old_attachment["attachment_id"].(string)),
			Force:        aws.Boolean(true),
		}
		ec2conn := meta.(*AWSClient).ec2conn
		detach_err := ec2conn.DetachNetworkInterface(detach_request)
		if detach_err != nil {
			return fmt.Errorf("Error detaching ENI: %s", detach_err)
		}

		log.Printf("[DEBUG] Waiting for ENI (%s) to become dettached", eniId)
		stateConf := &resource.StateChangeConf{
			Pending: []string{"true"},
			Target:  "false",
			Refresh: networkInterfaceAttachmentRefreshFunc(ec2conn, eniId),
			Timeout: 10 * time.Minute,
		}
		if _, err := stateConf.WaitForState(); err != nil {
			return fmt.Errorf(
				"Error waiting for ENI (%s) to become dettached: %s", eniId, err)
		}
	}

	return nil
}
func testAccCheckAWSDBSecurityGroupExists(n string, v *rds.DBSecurityGroup) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		rs, ok := s.RootModule().Resources[n]
		if !ok {
			return fmt.Errorf("Not found: %s", n)
		}

		if rs.Primary.ID == "" {
			return fmt.Errorf("No DB Security Group ID is set")
		}

		conn := testAccProvider.Meta().(*AWSClient).rdsconn

		opts := rds.DescribeDBSecurityGroupsMessage{
			DBSecurityGroupName: aws.String(rs.Primary.ID),
		}

		resp, err := conn.DescribeDBSecurityGroups(&opts)

		if err != nil {
			return err
		}

		if len(resp.DBSecurityGroups) != 1 ||
			*resp.DBSecurityGroups[0].DBSecurityGroupName != rs.Primary.ID {
			return fmt.Errorf("DB Security Group not found")
		}

		*v = resp.DBSecurityGroups[0]

		return nil
	}
}
func resourceAwsVpnGatewayDelete(d *schema.ResourceData, meta interface{}) error {
	ec2conn := meta.(*AWSClient).ec2conn

	// Detach if it is attached
	if err := resourceAwsVpnGatewayDetach(d, meta); err != nil {
		return err
	}

	log.Printf("[INFO] Deleting VPN gateway: %s", d.Id())

	return resource.Retry(5*time.Minute, func() error {
		err := ec2conn.DeleteVPNGateway(&ec2.DeleteVPNGatewayRequest{
			VPNGatewayID: aws.String(d.Id()),
		})
		if err == nil {
			return nil
		}

		ec2err, ok := err.(aws.APIError)
		if !ok {
			return err
		}

		switch ec2err.Code {
		case "InvalidVpnGatewayID.NotFound":
			return nil
		case "IncorrectState":
			return err // retry
		}

		return resource.RetryError{Err: err}
	})
}
func testAccCheckAWSELBAttributesHealthCheck(conf *elb.LoadBalancerDescription) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		zones := []string{"us-west-2a", "us-west-2b", "us-west-2c"}
		sort.StringSlice(conf.AvailabilityZones).Sort()
		if !reflect.DeepEqual(conf.AvailabilityZones, zones) {
			return fmt.Errorf("bad availability_zones")
		}

		if *conf.LoadBalancerName != "foobar-terraform-test" {
			return fmt.Errorf("bad name")
		}

		check := elb.HealthCheck{
			Timeout:            aws.Integer(30),
			UnhealthyThreshold: aws.Integer(5),
			HealthyThreshold:   aws.Integer(5),
			Interval:           aws.Integer(60),
			Target:             aws.String("HTTP:8000/"),
		}

		if !reflect.DeepEqual(conf.HealthCheck, &check) {
			return fmt.Errorf(
				"Got:\n\n%#v\n\nExpected:\n\n%#v\n",
				conf.HealthCheck,
				check)
		}

		if *conf.DNSName == "" {
			return fmt.Errorf("empty dns_name")
		}

		return nil
	}
}
func testAccCheckAWSDBSecurityGroupDestroy(s *terraform.State) error {
	conn := testAccProvider.Meta().(*AWSClient).rdsconn

	for _, rs := range s.RootModule().Resources {
		if rs.Type != "aws_db_security_group" {
			continue
		}

		// Try to find the Group
		resp, err := conn.DescribeDBSecurityGroups(
			&rds.DescribeDBSecurityGroupsMessage{
				DBSecurityGroupName: aws.String(rs.Primary.ID),
			})

		if err == nil {
			if len(resp.DBSecurityGroups) != 0 &&
				*resp.DBSecurityGroups[0].DBSecurityGroupName == rs.Primary.ID {
				return fmt.Errorf("DB Security Group still exists")
			}
		}

		// Verify the error
		newerr, ok := err.(aws.APIError)
		if !ok {
			return err
		}
		if newerr.Code != "InvalidDBSecurityGroup.NotFound" {
			return err
		}
	}

	return nil
}