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