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