github.com/danp/terraform@v0.9.5-0.20170426144147-39d740081351/builtin/providers/aws/resource_aws_kms_alias.go (about)

     1  package aws
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"regexp"
     7  
     8  	"github.com/hashicorp/terraform/helper/resource"
     9  	"github.com/hashicorp/terraform/helper/schema"
    10  
    11  	"github.com/aws/aws-sdk-go/aws"
    12  	"github.com/aws/aws-sdk-go/service/kms"
    13  )
    14  
    15  func resourceAwsKmsAlias() *schema.Resource {
    16  	return &schema.Resource{
    17  		Create: resourceAwsKmsAliasCreate,
    18  		Read:   resourceAwsKmsAliasRead,
    19  		Update: resourceAwsKmsAliasUpdate,
    20  		Delete: resourceAwsKmsAliasDelete,
    21  
    22  		Schema: map[string]*schema.Schema{
    23  			"arn": &schema.Schema{
    24  				Type:     schema.TypeString,
    25  				Computed: true,
    26  			},
    27  			"name": &schema.Schema{
    28  				Type:          schema.TypeString,
    29  				Optional:      true,
    30  				ForceNew:      true,
    31  				ConflictsWith: []string{"name_prefix"},
    32  				ValidateFunc:  validateAwsKmsName,
    33  			},
    34  			"name_prefix": &schema.Schema{
    35  				Type:     schema.TypeString,
    36  				Optional: true,
    37  				ForceNew: true,
    38  				ValidateFunc: func(v interface{}, k string) (ws []string, es []error) {
    39  					value := v.(string)
    40  					if !regexp.MustCompile(`^(alias\/)[a-zA-Z0-9:/_-]+$`).MatchString(value) {
    41  						es = append(es, fmt.Errorf(
    42  							"%q must begin with 'alias/' and be comprised of only [a-zA-Z0-9:/_-]", k))
    43  					}
    44  					return
    45  				},
    46  			},
    47  			"target_key_id": &schema.Schema{
    48  				Type:     schema.TypeString,
    49  				Required: true,
    50  			},
    51  		},
    52  	}
    53  }
    54  
    55  func resourceAwsKmsAliasCreate(d *schema.ResourceData, meta interface{}) error {
    56  	conn := meta.(*AWSClient).kmsconn
    57  
    58  	var name string
    59  	if v, ok := d.GetOk("name"); ok {
    60  		name = v.(string)
    61  	} else if v, ok := d.GetOk("name_prefix"); ok {
    62  		name = resource.PrefixedUniqueId(v.(string))
    63  	} else {
    64  		name = resource.PrefixedUniqueId("alias/")
    65  	}
    66  
    67  	targetKeyId := d.Get("target_key_id").(string)
    68  
    69  	log.Printf("[DEBUG] KMS alias create name: %s, target_key: %s", name, targetKeyId)
    70  
    71  	req := &kms.CreateAliasInput{
    72  		AliasName:   aws.String(name),
    73  		TargetKeyId: aws.String(targetKeyId),
    74  	}
    75  	_, err := conn.CreateAlias(req)
    76  	if err != nil {
    77  		return err
    78  	}
    79  	d.SetId(name)
    80  	return resourceAwsKmsAliasRead(d, meta)
    81  }
    82  
    83  func resourceAwsKmsAliasRead(d *schema.ResourceData, meta interface{}) error {
    84  	conn := meta.(*AWSClient).kmsconn
    85  
    86  	alias, err := findKmsAliasByName(conn, d.Id(), nil)
    87  	if err != nil {
    88  		return err
    89  	}
    90  	if alias == nil {
    91  		log.Printf("[DEBUG] Removing KMS Alias (%s) as it's already gone", d.Id())
    92  		d.SetId("")
    93  		return nil
    94  	}
    95  
    96  	log.Printf("[DEBUG] Found KMS Alias: %s", alias)
    97  
    98  	d.Set("arn", alias.AliasArn)
    99  	d.Set("target_key_id", alias.TargetKeyId)
   100  
   101  	return nil
   102  }
   103  
   104  func resourceAwsKmsAliasUpdate(d *schema.ResourceData, meta interface{}) error {
   105  	conn := meta.(*AWSClient).kmsconn
   106  
   107  	if d.HasChange("target_key_id") {
   108  		err := resourceAwsKmsAliasTargetUpdate(conn, d)
   109  		if err != nil {
   110  			return err
   111  		}
   112  	}
   113  	return nil
   114  }
   115  
   116  func resourceAwsKmsAliasTargetUpdate(conn *kms.KMS, d *schema.ResourceData) error {
   117  	name := d.Get("name").(string)
   118  	targetKeyId := d.Get("target_key_id").(string)
   119  
   120  	log.Printf("[DEBUG] KMS alias: %s, update target: %s", name, targetKeyId)
   121  
   122  	req := &kms.UpdateAliasInput{
   123  		AliasName:   aws.String(name),
   124  		TargetKeyId: aws.String(targetKeyId),
   125  	}
   126  	_, err := conn.UpdateAlias(req)
   127  
   128  	return err
   129  }
   130  
   131  func resourceAwsKmsAliasDelete(d *schema.ResourceData, meta interface{}) error {
   132  	conn := meta.(*AWSClient).kmsconn
   133  
   134  	req := &kms.DeleteAliasInput{
   135  		AliasName: aws.String(d.Id()),
   136  	}
   137  	_, err := conn.DeleteAlias(req)
   138  	if err != nil {
   139  		return err
   140  	}
   141  
   142  	log.Printf("[DEBUG] KMS Alias: (%s) deleted.", d.Id())
   143  	d.SetId("")
   144  	return nil
   145  }
   146  
   147  // API by default limits results to 50 aliases
   148  // This is how we make sure we won't miss any alias
   149  // See http://docs.aws.amazon.com/kms/latest/APIReference/API_ListAliases.html
   150  func findKmsAliasByName(conn *kms.KMS, name string, marker *string) (*kms.AliasListEntry, error) {
   151  	req := kms.ListAliasesInput{
   152  		Limit: aws.Int64(int64(100)),
   153  	}
   154  	if marker != nil {
   155  		req.Marker = marker
   156  	}
   157  
   158  	log.Printf("[DEBUG] Listing KMS aliases: %s", req)
   159  	resp, err := conn.ListAliases(&req)
   160  	if err != nil {
   161  		return nil, err
   162  	}
   163  
   164  	for _, entry := range resp.Aliases {
   165  		if *entry.AliasName == name {
   166  			return entry, nil
   167  		}
   168  	}
   169  	if *resp.Truncated {
   170  		log.Printf("[DEBUG] KMS alias list is truncated, listing more via %s", *resp.NextMarker)
   171  		return findKmsAliasByName(conn, name, resp.NextMarker)
   172  	}
   173  
   174  	return nil, nil
   175  }