Merge pull request #1595 from TimeIncOSS/aws-account-protection
aws: Allow defining blacklist/whitelist of account IDs
This commit is contained in:
commit
3176e5b44a
|
@ -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
|
||||||
|
}
|
||||||
|
|
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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.
|
||||||
|
|
Loading…
Reference in New Issue