Merge pull request #1595 from TimeIncOSS/aws-account-protection

aws: Allow defining blacklist/whitelist of account IDs
This commit is contained in:
Mitchell Hashimoto 2015-04-22 08:08:01 +02:00
commit 3176e5b44a
4 changed files with 86 additions and 0 deletions

View File

@ -3,6 +3,7 @@ package aws
import ( import (
"fmt" "fmt"
"log" "log"
"strings"
"github.com/hashicorp/terraform/helper/multierror" "github.com/hashicorp/terraform/helper/multierror"
@ -21,6 +22,9 @@ type Config struct {
SecretKey string SecretKey string
Token string Token string
Region string Region string
AllowedAccountIds []interface{}
ForbiddenAccountIds []interface{}
} }
type AWSClient struct { type AWSClient struct {
@ -71,6 +75,12 @@ func (c *Config) Client() (interface{}, error) {
log.Println("[INFO] Initializing IAM Connection") log.Println("[INFO] Initializing IAM Connection")
client.iamconn = iam.New(awsConfig) client.iamconn = iam.New(awsConfig)
err := c.ValidateAccountId(client.iamconn)
if err != nil {
errs = append(errs, err)
}
log.Println("[INFO] Initializing AutoScaling connection") log.Println("[INFO] Initializing AutoScaling connection")
client.autoscalingconn = autoscaling.New(awsConfig) client.autoscalingconn = autoscaling.New(awsConfig)
@ -109,3 +119,37 @@ func (c *Config) ValidateRegion() error {
} }
return fmt.Errorf("Not a valid region: %s", c.Region) return fmt.Errorf("Not a valid region: %s", c.Region)
} }
func (c *Config) ValidateAccountId(iamconn *iam.IAM) error {
if c.AllowedAccountIds == nil && c.ForbiddenAccountIds == nil {
return nil
}
log.Printf("[INFO] Validating account ID")
out, err := iamconn.GetUser(nil)
if err != nil {
return fmt.Errorf("Failed getting account ID from IAM: %s", err)
}
account_id := strings.Split(*out.User.ARN, ":")[4]
if c.ForbiddenAccountIds != nil {
for _, id := range c.ForbiddenAccountIds {
if id == account_id {
return fmt.Errorf("Forbidden account ID (%s)", id)
}
}
}
if c.AllowedAccountIds != nil {
for _, id := range c.AllowedAccountIds {
if id == account_id {
return nil
}
}
return fmt.Errorf("Account ID not allowed (%s)", account_id)
}
return nil
}

View File

@ -1,6 +1,7 @@
package aws package aws
import ( import (
"github.com/hashicorp/terraform/helper/hashcode"
"github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/terraform" "github.com/hashicorp/terraform/terraform"
) )
@ -51,6 +52,26 @@ func Provider() terraform.ResourceProvider {
Description: descriptions["region"], Description: descriptions["region"],
InputDefault: "us-east-1", InputDefault: "us-east-1",
}, },
"allowed_account_ids": &schema.Schema{
Type: schema.TypeSet,
Elem: &schema.Schema{Type: schema.TypeString},
Optional: true,
ConflictsWith: []string{"forbidden_account_ids"},
Set: func(v interface{}) int {
return hashcode.String(v.(string))
},
},
"forbidden_account_ids": &schema.Schema{
Type: schema.TypeSet,
Elem: &schema.Schema{Type: schema.TypeString},
Optional: true,
ConflictsWith: []string{"allowed_account_ids"},
Set: func(v interface{}) int {
return hashcode.String(v.(string))
},
},
}, },
ResourcesMap: map[string]*schema.Resource{ ResourcesMap: map[string]*schema.Resource{
@ -110,5 +131,13 @@ func providerConfigure(d *schema.ResourceData) (interface{}, error) {
Region: d.Get("region").(string), Region: d.Get("region").(string),
} }
if v, ok := d.GetOk("allowed_account_ids"); ok {
config.AllowedAccountIds = v.(*schema.Set).List()
}
if v, ok := d.GetOk("forbidden_account_ids"); ok {
config.ForbiddenAccountIds = v.(*schema.Set).List()
}
return config.Client() return config.Client()
} }

View File

@ -384,6 +384,8 @@ func (m schemaMap) Input(
fallthrough fallthrough
case TypeFloat: case TypeFloat:
fallthrough fallthrough
case TypeSet:
continue
case TypeString: case TypeString:
value, err = m.inputString(input, k, v) value, err = m.inputString(input, k, v)
default: default:

View File

@ -22,6 +22,9 @@ provider "aws" {
access_key = "${var.aws_access_key}" access_key = "${var.aws_access_key}"
secret_key = "${var.aws_secret_key}" secret_key = "${var.aws_secret_key}"
region = "us-east-1" region = "us-east-1"
# Not run this in live account
forbidden_account_ids = ["1234567890"]
} }
# Create a web server # Create a web server
@ -43,5 +46,13 @@ The following arguments are supported in the `provider` block:
* `region` - (Required) This is the AWS region. It must be provided, but * `region` - (Required) This is the AWS region. It must be provided, but
it can also be sourced from the `AWS_DEFAULT_REGION` environment variables. it can also be sourced from the `AWS_DEFAULT_REGION` environment variables.
* `allowed_account_ids` - (Optional) List of allowed AWS account IDs (whitelist)
to prevent you mistakenly using a wrong one (and end up destroying live environment).
Conflicts with `forbidden_account_ids`.
* `forbidden_account_ids` - (Optional) List of forbidden AWS account IDs (blacklist)
to prevent you mistakenly using a wrong one (and end up destroying live environment).
Conflicts with `allowed_account_ids`.
In addition to the above parameters, the `AWS_SECURITY_TOKEN` environmental In addition to the above parameters, the `AWS_SECURITY_TOKEN` environmental
variable can be set to set an MFA token. variable can be set to set an MFA token.