Merge branch 'master' into dynamodb-local
This commit is contained in:
commit
28bef7c0c7
37
CHANGELOG.md
37
CHANGELOG.md
|
@ -1,4 +1,39 @@
|
|||
## 0.6.1 (Unreleased)
|
||||
## 0.6.2 (Unreleased)
|
||||
|
||||
FEATURES:
|
||||
|
||||
* **New resource: `google_compute_instance_group_manager`** [GH-2868]
|
||||
* **New resource: `google_compute_autoscaler`** [GH-2868]
|
||||
|
||||
IMPROVEMENTS:
|
||||
|
||||
* core: Add resource IDs to errors coming from `apply`/`refresh` [GH-2815]
|
||||
* provider/aws: Validate credentials before walking the graph [GH-2730]
|
||||
* provider/aws: Added website_domain for S3 buckets [GH-2210]
|
||||
* provider/aws: ELB names are now optional, and generated by Terraform if omitted [GH-2571]
|
||||
* provider/aws: Downcase RDS engine names to prevent continuous diffs [GH-2745]
|
||||
* provider/aws: Added `source_dest_check` attribute to the aws_network_interface [GH-2741]
|
||||
* provider/aws: Clean up externally removed Launch Configurations [GH-2806]
|
||||
* provider/aws: Compute private ip addresses of ENIs if they are not specified [GH-2743]
|
||||
* provider/azure: Provide a simpler error when using a Platform Image without a
|
||||
Storage Service [GH-2861]
|
||||
* provider/google: `account_file` is now expected to be JSON. Paths are still supported for
|
||||
backwards compatibility. [GH-2839]
|
||||
|
||||
BUG FIXES:
|
||||
|
||||
* core: Prevent error duplication in `apply` [GH-2815]
|
||||
* core: Fix crash when a provider validation adds a warning [GH-2878]
|
||||
* provider/aws: Fix issue with toggling monitoring in AWS Instances [GH-2794]
|
||||
* provider/aws: Fix issue with Spot Instance Requests and cancellation [GH-2805]
|
||||
* provider/aws: Fix issue with checking for ElastiCache cluster cache node status [GH-2842]
|
||||
* provider/aws: Fix issue when unable to find a Root Block Device name of an Instance Backed
|
||||
AMI [GH-2646]
|
||||
* provider/dnsimple: Domain and type should force new records [GH-2777]
|
||||
* provider/aws: Fix issue with IAM Server Certificates and Chains [GH-2871]
|
||||
* provider/aws: Fix issue with IAM Server Certificates when using `path` [GH-2871]
|
||||
|
||||
## 0.6.1 (July 20, 2015)
|
||||
|
||||
FEATURES:
|
||||
|
||||
|
|
|
@ -51,9 +51,13 @@ git tag -m "${VERSION}" "${VERSION}"
|
|||
# Build the release
|
||||
make release
|
||||
|
||||
# Add Godeps for the archive
|
||||
git add Godeps
|
||||
|
||||
# Make an archive with vendored dependencies
|
||||
stashName=$(git stash)
|
||||
stashName=$(git stash create)
|
||||
git archive -o terraform-$VERSION-src.tar.gz $stashName
|
||||
git reset --hard ${VERSION}
|
||||
|
||||
# Zip and push release to bintray
|
||||
export BINTRAY_API_KEY="..."
|
||||
|
|
|
@ -42,6 +42,7 @@ SCRIPT
|
|||
|
||||
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
|
||||
config.vm.box = "chef/ubuntu-12.04"
|
||||
config.vm.hostname = "terraform"
|
||||
|
||||
config.vm.provision "shell", inline: $script, privileged: false
|
||||
config.vm.synced_folder '.', '/opt/gopath/src/github.com/hashicorp/terraform'
|
||||
|
|
|
@ -122,7 +122,7 @@ func autoscalingTagsFromMap(m map[string]interface{}, resourceID string) []*auto
|
|||
result = append(result, &autoscaling.Tag{
|
||||
Key: aws.String(k),
|
||||
Value: aws.String(attr["value"].(string)),
|
||||
PropagateAtLaunch: aws.Boolean(attr["propagate_at_launch"].(bool)),
|
||||
PropagateAtLaunch: aws.Bool(attr["propagate_at_launch"].(bool)),
|
||||
ResourceID: aws.String(resourceID),
|
||||
ResourceType: aws.String("auto-scaling-group"),
|
||||
})
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"github.com/hashicorp/terraform/helper/multierror"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||
"github.com/aws/aws-sdk-go/service/autoscaling"
|
||||
"github.com/aws/aws-sdk-go/service/cloudwatch"
|
||||
|
@ -83,8 +84,16 @@ func (c *Config) Client() (interface{}, error) {
|
|||
creds := credentials.NewStaticCredentials(c.AccessKey, c.SecretKey, c.Token)
|
||||
awsConfig := &aws.Config{
|
||||
Credentials: creds,
|
||||
Region: c.Region,
|
||||
MaxRetries: c.MaxRetries,
|
||||
Region: aws.String(c.Region),
|
||||
MaxRetries: aws.Int(c.MaxRetries),
|
||||
}
|
||||
|
||||
log.Println("[INFO] Initializing IAM Connection")
|
||||
client.iamconn = iam.New(awsConfig)
|
||||
|
||||
err := c.ValidateCredentials(client.iamconn)
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
awsDynamoDBConfig := &aws.Config{
|
||||
Credentials: creds,
|
||||
|
@ -111,15 +120,12 @@ func (c *Config) Client() (interface{}, error) {
|
|||
log.Println("[INFO] Initializing RDS Connection")
|
||||
client.rdsconn = rds.New(awsConfig)
|
||||
|
||||
log.Println("[INFO] Initializing IAM Connection")
|
||||
client.iamconn = iam.New(awsConfig)
|
||||
|
||||
log.Println("[INFO] Initializing Kinesis Connection")
|
||||
client.kinesisconn = kinesis.New(awsConfig)
|
||||
|
||||
err := c.ValidateAccountId(client.iamconn)
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
authErr := c.ValidateAccountId(client.iamconn)
|
||||
if authErr != nil {
|
||||
errs = append(errs, authErr)
|
||||
}
|
||||
|
||||
log.Println("[INFO] Initializing AutoScaling connection")
|
||||
|
@ -137,8 +143,8 @@ func (c *Config) Client() (interface{}, error) {
|
|||
log.Println("[INFO] Initializing Route 53 connection")
|
||||
client.r53conn = route53.New(&aws.Config{
|
||||
Credentials: creds,
|
||||
Region: "us-east-1",
|
||||
MaxRetries: c.MaxRetries,
|
||||
Region: aws.String("us-east-1"),
|
||||
MaxRetries: aws.Int(c.MaxRetries),
|
||||
})
|
||||
|
||||
log.Println("[INFO] Initializing Elasticache Connection")
|
||||
|
@ -173,6 +179,19 @@ func (c *Config) ValidateRegion() error {
|
|||
return fmt.Errorf("Not a valid region: %s", c.Region)
|
||||
}
|
||||
|
||||
// Validate credentials early and fail before we do any graph walking
|
||||
func (c *Config) ValidateCredentials(iamconn *iam.IAM) error {
|
||||
_, err := iamconn.GetUser(nil)
|
||||
|
||||
if awsErr, ok := err.(awserr.Error); ok {
|
||||
if awsErr.Code() == "SignatureDoesNotMatch" {
|
||||
return fmt.Errorf("Failed authenticating with AWS: please verify credentials")
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// ValidateAccountId returns a context-specific error if the configured account
|
||||
// id is explicitly forbidden or not authorised; and nil if it is authorised.
|
||||
func (c *Config) ValidateAccountId(iamconn *iam.IAM) error {
|
||||
|
|
|
@ -26,12 +26,12 @@ func expandNetworkAclEntries(configured []interface{}, entryType string) ([]*ec2
|
|||
e := &ec2.NetworkACLEntry{
|
||||
Protocol: aws.String(strconv.Itoa(p)),
|
||||
PortRange: &ec2.PortRange{
|
||||
From: aws.Long(int64(data["from_port"].(int))),
|
||||
To: aws.Long(int64(data["to_port"].(int))),
|
||||
From: aws.Int64(int64(data["from_port"].(int))),
|
||||
To: aws.Int64(int64(data["to_port"].(int))),
|
||||
},
|
||||
Egress: aws.Boolean((entryType == "egress")),
|
||||
Egress: aws.Bool((entryType == "egress")),
|
||||
RuleAction: aws.String(data["action"].(string)),
|
||||
RuleNumber: aws.Long(int64(data["rule_no"].(int))),
|
||||
RuleNumber: aws.Int64(int64(data["rule_no"].(int))),
|
||||
CIDRBlock: aws.String(data["cidr_block"].(string)),
|
||||
}
|
||||
|
||||
|
@ -39,10 +39,10 @@ func expandNetworkAclEntries(configured []interface{}, entryType string) ([]*ec2
|
|||
if p == 1 {
|
||||
e.ICMPTypeCode = &ec2.ICMPTypeCode{}
|
||||
if v, ok := data["icmp_code"]; ok {
|
||||
e.ICMPTypeCode.Code = aws.Long(int64(v.(int)))
|
||||
e.ICMPTypeCode.Code = aws.Int64(int64(v.(int)))
|
||||
}
|
||||
if v, ok := data["icmp_type"]; ok {
|
||||
e.ICMPTypeCode.Type = aws.Long(int64(v.(int)))
|
||||
e.ICMPTypeCode.Type = aws.Int64(int64(v.(int)))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -41,35 +41,35 @@ func Test_expandNetworkACLEntry(t *testing.T) {
|
|||
&ec2.NetworkACLEntry{
|
||||
Protocol: aws.String("6"),
|
||||
PortRange: &ec2.PortRange{
|
||||
From: aws.Long(22),
|
||||
To: aws.Long(22),
|
||||
From: aws.Int64(22),
|
||||
To: aws.Int64(22),
|
||||
},
|
||||
RuleAction: aws.String("deny"),
|
||||
RuleNumber: aws.Long(1),
|
||||
RuleNumber: aws.Int64(1),
|
||||
CIDRBlock: aws.String("0.0.0.0/0"),
|
||||
Egress: aws.Boolean(true),
|
||||
Egress: aws.Bool(true),
|
||||
},
|
||||
&ec2.NetworkACLEntry{
|
||||
Protocol: aws.String("6"),
|
||||
PortRange: &ec2.PortRange{
|
||||
From: aws.Long(443),
|
||||
To: aws.Long(443),
|
||||
From: aws.Int64(443),
|
||||
To: aws.Int64(443),
|
||||
},
|
||||
RuleAction: aws.String("deny"),
|
||||
RuleNumber: aws.Long(2),
|
||||
RuleNumber: aws.Int64(2),
|
||||
CIDRBlock: aws.String("0.0.0.0/0"),
|
||||
Egress: aws.Boolean(true),
|
||||
Egress: aws.Bool(true),
|
||||
},
|
||||
&ec2.NetworkACLEntry{
|
||||
Protocol: aws.String("-1"),
|
||||
PortRange: &ec2.PortRange{
|
||||
From: aws.Long(443),
|
||||
To: aws.Long(443),
|
||||
From: aws.Int64(443),
|
||||
To: aws.Int64(443),
|
||||
},
|
||||
RuleAction: aws.String("deny"),
|
||||
RuleNumber: aws.Long(2),
|
||||
RuleNumber: aws.Int64(2),
|
||||
CIDRBlock: aws.String("0.0.0.0/0"),
|
||||
Egress: aws.Boolean(true),
|
||||
Egress: aws.Bool(true),
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -88,21 +88,21 @@ func Test_flattenNetworkACLEntry(t *testing.T) {
|
|||
&ec2.NetworkACLEntry{
|
||||
Protocol: aws.String("tcp"),
|
||||
PortRange: &ec2.PortRange{
|
||||
From: aws.Long(22),
|
||||
To: aws.Long(22),
|
||||
From: aws.Int64(22),
|
||||
To: aws.Int64(22),
|
||||
},
|
||||
RuleAction: aws.String("deny"),
|
||||
RuleNumber: aws.Long(1),
|
||||
RuleNumber: aws.Int64(1),
|
||||
CIDRBlock: aws.String("0.0.0.0/0"),
|
||||
},
|
||||
&ec2.NetworkACLEntry{
|
||||
Protocol: aws.String("tcp"),
|
||||
PortRange: &ec2.PortRange{
|
||||
From: aws.Long(443),
|
||||
To: aws.Long(443),
|
||||
From: aws.Int64(443),
|
||||
To: aws.Int64(443),
|
||||
},
|
||||
RuleAction: aws.String("deny"),
|
||||
RuleNumber: aws.Long(2),
|
||||
RuleNumber: aws.Int64(2),
|
||||
CIDRBlock: aws.String("0.0.0.0/0"),
|
||||
},
|
||||
}
|
||||
|
|
|
@ -64,7 +64,7 @@ func resourceAwsAppCookieStickinessPolicyCreate(d *schema.ResourceData, meta int
|
|||
|
||||
setLoadBalancerOpts := &elb.SetLoadBalancerPoliciesOfListenerInput{
|
||||
LoadBalancerName: aws.String(d.Get("load_balancer").(string)),
|
||||
LoadBalancerPort: aws.Long(int64(d.Get("lb_port").(int))),
|
||||
LoadBalancerPort: aws.Int64(int64(d.Get("lb_port").(int))),
|
||||
PolicyNames: []*string{aws.String(d.Get("name").(string))},
|
||||
}
|
||||
|
||||
|
@ -129,7 +129,7 @@ func resourceAwsAppCookieStickinessPolicyDelete(d *schema.ResourceData, meta int
|
|||
// policy itself.
|
||||
setLoadBalancerOpts := &elb.SetLoadBalancerPoliciesOfListenerInput{
|
||||
LoadBalancerName: aws.String(d.Get("load_balancer").(string)),
|
||||
LoadBalancerPort: aws.Long(int64(d.Get("lb_port").(int))),
|
||||
LoadBalancerPort: aws.Int64(int64(d.Get("lb_port").(int))),
|
||||
PolicyNames: []*string{},
|
||||
}
|
||||
|
||||
|
|
|
@ -131,8 +131,8 @@ func resourceAwsAutoscalingGroupCreate(d *schema.ResourceData, meta interface{})
|
|||
var autoScalingGroupOpts autoscaling.CreateAutoScalingGroupInput
|
||||
autoScalingGroupOpts.AutoScalingGroupName = aws.String(d.Get("name").(string))
|
||||
autoScalingGroupOpts.LaunchConfigurationName = aws.String(d.Get("launch_configuration").(string))
|
||||
autoScalingGroupOpts.MinSize = aws.Long(int64(d.Get("min_size").(int)))
|
||||
autoScalingGroupOpts.MaxSize = aws.Long(int64(d.Get("max_size").(int)))
|
||||
autoScalingGroupOpts.MinSize = aws.Int64(int64(d.Get("min_size").(int)))
|
||||
autoScalingGroupOpts.MaxSize = aws.Int64(int64(d.Get("max_size").(int)))
|
||||
|
||||
// Availability Zones are optional if VPC Zone Identifer(s) are specified
|
||||
if v, ok := d.GetOk("availability_zones"); ok && v.(*schema.Set).Len() > 0 {
|
||||
|
@ -145,7 +145,7 @@ func resourceAwsAutoscalingGroupCreate(d *schema.ResourceData, meta interface{})
|
|||
}
|
||||
|
||||
if v, ok := d.GetOk("default_cooldown"); ok {
|
||||
autoScalingGroupOpts.DefaultCooldown = aws.Long(int64(v.(int)))
|
||||
autoScalingGroupOpts.DefaultCooldown = aws.Int64(int64(v.(int)))
|
||||
}
|
||||
|
||||
if v, ok := d.GetOk("health_check_type"); ok && v.(string) != "" {
|
||||
|
@ -153,11 +153,11 @@ func resourceAwsAutoscalingGroupCreate(d *schema.ResourceData, meta interface{})
|
|||
}
|
||||
|
||||
if v, ok := d.GetOk("desired_capacity"); ok {
|
||||
autoScalingGroupOpts.DesiredCapacity = aws.Long(int64(v.(int)))
|
||||
autoScalingGroupOpts.DesiredCapacity = aws.Int64(int64(v.(int)))
|
||||
}
|
||||
|
||||
if v, ok := d.GetOk("health_check_grace_period"); ok {
|
||||
autoScalingGroupOpts.HealthCheckGracePeriod = aws.Long(int64(v.(int)))
|
||||
autoScalingGroupOpts.HealthCheckGracePeriod = aws.Int64(int64(v.(int)))
|
||||
}
|
||||
|
||||
if v, ok := d.GetOk("load_balancers"); ok && v.(*schema.Set).Len() > 0 {
|
||||
|
@ -224,11 +224,11 @@ func resourceAwsAutoscalingGroupUpdate(d *schema.ResourceData, meta interface{})
|
|||
}
|
||||
|
||||
if d.HasChange("default_cooldown") {
|
||||
opts.DefaultCooldown = aws.Long(int64(d.Get("default_cooldown").(int)))
|
||||
opts.DefaultCooldown = aws.Int64(int64(d.Get("default_cooldown").(int)))
|
||||
}
|
||||
|
||||
if d.HasChange("desired_capacity") {
|
||||
opts.DesiredCapacity = aws.Long(int64(d.Get("desired_capacity").(int)))
|
||||
opts.DesiredCapacity = aws.Int64(int64(d.Get("desired_capacity").(int)))
|
||||
}
|
||||
|
||||
if d.HasChange("launch_configuration") {
|
||||
|
@ -236,19 +236,19 @@ func resourceAwsAutoscalingGroupUpdate(d *schema.ResourceData, meta interface{})
|
|||
}
|
||||
|
||||
if d.HasChange("min_size") {
|
||||
opts.MinSize = aws.Long(int64(d.Get("min_size").(int)))
|
||||
opts.MinSize = aws.Int64(int64(d.Get("min_size").(int)))
|
||||
}
|
||||
|
||||
if d.HasChange("max_size") {
|
||||
opts.MaxSize = aws.Long(int64(d.Get("max_size").(int)))
|
||||
opts.MaxSize = aws.Int64(int64(d.Get("max_size").(int)))
|
||||
}
|
||||
|
||||
if d.HasChange("health_check_grace_period") {
|
||||
opts.HealthCheckGracePeriod = aws.Long(int64(d.Get("health_check_grace_period").(int)))
|
||||
opts.HealthCheckGracePeriod = aws.Int64(int64(d.Get("health_check_grace_period").(int)))
|
||||
}
|
||||
|
||||
if d.HasChange("health_check_type") {
|
||||
opts.HealthCheckGracePeriod = aws.Long(int64(d.Get("health_check_grace_period").(int)))
|
||||
opts.HealthCheckGracePeriod = aws.Int64(int64(d.Get("health_check_grace_period").(int)))
|
||||
opts.HealthCheckType = aws.String(d.Get("health_check_type").(string))
|
||||
}
|
||||
|
||||
|
@ -342,7 +342,7 @@ func resourceAwsAutoscalingGroupDelete(d *schema.ResourceData, meta interface{})
|
|||
// and then delete the group. This bypasses that and leaves
|
||||
// resources potentially dangling.
|
||||
if d.Get("force_delete").(bool) {
|
||||
deleteopts.ForceDelete = aws.Boolean(true)
|
||||
deleteopts.ForceDelete = aws.Bool(true)
|
||||
}
|
||||
|
||||
// We retry the delete operation to handle InUse/InProgress errors coming
|
||||
|
@ -418,9 +418,9 @@ func resourceAwsAutoscalingGroupDrain(d *schema.ResourceData, meta interface{})
|
|||
log.Printf("[DEBUG] Reducing autoscaling group capacity to zero")
|
||||
opts := autoscaling.UpdateAutoScalingGroupInput{
|
||||
AutoScalingGroupName: aws.String(d.Id()),
|
||||
DesiredCapacity: aws.Long(0),
|
||||
MinSize: aws.Long(0),
|
||||
MaxSize: aws.Long(0),
|
||||
DesiredCapacity: aws.Int64(0),
|
||||
MinSize: aws.Int64(0),
|
||||
MaxSize: aws.Int64(0),
|
||||
}
|
||||
if _, err := conn.UpdateAutoScalingGroup(&opts); err != nil {
|
||||
return fmt.Errorf("Error setting capacity to zero to drain: %s", err)
|
||||
|
|
|
@ -217,7 +217,7 @@ func testAccCheckAWSAutoScalingGroupAttributes(group *autoscaling.Group) resourc
|
|||
t := &autoscaling.TagDescription{
|
||||
Key: aws.String("Foo"),
|
||||
Value: aws.String("foo-bar"),
|
||||
PropagateAtLaunch: aws.Boolean(true),
|
||||
PropagateAtLaunch: aws.Bool(true),
|
||||
ResourceType: aws.String("auto-scaling-group"),
|
||||
ResourceID: group.AutoScalingGroupName,
|
||||
}
|
||||
|
|
|
@ -140,15 +140,15 @@ func getAwsAutoscalingPutScalingPolicyInput(d *schema.ResourceData) autoscaling.
|
|||
}
|
||||
|
||||
if v, ok := d.GetOk("cooldown"); ok {
|
||||
params.Cooldown = aws.Long(int64(v.(int)))
|
||||
params.Cooldown = aws.Int64(int64(v.(int)))
|
||||
}
|
||||
|
||||
if v, ok := d.GetOk("scaling_adjustment"); ok {
|
||||
params.ScalingAdjustment = aws.Long(int64(v.(int)))
|
||||
params.ScalingAdjustment = aws.Int64(int64(v.(int)))
|
||||
}
|
||||
|
||||
if v, ok := d.GetOk("min_adjustment_step"); ok {
|
||||
params.MinAdjustmentStep = aws.Long(int64(v.(int)))
|
||||
params.MinAdjustmentStep = aws.Int64(int64(v.(int)))
|
||||
}
|
||||
|
||||
return params
|
||||
|
|
|
@ -197,16 +197,16 @@ func getAwsCloudWatchPutMetricAlarmInput(d *schema.ResourceData) cloudwatch.PutM
|
|||
params := cloudwatch.PutMetricAlarmInput{
|
||||
AlarmName: aws.String(d.Get("alarm_name").(string)),
|
||||
ComparisonOperator: aws.String(d.Get("comparison_operator").(string)),
|
||||
EvaluationPeriods: aws.Long(int64(d.Get("evaluation_periods").(int))),
|
||||
EvaluationPeriods: aws.Int64(int64(d.Get("evaluation_periods").(int))),
|
||||
MetricName: aws.String(d.Get("metric_name").(string)),
|
||||
Namespace: aws.String(d.Get("namespace").(string)),
|
||||
Period: aws.Long(int64(d.Get("period").(int))),
|
||||
Period: aws.Int64(int64(d.Get("period").(int))),
|
||||
Statistic: aws.String(d.Get("statistic").(string)),
|
||||
Threshold: aws.Double(d.Get("threshold").(float64)),
|
||||
Threshold: aws.Float64(d.Get("threshold").(float64)),
|
||||
}
|
||||
|
||||
if v := d.Get("actions_enabled"); v != nil {
|
||||
params.ActionsEnabled = aws.Boolean(v.(bool))
|
||||
params.ActionsEnabled = aws.Bool(v.(bool))
|
||||
}
|
||||
|
||||
if v, ok := d.GetOk("alarm_description"); ok {
|
||||
|
|
|
@ -48,7 +48,7 @@ func resourceAwsCustomerGatewayCreate(d *schema.ResourceData, meta interface{})
|
|||
conn := meta.(*AWSClient).ec2conn
|
||||
|
||||
createOpts := &ec2.CreateCustomerGatewayInput{
|
||||
BGPASN: aws.Long(int64(d.Get("bgp_asn").(int))),
|
||||
BGPASN: aws.Int64(int64(d.Get("bgp_asn").(int))),
|
||||
PublicIP: aws.String(d.Get("ip_address").(string)),
|
||||
Type: aws.String(d.Get("type").(string)),
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ import (
|
|||
"github.com/hashicorp/terraform/terraform"
|
||||
)
|
||||
|
||||
func TestAccCustomerGateway_basic(t *testing.T) {
|
||||
func TestAccAWSCustomerGateway_basic(t *testing.T) {
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
|
|
|
@ -46,6 +46,10 @@ func resourceAwsDbInstance() *schema.Resource {
|
|||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
StateFunc: func(v interface{}) string {
|
||||
value := v.(string)
|
||||
return strings.ToLower(value)
|
||||
},
|
||||
},
|
||||
|
||||
"engine_version": &schema.Schema{
|
||||
|
@ -268,11 +272,11 @@ func resourceAwsDbInstanceCreate(d *schema.ResourceData, meta interface{}) error
|
|||
Tags: tags,
|
||||
}
|
||||
if attr, ok := d.GetOk("iops"); ok {
|
||||
opts.IOPS = aws.Long(int64(attr.(int)))
|
||||
opts.IOPS = aws.Int64(int64(attr.(int)))
|
||||
}
|
||||
|
||||
if attr, ok := d.GetOk("port"); ok {
|
||||
opts.Port = aws.Long(int64(attr.(int)))
|
||||
opts.Port = aws.Int64(int64(attr.(int)))
|
||||
}
|
||||
|
||||
if attr, ok := d.GetOk("availability_zone"); ok {
|
||||
|
@ -280,7 +284,7 @@ func resourceAwsDbInstanceCreate(d *schema.ResourceData, meta interface{}) error
|
|||
}
|
||||
|
||||
if attr, ok := d.GetOk("publicly_accessible"); ok {
|
||||
opts.PubliclyAccessible = aws.Boolean(attr.(bool))
|
||||
opts.PubliclyAccessible = aws.Bool(attr.(bool))
|
||||
}
|
||||
_, err := conn.CreateDBInstanceReadReplica(&opts)
|
||||
if err != nil {
|
||||
|
@ -295,7 +299,7 @@ func resourceAwsDbInstanceCreate(d *schema.ResourceData, meta interface{}) error
|
|||
}
|
||||
|
||||
if attr, ok := d.GetOk("auto_minor_version_upgrade"); ok {
|
||||
opts.AutoMinorVersionUpgrade = aws.Boolean(attr.(bool))
|
||||
opts.AutoMinorVersionUpgrade = aws.Bool(attr.(bool))
|
||||
}
|
||||
|
||||
if attr, ok := d.GetOk("availability_zone"); ok {
|
||||
|
@ -311,7 +315,7 @@ func resourceAwsDbInstanceCreate(d *schema.ResourceData, meta interface{}) error
|
|||
}
|
||||
|
||||
if attr, ok := d.GetOk("iops"); ok {
|
||||
opts.IOPS = aws.Long(int64(attr.(int)))
|
||||
opts.IOPS = aws.Int64(int64(attr.(int)))
|
||||
}
|
||||
|
||||
if attr, ok := d.GetOk("license_model"); ok {
|
||||
|
@ -319,7 +323,7 @@ func resourceAwsDbInstanceCreate(d *schema.ResourceData, meta interface{}) error
|
|||
}
|
||||
|
||||
if attr, ok := d.GetOk("multi_az"); ok {
|
||||
opts.MultiAZ = aws.Boolean(attr.(bool))
|
||||
opts.MultiAZ = aws.Bool(attr.(bool))
|
||||
}
|
||||
|
||||
if attr, ok := d.GetOk("option_group_name"); ok {
|
||||
|
@ -327,11 +331,11 @@ func resourceAwsDbInstanceCreate(d *schema.ResourceData, meta interface{}) error
|
|||
}
|
||||
|
||||
if attr, ok := d.GetOk("port"); ok {
|
||||
opts.Port = aws.Long(int64(attr.(int)))
|
||||
opts.Port = aws.Int64(int64(attr.(int)))
|
||||
}
|
||||
|
||||
if attr, ok := d.GetOk("publicly_accessible"); ok {
|
||||
opts.PubliclyAccessible = aws.Boolean(attr.(bool))
|
||||
opts.PubliclyAccessible = aws.Bool(attr.(bool))
|
||||
}
|
||||
|
||||
if attr, ok := d.GetOk("tde_credential_arn"); ok {
|
||||
|
@ -348,7 +352,7 @@ func resourceAwsDbInstanceCreate(d *schema.ResourceData, meta interface{}) error
|
|||
}
|
||||
} else {
|
||||
opts := rds.CreateDBInstanceInput{
|
||||
AllocatedStorage: aws.Long(int64(d.Get("allocated_storage").(int))),
|
||||
AllocatedStorage: aws.Int64(int64(d.Get("allocated_storage").(int))),
|
||||
DBName: aws.String(d.Get("name").(string)),
|
||||
DBInstanceClass: aws.String(d.Get("instance_class").(string)),
|
||||
DBInstanceIdentifier: aws.String(d.Get("identifier").(string)),
|
||||
|
@ -356,14 +360,14 @@ func resourceAwsDbInstanceCreate(d *schema.ResourceData, meta interface{}) error
|
|||
MasterUserPassword: aws.String(d.Get("password").(string)),
|
||||
Engine: aws.String(d.Get("engine").(string)),
|
||||
EngineVersion: aws.String(d.Get("engine_version").(string)),
|
||||
StorageEncrypted: aws.Boolean(d.Get("storage_encrypted").(bool)),
|
||||
StorageEncrypted: aws.Bool(d.Get("storage_encrypted").(bool)),
|
||||
Tags: tags,
|
||||
}
|
||||
|
||||
attr := d.Get("backup_retention_period")
|
||||
opts.BackupRetentionPeriod = aws.Long(int64(attr.(int)))
|
||||
opts.BackupRetentionPeriod = aws.Int64(int64(attr.(int)))
|
||||
if attr, ok := d.GetOk("multi_az"); ok {
|
||||
opts.MultiAZ = aws.Boolean(attr.(bool))
|
||||
opts.MultiAZ = aws.Bool(attr.(bool))
|
||||
}
|
||||
|
||||
if attr, ok := d.GetOk("maintenance_window"); ok {
|
||||
|
@ -405,11 +409,11 @@ func resourceAwsDbInstanceCreate(d *schema.ResourceData, meta interface{}) error
|
|||
}
|
||||
|
||||
if attr, ok := d.GetOk("iops"); ok {
|
||||
opts.IOPS = aws.Long(int64(attr.(int)))
|
||||
opts.IOPS = aws.Int64(int64(attr.(int)))
|
||||
}
|
||||
|
||||
if attr, ok := d.GetOk("port"); ok {
|
||||
opts.Port = aws.Long(int64(attr.(int)))
|
||||
opts.Port = aws.Int64(int64(attr.(int)))
|
||||
}
|
||||
|
||||
if attr, ok := d.GetOk("availability_zone"); ok {
|
||||
|
@ -417,7 +421,7 @@ func resourceAwsDbInstanceCreate(d *schema.ResourceData, meta interface{}) error
|
|||
}
|
||||
|
||||
if attr, ok := d.GetOk("publicly_accessible"); ok {
|
||||
opts.PubliclyAccessible = aws.Boolean(attr.(bool))
|
||||
opts.PubliclyAccessible = aws.Bool(attr.(bool))
|
||||
}
|
||||
|
||||
log.Printf("[DEBUG] DB Instance create configuration: %#v", opts)
|
||||
|
@ -567,7 +571,7 @@ func resourceAwsDbInstanceDelete(d *schema.ResourceData, meta interface{}) error
|
|||
|
||||
finalSnapshot := d.Get("final_snapshot_identifier").(string)
|
||||
if finalSnapshot == "" {
|
||||
opts.SkipFinalSnapshot = aws.Boolean(true)
|
||||
opts.SkipFinalSnapshot = aws.Bool(true)
|
||||
} else {
|
||||
opts.FinalDBSnapshotIdentifier = aws.String(finalSnapshot)
|
||||
}
|
||||
|
@ -601,7 +605,7 @@ func resourceAwsDbInstanceUpdate(d *schema.ResourceData, meta interface{}) error
|
|||
d.Partial(true)
|
||||
|
||||
req := &rds.ModifyDBInstanceInput{
|
||||
ApplyImmediately: aws.Boolean(d.Get("apply_immediately").(bool)),
|
||||
ApplyImmediately: aws.Bool(d.Get("apply_immediately").(bool)),
|
||||
DBInstanceIdentifier: aws.String(d.Id()),
|
||||
}
|
||||
d.SetPartial("apply_immediately")
|
||||
|
@ -609,12 +613,12 @@ func resourceAwsDbInstanceUpdate(d *schema.ResourceData, meta interface{}) error
|
|||
requestUpdate := false
|
||||
if d.HasChange("allocated_storage") {
|
||||
d.SetPartial("allocated_storage")
|
||||
req.AllocatedStorage = aws.Long(int64(d.Get("allocated_storage").(int)))
|
||||
req.AllocatedStorage = aws.Int64(int64(d.Get("allocated_storage").(int)))
|
||||
requestUpdate = true
|
||||
}
|
||||
if d.HasChange("backup_retention_period") {
|
||||
d.SetPartial("backup_retention_period")
|
||||
req.BackupRetentionPeriod = aws.Long(int64(d.Get("backup_retention_period").(int)))
|
||||
req.BackupRetentionPeriod = aws.Int64(int64(d.Get("backup_retention_period").(int)))
|
||||
requestUpdate = true
|
||||
}
|
||||
if d.HasChange("instance_class") {
|
||||
|
@ -634,7 +638,7 @@ func resourceAwsDbInstanceUpdate(d *schema.ResourceData, meta interface{}) error
|
|||
}
|
||||
if d.HasChange("iops") {
|
||||
d.SetPartial("iops")
|
||||
req.IOPS = aws.Long(int64(d.Get("iops").(int)))
|
||||
req.IOPS = aws.Int64(int64(d.Get("iops").(int)))
|
||||
requestUpdate = true
|
||||
}
|
||||
if d.HasChange("backup_window") {
|
||||
|
@ -654,7 +658,7 @@ func resourceAwsDbInstanceUpdate(d *schema.ResourceData, meta interface{}) error
|
|||
}
|
||||
if d.HasChange("multi_az") {
|
||||
d.SetPartial("multi_az")
|
||||
req.MultiAZ = aws.Boolean(d.Get("multi_az").(bool))
|
||||
req.MultiAZ = aws.Bool(d.Get("multi_az").(bool))
|
||||
requestUpdate = true
|
||||
}
|
||||
if d.HasChange("storage_type") {
|
||||
|
@ -702,7 +706,7 @@ func resourceAwsDbInstanceUpdate(d *schema.ResourceData, meta interface{}) error
|
|||
DBInstanceIdentifier: aws.String(d.Id()),
|
||||
}
|
||||
attr := d.Get("backup_retention_period")
|
||||
opts.BackupRetentionPeriod = aws.Long(int64(attr.(int)))
|
||||
opts.BackupRetentionPeriod = aws.Int64(int64(attr.(int)))
|
||||
if attr, ok := d.GetOk("backup_window"); ok {
|
||||
opts.PreferredBackupWindow = aws.String(attr.(string))
|
||||
}
|
||||
|
|
|
@ -176,7 +176,7 @@ resource "aws_db_instance" "bar" {
|
|||
identifier = "foobarbaz-test-terraform-%d"
|
||||
|
||||
allocated_storage = 10
|
||||
engine = "mysql"
|
||||
engine = "MySQL"
|
||||
engine_version = "5.6.21"
|
||||
instance_class = "db.t1.micro"
|
||||
name = "baz"
|
||||
|
|
|
@ -166,8 +166,8 @@ func resourceAwsDynamoDbTableCreate(d *schema.ResourceData, meta interface{}) er
|
|||
log.Printf("[DEBUG] DynamoDB table create: %s", name)
|
||||
|
||||
throughput := &dynamodb.ProvisionedThroughput{
|
||||
ReadCapacityUnits: aws.Long(int64(d.Get("read_capacity").(int))),
|
||||
WriteCapacityUnits: aws.Long(int64(d.Get("write_capacity").(int))),
|
||||
ReadCapacityUnits: aws.Int64(int64(d.Get("read_capacity").(int))),
|
||||
WriteCapacityUnits: aws.Int64(int64(d.Get("write_capacity").(int))),
|
||||
}
|
||||
|
||||
hash_key_name := d.Get("hash_key").(string)
|
||||
|
@ -318,8 +318,8 @@ func resourceAwsDynamoDbTableUpdate(d *schema.ResourceData, meta interface{}) er
|
|||
}
|
||||
|
||||
throughput := &dynamodb.ProvisionedThroughput{
|
||||
ReadCapacityUnits: aws.Long(int64(d.Get("read_capacity").(int))),
|
||||
WriteCapacityUnits: aws.Long(int64(d.Get("write_capacity").(int))),
|
||||
ReadCapacityUnits: aws.Int64(int64(d.Get("read_capacity").(int))),
|
||||
WriteCapacityUnits: aws.Int64(int64(d.Get("write_capacity").(int))),
|
||||
}
|
||||
req.ProvisionedThroughput = throughput
|
||||
|
||||
|
@ -486,8 +486,8 @@ func resourceAwsDynamoDbTableUpdate(d *schema.ResourceData, meta interface{}) er
|
|||
Update: &dynamodb.UpdateGlobalSecondaryIndexAction{
|
||||
IndexName: aws.String(gsidata["name"].(string)),
|
||||
ProvisionedThroughput: &dynamodb.ProvisionedThroughput{
|
||||
WriteCapacityUnits: aws.Long(int64(gsiWriteCapacity)),
|
||||
ReadCapacityUnits: aws.Long(int64(gsiReadCapacity)),
|
||||
WriteCapacityUnits: aws.Int64(int64(gsiWriteCapacity)),
|
||||
ReadCapacityUnits: aws.Int64(int64(gsiReadCapacity)),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -634,8 +634,8 @@ func createGSIFromData(data *map[string]interface{}) dynamodb.GlobalSecondaryInd
|
|||
KeySchema: key_schema,
|
||||
Projection: projection,
|
||||
ProvisionedThroughput: &dynamodb.ProvisionedThroughput{
|
||||
WriteCapacityUnits: aws.Long(int64(writeCapacity)),
|
||||
ReadCapacityUnits: aws.Long(int64(readCapacity)),
|
||||
WriteCapacityUnits: aws.Int64(int64(writeCapacity)),
|
||||
ReadCapacityUnits: aws.Int64(int64(readCapacity)),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -74,16 +74,16 @@ func resourceAwsEbsVolumeCreate(d *schema.ResourceData, meta interface{}) error
|
|||
AvailabilityZone: aws.String(d.Get("availability_zone").(string)),
|
||||
}
|
||||
if value, ok := d.GetOk("encrypted"); ok {
|
||||
request.Encrypted = aws.Boolean(value.(bool))
|
||||
request.Encrypted = aws.Bool(value.(bool))
|
||||
}
|
||||
if value, ok := d.GetOk("iops"); ok {
|
||||
request.IOPS = aws.Long(int64(value.(int)))
|
||||
request.IOPS = aws.Int64(int64(value.(int)))
|
||||
}
|
||||
if value, ok := d.GetOk("kms_key_id"); ok {
|
||||
request.KMSKeyID = aws.String(value.(string))
|
||||
}
|
||||
if value, ok := d.GetOk("size"); ok {
|
||||
request.Size = aws.Long(int64(value.(int)))
|
||||
request.Size = aws.Int64(int64(value.(int)))
|
||||
}
|
||||
if value, ok := d.GetOk("snapshot_id"); ok {
|
||||
request.SnapshotID = aws.String(value.(string))
|
||||
|
|
|
@ -6,7 +6,6 @@ import (
|
|||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/aws/awsutil"
|
||||
"github.com/aws/aws-sdk-go/service/ecs"
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
|
@ -58,7 +57,7 @@ func resourceAwsEcsClusterRead(d *schema.ResourceData, meta interface{}) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Printf("[DEBUG] Received ECS clusters: %s", awsutil.StringValue(out.Clusters))
|
||||
log.Printf("[DEBUG] Received ECS clusters: %s", out.Clusters)
|
||||
|
||||
d.SetId(*out.Clusters[0].ClusterARN)
|
||||
d.Set("name", *out.Clusters[0].ClusterName)
|
||||
|
@ -77,7 +76,7 @@ func resourceAwsEcsClusterDelete(d *schema.ResourceData, meta interface{}) error
|
|||
})
|
||||
|
||||
if err == nil {
|
||||
log.Printf("[DEBUG] ECS cluster %s deleted: %s", d.Id(), awsutil.StringValue(out))
|
||||
log.Printf("[DEBUG] ECS cluster %s deleted: %s", d.Id(), out)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awsutil"
|
||||
"github.com/aws/aws-sdk-go/service/ecs"
|
||||
"github.com/aws/aws-sdk-go/service/iam"
|
||||
"github.com/hashicorp/terraform/helper/hashcode"
|
||||
|
@ -88,7 +87,7 @@ func resourceAwsEcsServiceCreate(d *schema.ResourceData, meta interface{}) error
|
|||
input := ecs.CreateServiceInput{
|
||||
ServiceName: aws.String(d.Get("name").(string)),
|
||||
TaskDefinition: aws.String(d.Get("task_definition").(string)),
|
||||
DesiredCount: aws.Long(int64(d.Get("desired_count").(int))),
|
||||
DesiredCount: aws.Int64(int64(d.Get("desired_count").(int))),
|
||||
ClientToken: aws.String(resource.UniqueId()),
|
||||
}
|
||||
|
||||
|
@ -98,14 +97,14 @@ func resourceAwsEcsServiceCreate(d *schema.ResourceData, meta interface{}) error
|
|||
|
||||
loadBalancers := expandEcsLoadBalancers(d.Get("load_balancer").(*schema.Set).List())
|
||||
if len(loadBalancers) > 0 {
|
||||
log.Printf("[DEBUG] Adding ECS load balancers: %s", awsutil.StringValue(loadBalancers))
|
||||
log.Printf("[DEBUG] Adding ECS load balancers: %s", loadBalancers)
|
||||
input.LoadBalancers = loadBalancers
|
||||
}
|
||||
if v, ok := d.GetOk("iam_role"); ok {
|
||||
input.Role = aws.String(v.(string))
|
||||
}
|
||||
|
||||
log.Printf("[DEBUG] Creating ECS service: %s", awsutil.StringValue(input))
|
||||
log.Printf("[DEBUG] Creating ECS service: %s", input)
|
||||
out, err := conn.CreateService(&input)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -139,7 +138,7 @@ func resourceAwsEcsServiceRead(d *schema.ResourceData, meta interface{}) error {
|
|||
}
|
||||
|
||||
service := out.Services[0]
|
||||
log.Printf("[DEBUG] Received ECS service %s", awsutil.StringValue(service))
|
||||
log.Printf("[DEBUG] Received ECS service %s", service)
|
||||
|
||||
d.SetId(*service.ServiceARN)
|
||||
d.Set("name", *service.ServiceName)
|
||||
|
@ -177,7 +176,7 @@ func resourceAwsEcsServiceUpdate(d *schema.ResourceData, meta interface{}) error
|
|||
|
||||
if d.HasChange("desired_count") {
|
||||
_, n := d.GetChange("desired_count")
|
||||
input.DesiredCount = aws.Long(int64(n.(int)))
|
||||
input.DesiredCount = aws.Int64(int64(n.(int)))
|
||||
}
|
||||
if d.HasChange("task_definition") {
|
||||
_, n := d.GetChange("task_definition")
|
||||
|
@ -189,7 +188,7 @@ func resourceAwsEcsServiceUpdate(d *schema.ResourceData, meta interface{}) error
|
|||
return err
|
||||
}
|
||||
service := out.Service
|
||||
log.Printf("[DEBUG] Updated ECS service %s", awsutil.StringValue(service))
|
||||
log.Printf("[DEBUG] Updated ECS service %s", service)
|
||||
|
||||
return resourceAwsEcsServiceRead(d, meta)
|
||||
}
|
||||
|
@ -217,7 +216,7 @@ func resourceAwsEcsServiceDelete(d *schema.ResourceData, meta interface{}) error
|
|||
_, err = conn.UpdateService(&ecs.UpdateServiceInput{
|
||||
Service: aws.String(d.Id()),
|
||||
Cluster: aws.String(d.Get("cluster").(string)),
|
||||
DesiredCount: aws.Long(int64(0)),
|
||||
DesiredCount: aws.Int64(int64(0)),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -229,7 +228,7 @@ func resourceAwsEcsServiceDelete(d *schema.ResourceData, meta interface{}) error
|
|||
Cluster: aws.String(d.Get("cluster").(string)),
|
||||
}
|
||||
|
||||
log.Printf("[DEBUG] Deleting ECS service %s", awsutil.StringValue(input))
|
||||
log.Printf("[DEBUG] Deleting ECS service %s", input)
|
||||
out, err := conn.DeleteService(&input)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -8,7 +8,6 @@ import (
|
|||
"log"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awsutil"
|
||||
"github.com/aws/aws-sdk-go/service/ecs"
|
||||
"github.com/hashicorp/terraform/helper/hashcode"
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
|
@ -91,7 +90,7 @@ func resourceAwsEcsTaskDefinitionCreate(d *schema.ResourceData, meta interface{}
|
|||
input.Volumes = volumes
|
||||
}
|
||||
|
||||
log.Printf("[DEBUG] Registering ECS task definition: %s", awsutil.StringValue(input))
|
||||
log.Printf("[DEBUG] Registering ECS task definition: %s", input)
|
||||
out, err := conn.RegisterTaskDefinition(&input)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -118,7 +117,7 @@ func resourceAwsEcsTaskDefinitionRead(d *schema.ResourceData, meta interface{})
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Printf("[DEBUG] Received task definition %s", awsutil.StringValue(out))
|
||||
log.Printf("[DEBUG] Received task definition %s", out)
|
||||
|
||||
taskDefinition := out.TaskDefinition
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@ import (
|
|||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/aws/awsutil"
|
||||
"github.com/aws/aws-sdk-go/service/elasticache"
|
||||
"github.com/aws/aws-sdk-go/service/iam"
|
||||
"github.com/hashicorp/terraform/helper/hashcode"
|
||||
|
@ -160,10 +159,10 @@ func resourceAwsElasticacheClusterCreate(d *schema.ResourceData, meta interface{
|
|||
req := &elasticache.CreateCacheClusterInput{
|
||||
CacheClusterID: aws.String(clusterId),
|
||||
CacheNodeType: aws.String(nodeType),
|
||||
NumCacheNodes: aws.Long(numNodes),
|
||||
NumCacheNodes: aws.Int64(numNodes),
|
||||
Engine: aws.String(engine),
|
||||
EngineVersion: aws.String(engineVersion),
|
||||
Port: aws.Long(port),
|
||||
Port: aws.Int64(port),
|
||||
CacheSubnetGroupName: aws.String(subnetGroupName),
|
||||
CacheSecurityGroupNames: securityNames,
|
||||
SecurityGroupIDs: securityIds,
|
||||
|
@ -186,11 +185,13 @@ func resourceAwsElasticacheClusterCreate(d *schema.ResourceData, meta interface{
|
|||
log.Printf("[DEBUG] Restoring Redis cluster from S3 snapshot: %#v", s)
|
||||
}
|
||||
|
||||
_, err := conn.CreateCacheCluster(req)
|
||||
resp, err := conn.CreateCacheCluster(req)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error creating Elasticache: %s", err)
|
||||
}
|
||||
|
||||
d.SetId(*resp.CacheCluster.CacheClusterID)
|
||||
|
||||
pending := []string{"creating"}
|
||||
stateConf := &resource.StateChangeConf{
|
||||
Pending: pending,
|
||||
|
@ -207,8 +208,6 @@ func resourceAwsElasticacheClusterCreate(d *schema.ResourceData, meta interface{
|
|||
return fmt.Errorf("Error waiting for elasticache (%s) to be created: %s", d.Id(), sterr)
|
||||
}
|
||||
|
||||
d.SetId(clusterId)
|
||||
|
||||
return resourceAwsElasticacheClusterRead(d, meta)
|
||||
}
|
||||
|
||||
|
@ -216,7 +215,7 @@ func resourceAwsElasticacheClusterRead(d *schema.ResourceData, meta interface{})
|
|||
conn := meta.(*AWSClient).elasticacheconn
|
||||
req := &elasticache.DescribeCacheClustersInput{
|
||||
CacheClusterID: aws.String(d.Id()),
|
||||
ShowCacheNodeInfo: aws.Boolean(true),
|
||||
ShowCacheNodeInfo: aws.Bool(true),
|
||||
}
|
||||
|
||||
res, err := conn.DescribeCacheClusters(req)
|
||||
|
@ -281,7 +280,7 @@ func resourceAwsElasticacheClusterUpdate(d *schema.ResourceData, meta interface{
|
|||
|
||||
req := &elasticache.ModifyCacheClusterInput{
|
||||
CacheClusterID: aws.String(d.Id()),
|
||||
ApplyImmediately: aws.Boolean(d.Get("apply_immediately").(bool)),
|
||||
ApplyImmediately: aws.Bool(d.Get("apply_immediately").(bool)),
|
||||
}
|
||||
|
||||
requestUpdate := false
|
||||
|
@ -308,12 +307,12 @@ func resourceAwsElasticacheClusterUpdate(d *schema.ResourceData, meta interface{
|
|||
}
|
||||
|
||||
if d.HasChange("num_cache_nodes") {
|
||||
req.NumCacheNodes = aws.Long(int64(d.Get("num_cache_nodes").(int)))
|
||||
req.NumCacheNodes = aws.Int64(int64(d.Get("num_cache_nodes").(int)))
|
||||
requestUpdate = true
|
||||
}
|
||||
|
||||
if requestUpdate {
|
||||
log.Printf("[DEBUG] Modifying ElastiCache Cluster (%s), opts:\n%s", d.Id(), awsutil.StringValue(req))
|
||||
log.Printf("[DEBUG] Modifying ElastiCache Cluster (%s), opts:\n%s", d.Id(), req)
|
||||
_, err := conn.ModifyCacheCluster(req)
|
||||
if err != nil {
|
||||
return fmt.Errorf("[WARN] Error updating ElastiCache cluster (%s), error: %s", d.Id(), err)
|
||||
|
@ -348,7 +347,7 @@ func setCacheNodeData(d *schema.ResourceData, c *elasticache.CacheCluster) error
|
|||
|
||||
for _, node := range sortedCacheNodes {
|
||||
if node.CacheNodeID == nil || node.Endpoint == nil || node.Endpoint.Address == nil || node.Endpoint.Port == nil {
|
||||
return fmt.Errorf("Unexpected nil pointer in: %s", awsutil.StringValue(node))
|
||||
return fmt.Errorf("Unexpected nil pointer in: %s", node)
|
||||
}
|
||||
cacheNodeData = append(cacheNodeData, map[string]interface{}{
|
||||
"id": *node.CacheNodeID,
|
||||
|
@ -404,7 +403,7 @@ func cacheClusterStateRefreshFunc(conn *elasticache.ElastiCache, clusterID, give
|
|||
return func() (interface{}, string, error) {
|
||||
resp, err := conn.DescribeCacheClusters(&elasticache.DescribeCacheClustersInput{
|
||||
CacheClusterID: aws.String(clusterID),
|
||||
ShowCacheNodeInfo: aws.Boolean(true),
|
||||
ShowCacheNodeInfo: aws.Bool(true),
|
||||
})
|
||||
if err != nil {
|
||||
apierr := err.(awserr.Error)
|
||||
|
@ -418,11 +417,27 @@ func cacheClusterStateRefreshFunc(conn *elasticache.ElastiCache, clusterID, give
|
|||
return nil, "", err
|
||||
}
|
||||
|
||||
c := resp.CacheClusters[0]
|
||||
log.Printf("[DEBUG] status: %v", *c.CacheClusterStatus)
|
||||
if len(resp.CacheClusters) == 0 {
|
||||
return nil, "", fmt.Errorf("[WARN] Error: no Cache Clusters found for id (%s)", clusterID)
|
||||
}
|
||||
|
||||
var c *elasticache.CacheCluster
|
||||
for _, cluster := range resp.CacheClusters {
|
||||
if *cluster.CacheClusterID == clusterID {
|
||||
log.Printf("[DEBUG] Found matching ElastiCache cluster: %s", *cluster.CacheClusterID)
|
||||
c = cluster
|
||||
}
|
||||
}
|
||||
|
||||
if c == nil {
|
||||
return nil, "", fmt.Errorf("[WARN] Error: no matching Elastic Cache cluster for id (%s)", clusterID)
|
||||
}
|
||||
|
||||
log.Printf("[DEBUG] ElastiCache Cluster (%s) status: %v", clusterID, *c.CacheClusterStatus)
|
||||
|
||||
// return the current state if it's in the pending array
|
||||
for _, p := range pending {
|
||||
log.Printf("[DEBUG] ElastiCache: checking pending state (%s) for cluster (%s), cluster status: %s", pending, clusterID, *c.CacheClusterStatus)
|
||||
s := *c.CacheClusterStatus
|
||||
if p == s {
|
||||
log.Printf("[DEBUG] Return with status: %v", *c.CacheClusterStatus)
|
||||
|
@ -432,18 +447,24 @@ func cacheClusterStateRefreshFunc(conn *elasticache.ElastiCache, clusterID, give
|
|||
|
||||
// return given state if it's not in pending
|
||||
if givenState != "" {
|
||||
log.Printf("[DEBUG] ElastiCache: checking given state (%s) of cluster (%s) against cluster status (%s)", givenState, clusterID, *c.CacheClusterStatus)
|
||||
// check to make sure we have the node count we're expecting
|
||||
if int64(len(c.CacheNodes)) != *c.NumCacheNodes {
|
||||
log.Printf("[DEBUG] Node count is not what is expected: %d found, %d expected", len(c.CacheNodes), *c.NumCacheNodes)
|
||||
return nil, "creating", nil
|
||||
}
|
||||
|
||||
log.Printf("[DEBUG] Node count matched (%d)", len(c.CacheNodes))
|
||||
// loop the nodes and check their status as well
|
||||
for _, n := range c.CacheNodes {
|
||||
log.Printf("[DEBUG] Checking cache node for status: %s", n)
|
||||
if n.CacheNodeStatus != nil && *n.CacheNodeStatus != "available" {
|
||||
log.Printf("[DEBUG] Node (%s) is not yet available, status: %s", *n.CacheNodeID, *n.CacheNodeStatus)
|
||||
return nil, "creating", nil
|
||||
}
|
||||
log.Printf("[DEBUG] Cache node not in expected state")
|
||||
}
|
||||
log.Printf("[DEBUG] ElastiCache returning given state (%s), cluster: %s", givenState, c)
|
||||
return c, givenState, nil
|
||||
}
|
||||
log.Printf("[DEBUG] current status: %v", *c.CacheClusterStatus)
|
||||
|
|
|
@ -65,7 +65,7 @@ func resourceAwsElasticacheParameterGroupCreate(d *schema.ResourceData, meta int
|
|||
createOpts := elasticache.CreateCacheParameterGroupInput{
|
||||
CacheParameterGroupName: aws.String(d.Get("name").(string)),
|
||||
CacheParameterGroupFamily: aws.String(d.Get("family").(string)),
|
||||
Description: aws.String(d.Get("description").(string)),
|
||||
Description: aws.String(d.Get("description").(string)),
|
||||
}
|
||||
|
||||
log.Printf("[DEBUG] Create Cache Parameter Group: %#v", createOpts)
|
||||
|
@ -110,7 +110,7 @@ func resourceAwsElasticacheParameterGroupRead(d *schema.ResourceData, meta inter
|
|||
// Only include user customized parameters as there's hundreds of system/default ones
|
||||
describeParametersOpts := elasticache.DescribeCacheParametersInput{
|
||||
CacheParameterGroupName: aws.String(d.Id()),
|
||||
Source: aws.String("user"),
|
||||
Source: aws.String("user"),
|
||||
}
|
||||
|
||||
describeParametersResp, err := conn.DescribeCacheParameters(&describeParametersOpts)
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/service/elb"
|
||||
"github.com/hashicorp/terraform/helper/hashcode"
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
)
|
||||
|
||||
|
@ -24,7 +25,8 @@ func resourceAwsElb() *schema.Resource {
|
|||
Schema: map[string]*schema.Schema{
|
||||
"name": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
ForceNew: true,
|
||||
ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) {
|
||||
value := v.(string)
|
||||
|
@ -211,10 +213,18 @@ func resourceAwsElbCreate(d *schema.ResourceData, meta interface{}) error {
|
|||
return err
|
||||
}
|
||||
|
||||
var elbName string
|
||||
if v, ok := d.GetOk("name"); ok {
|
||||
elbName = v.(string)
|
||||
} else {
|
||||
elbName = resource.PrefixedUniqueId("tf-lb-")
|
||||
d.Set("name", elbName)
|
||||
}
|
||||
|
||||
tags := tagsFromMapELB(d.Get("tags").(map[string]interface{}))
|
||||
// Provision the elb
|
||||
elbOpts := &elb.CreateLoadBalancerInput{
|
||||
LoadBalancerName: aws.String(d.Get("name").(string)),
|
||||
LoadBalancerName: aws.String(elbName),
|
||||
Listeners: listeners,
|
||||
Tags: tags,
|
||||
}
|
||||
|
@ -241,7 +251,7 @@ func resourceAwsElbCreate(d *schema.ResourceData, meta interface{}) error {
|
|||
}
|
||||
|
||||
// Assign the elb's unique identifier for use later
|
||||
d.SetId(d.Get("name").(string))
|
||||
d.SetId(elbName)
|
||||
log.Printf("[INFO] ELB ID: %s", d.Id())
|
||||
|
||||
// Enable partial mode and record what we set
|
||||
|
@ -419,10 +429,10 @@ func resourceAwsElbUpdate(d *schema.ResourceData, meta interface{}) error {
|
|||
LoadBalancerName: aws.String(d.Get("name").(string)),
|
||||
LoadBalancerAttributes: &elb.LoadBalancerAttributes{
|
||||
CrossZoneLoadBalancing: &elb.CrossZoneLoadBalancing{
|
||||
Enabled: aws.Boolean(d.Get("cross_zone_load_balancing").(bool)),
|
||||
Enabled: aws.Bool(d.Get("cross_zone_load_balancing").(bool)),
|
||||
},
|
||||
ConnectionSettings: &elb.ConnectionSettings{
|
||||
IdleTimeout: aws.Long(int64(d.Get("idle_timeout").(int))),
|
||||
IdleTimeout: aws.Int64(int64(d.Get("idle_timeout").(int))),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -449,8 +459,8 @@ func resourceAwsElbUpdate(d *schema.ResourceData, meta interface{}) error {
|
|||
LoadBalancerName: aws.String(d.Get("name").(string)),
|
||||
LoadBalancerAttributes: &elb.LoadBalancerAttributes{
|
||||
ConnectionDraining: &elb.ConnectionDraining{
|
||||
Enabled: aws.Boolean(true),
|
||||
Timeout: aws.Long(int64(d.Get("connection_draining_timeout").(int))),
|
||||
Enabled: aws.Bool(true),
|
||||
Timeout: aws.Int64(int64(d.Get("connection_draining_timeout").(int))),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -470,7 +480,7 @@ func resourceAwsElbUpdate(d *schema.ResourceData, meta interface{}) error {
|
|||
LoadBalancerName: aws.String(d.Get("name").(string)),
|
||||
LoadBalancerAttributes: &elb.LoadBalancerAttributes{
|
||||
ConnectionDraining: &elb.ConnectionDraining{
|
||||
Enabled: aws.Boolean(d.Get("connection_draining").(bool)),
|
||||
Enabled: aws.Bool(d.Get("connection_draining").(bool)),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -490,11 +500,11 @@ func resourceAwsElbUpdate(d *schema.ResourceData, meta interface{}) error {
|
|||
configureHealthCheckOpts := elb.ConfigureHealthCheckInput{
|
||||
LoadBalancerName: aws.String(d.Id()),
|
||||
HealthCheck: &elb.HealthCheck{
|
||||
HealthyThreshold: aws.Long(int64(check["healthy_threshold"].(int))),
|
||||
UnhealthyThreshold: aws.Long(int64(check["unhealthy_threshold"].(int))),
|
||||
Interval: aws.Long(int64(check["interval"].(int))),
|
||||
HealthyThreshold: aws.Int64(int64(check["healthy_threshold"].(int))),
|
||||
UnhealthyThreshold: aws.Int64(int64(check["unhealthy_threshold"].(int))),
|
||||
Interval: aws.Int64(int64(check["interval"].(int))),
|
||||
Target: aws.String(check["target"].(string)),
|
||||
Timeout: aws.Long(int64(check["timeout"].(int))),
|
||||
Timeout: aws.Int64(int64(check["timeout"].(int))),
|
||||
},
|
||||
}
|
||||
_, err := elbconn.ConfigureHealthCheck(&configureHealthCheckOpts)
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"fmt"
|
||||
"os"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"sort"
|
||||
"testing"
|
||||
|
||||
|
@ -74,6 +75,27 @@ func TestAccAWSELB_fullCharacterRange(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestAccAWSELB_generatedName(t *testing.T) {
|
||||
var conf elb.LoadBalancerDescription
|
||||
generatedNameRegexp := regexp.MustCompile("^tf-lb-")
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckAWSELBDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
resource.TestStep{
|
||||
Config: testAccAWSELBGeneratedName,
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckAWSELBExists("aws_elb.foo", &conf),
|
||||
resource.TestMatchResourceAttr(
|
||||
"aws_elb.foo", "name", generatedNameRegexp),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestAccAWSELB_tags(t *testing.T) {
|
||||
var conf elb.LoadBalancerDescription
|
||||
var td elb.TagDescription
|
||||
|
@ -465,9 +487,9 @@ func testAccCheckAWSELBAttributes(conf *elb.LoadBalancerDescription) resource.Te
|
|||
}
|
||||
|
||||
l := elb.Listener{
|
||||
InstancePort: aws.Long(int64(8000)),
|
||||
InstancePort: aws.Int64(int64(8000)),
|
||||
InstanceProtocol: aws.String("HTTP"),
|
||||
LoadBalancerPort: aws.Long(int64(80)),
|
||||
LoadBalancerPort: aws.Int64(int64(80)),
|
||||
Protocol: aws.String("HTTP"),
|
||||
}
|
||||
|
||||
|
@ -503,10 +525,10 @@ func testAccCheckAWSELBAttributesHealthCheck(conf *elb.LoadBalancerDescription)
|
|||
}
|
||||
|
||||
check := &elb.HealthCheck{
|
||||
Timeout: aws.Long(int64(30)),
|
||||
UnhealthyThreshold: aws.Long(int64(5)),
|
||||
HealthyThreshold: aws.Long(int64(5)),
|
||||
Interval: aws.Long(int64(60)),
|
||||
Timeout: aws.Int64(int64(30)),
|
||||
UnhealthyThreshold: aws.Int64(int64(5)),
|
||||
HealthyThreshold: aws.Int64(int64(5)),
|
||||
Interval: aws.Int64(int64(60)),
|
||||
Target: aws.String("HTTP:8000/"),
|
||||
}
|
||||
|
||||
|
@ -592,6 +614,19 @@ resource "aws_elb" "foo" {
|
|||
}
|
||||
`
|
||||
|
||||
const testAccAWSELBGeneratedName = `
|
||||
resource "aws_elb" "foo" {
|
||||
availability_zones = ["us-west-2a", "us-west-2b", "us-west-2c"]
|
||||
|
||||
listener {
|
||||
instance_port = 8000
|
||||
instance_protocol = "http"
|
||||
lb_port = 80
|
||||
lb_protocol = "http"
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
const testAccAWSELBConfig_TagUpdate = `
|
||||
resource "aws_elb" "bar" {
|
||||
name = "foobar-terraform-test"
|
||||
|
|
|
@ -5,7 +5,6 @@ import (
|
|||
"log"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awsutil"
|
||||
"github.com/aws/aws-sdk-go/service/ec2"
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
)
|
||||
|
@ -94,7 +93,7 @@ func resourceAwsLogFlowCreate(d *schema.ResourceData, meta interface{}) error {
|
|||
}
|
||||
|
||||
log.Printf(
|
||||
"[DEBUG] Flow Log Create configuration: %s", awsutil.StringValue(opts))
|
||||
"[DEBUG] Flow Log Create configuration: %s", opts)
|
||||
resp, err := conn.CreateFlowLogs(opts)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error creating Flow Log for (%s), error: %s", resourceId, err)
|
||||
|
|
|
@ -11,7 +11,7 @@ import (
|
|||
"github.com/hashicorp/terraform/terraform"
|
||||
)
|
||||
|
||||
func TestAccFlowLog_basic(t *testing.T) {
|
||||
func TestAccAWSFlowLog_basic(t *testing.T) {
|
||||
var flowLog ec2.FlowLog
|
||||
lgn := os.Getenv("LOG_GROUP_NAME")
|
||||
|
||||
|
@ -31,7 +31,7 @@ func TestAccFlowLog_basic(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestAccFlowLog_subnet(t *testing.T) {
|
||||
func TestAccAWSFlowLog_subnet(t *testing.T) {
|
||||
var flowLog ec2.FlowLog
|
||||
lgn := os.Getenv("LOG_GROUP_NAME")
|
||||
|
||||
|
|
|
@ -97,7 +97,7 @@ func resourceAwsIamPolicyUpdate(d *schema.ResourceData, meta interface{}) error
|
|||
request := &iam.CreatePolicyVersionInput{
|
||||
PolicyARN: aws.String(d.Id()),
|
||||
PolicyDocument: aws.String(d.Get("policy").(string)),
|
||||
SetAsDefault: aws.Boolean(true),
|
||||
SetAsDefault: aws.Bool(true),
|
||||
}
|
||||
|
||||
if _, err := iamconn.CreatePolicyVersion(request); err != nil {
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"crypto/sha1"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
|
@ -34,8 +35,9 @@ func resourceAwsIAMServerCertificate() *schema.Resource {
|
|||
},
|
||||
|
||||
"path": &schema.Schema{
|
||||
Type: schema.TypeBool,
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Default: "/",
|
||||
ForceNew: true,
|
||||
},
|
||||
|
||||
|
@ -74,10 +76,11 @@ func resourceAwsIAMServerCertificateCreate(d *schema.ResourceData, meta interfac
|
|||
createOpts.CertificateChain = aws.String(v.(string))
|
||||
}
|
||||
|
||||
if v, ok := d.GetOk("Path"); ok {
|
||||
if v, ok := d.GetOk("path"); ok {
|
||||
createOpts.Path = aws.String(v.(string))
|
||||
}
|
||||
|
||||
log.Printf("[DEBUG] Creating IAM Server Certificate with opts: %s", createOpts)
|
||||
resp, err := conn.UploadServerCertificate(createOpts)
|
||||
if err != nil {
|
||||
if awsErr, ok := err.(awserr.Error); ok {
|
||||
|
@ -107,7 +110,12 @@ func resourceAwsIAMServerCertificateRead(d *schema.ResourceData, meta interface{
|
|||
// these values should always be present, and have a default if not set in
|
||||
// configuration, and so safe to reference with nil checks
|
||||
d.Set("certificate_body", normalizeCert(resp.ServerCertificate.CertificateBody))
|
||||
d.Set("certificate_chain", normalizeCert(resp.ServerCertificate.CertificateChain))
|
||||
|
||||
c := normalizeCert(resp.ServerCertificate.CertificateChain)
|
||||
if c != "" {
|
||||
d.Set("certificate_chain", c)
|
||||
}
|
||||
|
||||
d.Set("path", resp.ServerCertificate.ServerCertificateMetadata.Path)
|
||||
d.Set("arn", resp.ServerCertificate.ServerCertificateMetadata.ARN)
|
||||
|
||||
|
@ -132,9 +140,10 @@ func resourceAwsIAMServerCertificateDelete(d *schema.ResourceData, meta interfac
|
|||
}
|
||||
|
||||
func normalizeCert(cert interface{}) string {
|
||||
if cert == nil {
|
||||
if cert == nil || cert == (*string)(nil) {
|
||||
return ""
|
||||
}
|
||||
|
||||
switch cert.(type) {
|
||||
case string:
|
||||
hash := sha1.Sum([]byte(strings.TrimSpace(cert.(string))))
|
||||
|
|
|
@ -13,7 +13,7 @@ import (
|
|||
"github.com/hashicorp/terraform/terraform"
|
||||
)
|
||||
|
||||
func TestAccIAMServerCertificate_basic(t *testing.T) {
|
||||
func TestAccAWSIAMServerCertificate_basic(t *testing.T) {
|
||||
var cert iam.ServerCertificate
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
|
|
|
@ -12,7 +12,6 @@ import (
|
|||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/aws/awsutil"
|
||||
"github.com/aws/aws-sdk-go/service/ec2"
|
||||
"github.com/hashicorp/terraform/helper/hashcode"
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
|
@ -334,8 +333,8 @@ func resourceAwsInstanceCreate(d *schema.ResourceData, meta interface{}) error {
|
|||
ImageID: instanceOpts.ImageID,
|
||||
InstanceType: instanceOpts.InstanceType,
|
||||
KeyName: instanceOpts.KeyName,
|
||||
MaxCount: aws.Long(int64(1)),
|
||||
MinCount: aws.Long(int64(1)),
|
||||
MaxCount: aws.Int64(int64(1)),
|
||||
MinCount: aws.Int64(int64(1)),
|
||||
NetworkInterfaces: instanceOpts.NetworkInterfaces,
|
||||
Placement: instanceOpts.Placement,
|
||||
PrivateIPAddress: instanceOpts.PrivateIPAddress,
|
||||
|
@ -346,7 +345,7 @@ func resourceAwsInstanceCreate(d *schema.ResourceData, meta interface{}) error {
|
|||
}
|
||||
|
||||
// Create the instance
|
||||
log.Printf("[DEBUG] Run configuration: %s", awsutil.StringValue(runOpts))
|
||||
log.Printf("[DEBUG] Run configuration: %s", runOpts)
|
||||
|
||||
var runResp *ec2.Reservation
|
||||
for i := 0; i < 5; i++ {
|
||||
|
@ -543,7 +542,7 @@ func resourceAwsInstanceUpdate(d *schema.ResourceData, meta interface{}) error {
|
|||
_, err := conn.ModifyInstanceAttribute(&ec2.ModifyInstanceAttributeInput{
|
||||
InstanceID: aws.String(d.Id()),
|
||||
SourceDestCheck: &ec2.AttributeBooleanValue{
|
||||
Value: aws.Boolean(d.Get("source_dest_check").(bool)),
|
||||
Value: aws.Bool(d.Get("source_dest_check").(bool)),
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
|
@ -571,7 +570,7 @@ func resourceAwsInstanceUpdate(d *schema.ResourceData, meta interface{}) error {
|
|||
_, err := conn.ModifyInstanceAttribute(&ec2.ModifyInstanceAttributeInput{
|
||||
InstanceID: aws.String(d.Id()),
|
||||
DisableAPITermination: &ec2.AttributeBooleanValue{
|
||||
Value: aws.Boolean(d.Get("disable_api_termination").(bool)),
|
||||
Value: aws.Bool(d.Get("disable_api_termination").(bool)),
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
|
@ -579,6 +578,24 @@ func resourceAwsInstanceUpdate(d *schema.ResourceData, meta interface{}) error {
|
|||
}
|
||||
}
|
||||
|
||||
if d.HasChange("monitoring") {
|
||||
var mErr error
|
||||
if d.Get("monitoring").(bool) {
|
||||
log.Printf("[DEBUG] Enabling monitoring for Instance (%s)", d.Id())
|
||||
_, mErr = conn.MonitorInstances(&ec2.MonitorInstancesInput{
|
||||
InstanceIDs: []*string{aws.String(d.Id())},
|
||||
})
|
||||
} else {
|
||||
log.Printf("[DEBUG] Disabling monitoring for Instance (%s)", d.Id())
|
||||
_, mErr = conn.UnmonitorInstances(&ec2.UnmonitorInstancesInput{
|
||||
InstanceIDs: []*string{aws.String(d.Id())},
|
||||
})
|
||||
}
|
||||
if mErr != nil {
|
||||
return fmt.Errorf("[WARN] Error updating Instance monitoring: %s", mErr)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(mitchellh): wait for the attributes we modified to
|
||||
// persist the change...
|
||||
|
||||
|
@ -760,6 +777,10 @@ func fetchRootDeviceName(ami string, conn *ec2.EC2) (*string, error) {
|
|||
rootDeviceName = image.BlockDeviceMappings[0].DeviceName
|
||||
}
|
||||
|
||||
if rootDeviceName == nil {
|
||||
return nil, fmt.Errorf("[WARN] Error finding Root Device Name for AMI (%s)", ami)
|
||||
}
|
||||
|
||||
return rootDeviceName, nil
|
||||
}
|
||||
|
||||
|
@ -772,7 +793,7 @@ func readBlockDeviceMappingsFromConfig(
|
|||
for _, v := range vL {
|
||||
bd := v.(map[string]interface{})
|
||||
ebs := &ec2.EBSBlockDevice{
|
||||
DeleteOnTermination: aws.Boolean(bd["delete_on_termination"].(bool)),
|
||||
DeleteOnTermination: aws.Bool(bd["delete_on_termination"].(bool)),
|
||||
}
|
||||
|
||||
if v, ok := bd["snapshot_id"].(string); ok && v != "" {
|
||||
|
@ -780,11 +801,11 @@ func readBlockDeviceMappingsFromConfig(
|
|||
}
|
||||
|
||||
if v, ok := bd["encrypted"].(bool); ok && v {
|
||||
ebs.Encrypted = aws.Boolean(v)
|
||||
ebs.Encrypted = aws.Bool(v)
|
||||
}
|
||||
|
||||
if v, ok := bd["volume_size"].(int); ok && v != 0 {
|
||||
ebs.VolumeSize = aws.Long(int64(v))
|
||||
ebs.VolumeSize = aws.Int64(int64(v))
|
||||
}
|
||||
|
||||
if v, ok := bd["volume_type"].(string); ok && v != "" {
|
||||
|
@ -792,7 +813,7 @@ func readBlockDeviceMappingsFromConfig(
|
|||
}
|
||||
|
||||
if v, ok := bd["iops"].(int); ok && v > 0 {
|
||||
ebs.IOPS = aws.Long(int64(v))
|
||||
ebs.IOPS = aws.Int64(int64(v))
|
||||
}
|
||||
|
||||
blockDevices = append(blockDevices, &ec2.BlockDeviceMapping{
|
||||
|
@ -821,11 +842,11 @@ func readBlockDeviceMappingsFromConfig(
|
|||
for _, v := range vL {
|
||||
bd := v.(map[string]interface{})
|
||||
ebs := &ec2.EBSBlockDevice{
|
||||
DeleteOnTermination: aws.Boolean(bd["delete_on_termination"].(bool)),
|
||||
DeleteOnTermination: aws.Bool(bd["delete_on_termination"].(bool)),
|
||||
}
|
||||
|
||||
if v, ok := bd["volume_size"].(int); ok && v != 0 {
|
||||
ebs.VolumeSize = aws.Long(int64(v))
|
||||
ebs.VolumeSize = aws.Int64(int64(v))
|
||||
}
|
||||
|
||||
if v, ok := bd["volume_type"].(string); ok && v != "" {
|
||||
|
@ -833,7 +854,7 @@ func readBlockDeviceMappingsFromConfig(
|
|||
}
|
||||
|
||||
if v, ok := bd["iops"].(int); ok && v > 0 {
|
||||
ebs.IOPS = aws.Long(int64(v))
|
||||
ebs.IOPS = aws.Int64(int64(v))
|
||||
}
|
||||
|
||||
if dn, err := fetchRootDeviceName(d.Get("ami").(string), conn); err == nil {
|
||||
|
@ -880,14 +901,14 @@ func buildAwsInstanceOpts(
|
|||
conn := meta.(*AWSClient).ec2conn
|
||||
|
||||
opts := &awsInstanceOpts{
|
||||
DisableAPITermination: aws.Boolean(d.Get("disable_api_termination").(bool)),
|
||||
EBSOptimized: aws.Boolean(d.Get("ebs_optimized").(bool)),
|
||||
DisableAPITermination: aws.Bool(d.Get("disable_api_termination").(bool)),
|
||||
EBSOptimized: aws.Bool(d.Get("ebs_optimized").(bool)),
|
||||
ImageID: aws.String(d.Get("ami").(string)),
|
||||
InstanceType: aws.String(d.Get("instance_type").(string)),
|
||||
}
|
||||
|
||||
opts.Monitoring = &ec2.RunInstancesMonitoringEnabled{
|
||||
Enabled: aws.Boolean(d.Get("monitoring").(bool)),
|
||||
Enabled: aws.Bool(d.Get("monitoring").(bool)),
|
||||
}
|
||||
|
||||
opts.IAMInstanceProfile = &ec2.IAMInstanceProfileSpecification{
|
||||
|
@ -943,8 +964,8 @@ func buildAwsInstanceOpts(
|
|||
// to avoid: Network interfaces and an instance-level security groups may not be specified on
|
||||
// the same request
|
||||
ni := &ec2.InstanceNetworkInterfaceSpecification{
|
||||
AssociatePublicIPAddress: aws.Boolean(associatePublicIPAddress),
|
||||
DeviceIndex: aws.Long(int64(0)),
|
||||
AssociatePublicIPAddress: aws.Bool(associatePublicIPAddress),
|
||||
DeviceIndex: aws.Int64(int64(0)),
|
||||
SubnetID: aws.String(subnetID),
|
||||
Groups: groups,
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@ import (
|
|||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/aws/awsutil"
|
||||
"github.com/aws/aws-sdk-go/service/ec2"
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
|
@ -47,7 +46,7 @@ func TestAccAWSInstance_basic(t *testing.T) {
|
|||
var err error
|
||||
vol, err = conn.CreateVolume(&ec2.CreateVolumeInput{
|
||||
AvailabilityZone: aws.String("us-west-2a"),
|
||||
Size: aws.Long(int64(5)),
|
||||
Size: aws.Int64(int64(5)),
|
||||
})
|
||||
return err
|
||||
},
|
||||
|
@ -467,8 +466,8 @@ func TestAccAWSInstance_keyPairCheck(t *testing.T) {
|
|||
if v.KeyName == nil {
|
||||
return fmt.Errorf("No Key Pair found, expected(%s)", keyName)
|
||||
}
|
||||
if *v.KeyName != keyName {
|
||||
return fmt.Errorf("Bad key name, expected (%s), got (%s)", keyName, awsutil.StringValue(v.KeyName))
|
||||
if v.KeyName != nil && *v.KeyName != keyName {
|
||||
return fmt.Errorf("Bad key name, expected (%s), got (%s)", keyName, *v.KeyName)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
@ -43,7 +43,7 @@ func resourceAwsKinesisStreamCreate(d *schema.ResourceData, meta interface{}) er
|
|||
conn := meta.(*AWSClient).kinesisconn
|
||||
sn := d.Get("name").(string)
|
||||
createOpts := &kinesis.CreateStreamInput{
|
||||
ShardCount: aws.Long(int64(d.Get("shard_count").(int))),
|
||||
ShardCount: aws.Int64(int64(d.Get("shard_count").(int))),
|
||||
StreamName: aws.String(sn),
|
||||
}
|
||||
|
||||
|
@ -82,7 +82,7 @@ func resourceAwsKinesisStreamRead(d *schema.ResourceData, meta interface{}) erro
|
|||
conn := meta.(*AWSClient).kinesisconn
|
||||
describeOpts := &kinesis.DescribeStreamInput{
|
||||
StreamName: aws.String(d.Get("name").(string)),
|
||||
Limit: aws.Long(1),
|
||||
Limit: aws.Int64(1),
|
||||
}
|
||||
resp, err := conn.DescribeStream(describeOpts)
|
||||
if err != nil {
|
||||
|
@ -138,7 +138,7 @@ func streamStateRefreshFunc(conn *kinesis.Kinesis, sn string) resource.StateRefr
|
|||
return func() (interface{}, string, error) {
|
||||
describeOpts := &kinesis.DescribeStreamInput{
|
||||
StreamName: aws.String(sn),
|
||||
Limit: aws.Long(1),
|
||||
Limit: aws.Int64(1),
|
||||
}
|
||||
resp, err := conn.DescribeStream(describeOpts)
|
||||
if err != nil {
|
||||
|
|
|
@ -13,7 +13,7 @@ import (
|
|||
"github.com/hashicorp/terraform/terraform"
|
||||
)
|
||||
|
||||
func TestAccKinesisStream_basic(t *testing.T) {
|
||||
func TestAccAWSKinesisStream_basic(t *testing.T) {
|
||||
var stream kinesis.StreamDescription
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
|
@ -46,7 +46,7 @@ func testAccCheckKinesisStreamExists(n string, stream *kinesis.StreamDescription
|
|||
conn := testAccProvider.Meta().(*AWSClient).kinesisconn
|
||||
describeOpts := &kinesis.DescribeStreamInput{
|
||||
StreamName: aws.String(rs.Primary.Attributes["name"]),
|
||||
Limit: aws.Long(1),
|
||||
Limit: aws.Int64(1),
|
||||
}
|
||||
resp, err := conn.DescribeStream(describeOpts)
|
||||
if err != nil {
|
||||
|
@ -84,7 +84,7 @@ func testAccCheckKinesisStreamDestroy(s *terraform.State) error {
|
|||
conn := testAccProvider.Meta().(*AWSClient).kinesisconn
|
||||
describeOpts := &kinesis.DescribeStreamInput{
|
||||
StreamName: aws.String(rs.Primary.Attributes["name"]),
|
||||
Limit: aws.Long(1),
|
||||
Limit: aws.Int64(1),
|
||||
}
|
||||
resp, err := conn.DescribeStream(describeOpts)
|
||||
if err == nil {
|
||||
|
|
|
@ -112,10 +112,10 @@ func resourceAwsLambdaFunctionCreate(d *schema.ResourceData, meta interface{}) e
|
|||
Description: aws.String(d.Get("description").(string)),
|
||||
FunctionName: aws.String(functionName),
|
||||
Handler: aws.String(d.Get("handler").(string)),
|
||||
MemorySize: aws.Long(int64(d.Get("memory_size").(int))),
|
||||
MemorySize: aws.Int64(int64(d.Get("memory_size").(int))),
|
||||
Role: aws.String(iamRole),
|
||||
Runtime: aws.String(d.Get("runtime").(string)),
|
||||
Timeout: aws.Long(int64(d.Get("timeout").(int))),
|
||||
Timeout: aws.Int64(int64(d.Get("timeout").(int))),
|
||||
}
|
||||
|
||||
for i := 0; i < 5; i++ {
|
||||
|
|
|
@ -10,7 +10,7 @@ import (
|
|||
"github.com/hashicorp/terraform/terraform"
|
||||
)
|
||||
|
||||
func TestAccAWSLambdaFunction_normal(t *testing.T) {
|
||||
func TestAccAWSLambdaFunction_basic(t *testing.T) {
|
||||
var conf lambda.GetFunctionOutput
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
|
|
|
@ -264,7 +264,7 @@ func resourceAwsLaunchConfigurationCreate(d *schema.ResourceData, meta interface
|
|||
LaunchConfigurationName: aws.String(d.Get("name").(string)),
|
||||
ImageID: aws.String(d.Get("image_id").(string)),
|
||||
InstanceType: aws.String(d.Get("instance_type").(string)),
|
||||
EBSOptimized: aws.Boolean(d.Get("ebs_optimized").(bool)),
|
||||
EBSOptimized: aws.Bool(d.Get("ebs_optimized").(bool)),
|
||||
}
|
||||
|
||||
if v, ok := d.GetOk("user_data"); ok {
|
||||
|
@ -273,7 +273,7 @@ func resourceAwsLaunchConfigurationCreate(d *schema.ResourceData, meta interface
|
|||
}
|
||||
|
||||
createLaunchConfigurationOpts.InstanceMonitoring = &autoscaling.InstanceMonitoring{
|
||||
Enabled: aws.Boolean(d.Get("enable_monitoring").(bool)),
|
||||
Enabled: aws.Bool(d.Get("enable_monitoring").(bool)),
|
||||
}
|
||||
|
||||
if v, ok := d.GetOk("iam_instance_profile"); ok {
|
||||
|
@ -285,7 +285,7 @@ func resourceAwsLaunchConfigurationCreate(d *schema.ResourceData, meta interface
|
|||
}
|
||||
|
||||
if v, ok := d.GetOk("associate_public_ip_address"); ok {
|
||||
createLaunchConfigurationOpts.AssociatePublicIPAddress = aws.Boolean(v.(bool))
|
||||
createLaunchConfigurationOpts.AssociatePublicIPAddress = aws.Bool(v.(bool))
|
||||
}
|
||||
|
||||
if v, ok := d.GetOk("key_name"); ok {
|
||||
|
@ -308,7 +308,7 @@ func resourceAwsLaunchConfigurationCreate(d *schema.ResourceData, meta interface
|
|||
for _, v := range vL {
|
||||
bd := v.(map[string]interface{})
|
||||
ebs := &autoscaling.EBS{
|
||||
DeleteOnTermination: aws.Boolean(bd["delete_on_termination"].(bool)),
|
||||
DeleteOnTermination: aws.Bool(bd["delete_on_termination"].(bool)),
|
||||
}
|
||||
|
||||
if v, ok := bd["snapshot_id"].(string); ok && v != "" {
|
||||
|
@ -316,7 +316,7 @@ func resourceAwsLaunchConfigurationCreate(d *schema.ResourceData, meta interface
|
|||
}
|
||||
|
||||
if v, ok := bd["volume_size"].(int); ok && v != 0 {
|
||||
ebs.VolumeSize = aws.Long(int64(v))
|
||||
ebs.VolumeSize = aws.Int64(int64(v))
|
||||
}
|
||||
|
||||
if v, ok := bd["volume_type"].(string); ok && v != "" {
|
||||
|
@ -324,7 +324,7 @@ func resourceAwsLaunchConfigurationCreate(d *schema.ResourceData, meta interface
|
|||
}
|
||||
|
||||
if v, ok := bd["iops"].(int); ok && v > 0 {
|
||||
ebs.IOPS = aws.Long(int64(v))
|
||||
ebs.IOPS = aws.Int64(int64(v))
|
||||
}
|
||||
|
||||
blockDevices = append(blockDevices, &autoscaling.BlockDeviceMapping{
|
||||
|
@ -353,11 +353,11 @@ func resourceAwsLaunchConfigurationCreate(d *schema.ResourceData, meta interface
|
|||
for _, v := range vL {
|
||||
bd := v.(map[string]interface{})
|
||||
ebs := &autoscaling.EBS{
|
||||
DeleteOnTermination: aws.Boolean(bd["delete_on_termination"].(bool)),
|
||||
DeleteOnTermination: aws.Bool(bd["delete_on_termination"].(bool)),
|
||||
}
|
||||
|
||||
if v, ok := bd["volume_size"].(int); ok && v != 0 {
|
||||
ebs.VolumeSize = aws.Long(int64(v))
|
||||
ebs.VolumeSize = aws.Int64(int64(v))
|
||||
}
|
||||
|
||||
if v, ok := bd["volume_type"].(string); ok && v != "" {
|
||||
|
@ -365,7 +365,7 @@ func resourceAwsLaunchConfigurationCreate(d *schema.ResourceData, meta interface
|
|||
}
|
||||
|
||||
if v, ok := bd["iops"].(int); ok && v > 0 {
|
||||
ebs.IOPS = aws.Long(int64(v))
|
||||
ebs.IOPS = aws.Int64(int64(v))
|
||||
}
|
||||
|
||||
if dn, err := fetchRootDeviceName(d.Get("image_id").(string), ec2conn); err == nil {
|
||||
|
@ -480,7 +480,8 @@ func resourceAwsLaunchConfigurationDelete(d *schema.ResourceData, meta interface
|
|||
})
|
||||
if err != nil {
|
||||
autoscalingerr, ok := err.(awserr.Error)
|
||||
if ok && autoscalingerr.Code() == "InvalidConfiguration.NotFound" {
|
||||
if ok && (autoscalingerr.Code() == "InvalidConfiguration.NotFound" || autoscalingerr.Code() == "ValidationError") {
|
||||
log.Printf("[DEBUG] Launch configuration (%s) not found", d.Id())
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ func resourceAwsLBCookieStickinessPolicyCreate(d *schema.ResourceData, meta inte
|
|||
|
||||
// Provision the LBStickinessPolicy
|
||||
lbspOpts := &elb.CreateLBCookieStickinessPolicyInput{
|
||||
CookieExpirationPeriod: aws.Long(int64(d.Get("cookie_expiration_period").(int))),
|
||||
CookieExpirationPeriod: aws.Int64(int64(d.Get("cookie_expiration_period").(int))),
|
||||
LoadBalancerName: aws.String(d.Get("load_balancer").(string)),
|
||||
PolicyName: aws.String(d.Get("name").(string)),
|
||||
}
|
||||
|
@ -64,7 +64,7 @@ func resourceAwsLBCookieStickinessPolicyCreate(d *schema.ResourceData, meta inte
|
|||
|
||||
setLoadBalancerOpts := &elb.SetLoadBalancerPoliciesOfListenerInput{
|
||||
LoadBalancerName: aws.String(d.Get("load_balancer").(string)),
|
||||
LoadBalancerPort: aws.Long(int64(d.Get("lb_port").(int))),
|
||||
LoadBalancerPort: aws.Int64(int64(d.Get("lb_port").(int))),
|
||||
PolicyNames: []*string{aws.String(d.Get("name").(string))},
|
||||
}
|
||||
|
||||
|
@ -129,7 +129,7 @@ func resourceAwsLBCookieStickinessPolicyDelete(d *schema.ResourceData, meta inte
|
|||
// policy itself.
|
||||
setLoadBalancerOpts := &elb.SetLoadBalancerPoliciesOfListenerInput{
|
||||
LoadBalancerName: aws.String(d.Get("load_balancer").(string)),
|
||||
LoadBalancerPort: aws.Long(int64(d.Get("lb_port").(int))),
|
||||
LoadBalancerPort: aws.Int64(int64(d.Get("lb_port").(int))),
|
||||
PolicyNames: []*string{},
|
||||
}
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@ func resourceAwsNetworkInterface() *schema.Resource {
|
|||
Type: schema.TypeSet,
|
||||
Optional: true,
|
||||
ForceNew: true,
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{Type: schema.TypeString},
|
||||
Set: schema.HashString,
|
||||
},
|
||||
|
@ -46,6 +47,12 @@ func resourceAwsNetworkInterface() *schema.Resource {
|
|||
Set: schema.HashString,
|
||||
},
|
||||
|
||||
"source_dest_check": &schema.Schema{
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
Default: true,
|
||||
},
|
||||
|
||||
"attachment": &schema.Schema{
|
||||
Type: schema.TypeSet,
|
||||
Optional: true,
|
||||
|
@ -127,6 +134,7 @@ func resourceAwsNetworkInterfaceRead(d *schema.ResourceData, meta interface{}) e
|
|||
d.Set("subnet_id", eni.SubnetID)
|
||||
d.Set("private_ips", flattenNetworkInterfacesPrivateIPAddesses(eni.PrivateIPAddresses))
|
||||
d.Set("security_groups", flattenGroupIdentifiers(eni.Groups))
|
||||
d.Set("source_dest_check", eni.SourceDestCheck)
|
||||
|
||||
// Tags
|
||||
d.Set("tags", tagsToMap(eni.TagSet))
|
||||
|
@ -167,7 +175,7 @@ func resourceAwsNetworkInterfaceDetach(oa *schema.Set, meta interface{}, eniId s
|
|||
old_attachment := oa.List()[0].(map[string]interface{})
|
||||
detach_request := &ec2.DetachNetworkInterfaceInput{
|
||||
AttachmentID: aws.String(old_attachment["attachment_id"].(string)),
|
||||
Force: aws.Boolean(true),
|
||||
Force: aws.Bool(true),
|
||||
}
|
||||
conn := meta.(*AWSClient).ec2conn
|
||||
_, detach_err := conn.DetachNetworkInterface(detach_request)
|
||||
|
@ -208,7 +216,7 @@ func resourceAwsNetworkInterfaceUpdate(d *schema.ResourceData, meta interface{})
|
|||
new_attachment := na.(*schema.Set).List()[0].(map[string]interface{})
|
||||
di := new_attachment["device_index"].(int)
|
||||
attach_request := &ec2.AttachNetworkInterfaceInput{
|
||||
DeviceIndex: aws.Long(int64(di)),
|
||||
DeviceIndex: aws.Int64(int64(di)),
|
||||
InstanceID: aws.String(new_attachment["instance"].(string)),
|
||||
NetworkInterfaceID: aws.String(d.Id()),
|
||||
}
|
||||
|
@ -221,6 +229,18 @@ func resourceAwsNetworkInterfaceUpdate(d *schema.ResourceData, meta interface{})
|
|||
d.SetPartial("attachment")
|
||||
}
|
||||
|
||||
request := &ec2.ModifyNetworkInterfaceAttributeInput{
|
||||
NetworkInterfaceID: aws.String(d.Id()),
|
||||
SourceDestCheck: &ec2.AttributeBooleanValue{Value: aws.Bool(d.Get("source_dest_check").(bool))},
|
||||
}
|
||||
|
||||
_, err := conn.ModifyNetworkInterfaceAttribute(request)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failure updating ENI: %s", err)
|
||||
}
|
||||
|
||||
d.SetPartial("source_dest_check")
|
||||
|
||||
if d.HasChange("security_groups") {
|
||||
request := &ec2.ModifyNetworkInterfaceAttributeInput{
|
||||
NetworkInterfaceID: aws.String(d.Id()),
|
||||
|
|
|
@ -57,6 +57,46 @@ func TestAccAWSENI_attached(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestAccAWSENI_sourceDestCheck(t *testing.T) {
|
||||
var conf ec2.NetworkInterface
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckAWSENIDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
resource.TestStep{
|
||||
Config: testAccAWSENIConfigWithSourceDestCheck,
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckAWSENIExists("aws_network_interface.bar", &conf),
|
||||
resource.TestCheckResourceAttr(
|
||||
"aws_network_interface.bar", "source_dest_check", "false"),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestAccAWSENI_computedIPs(t *testing.T) {
|
||||
var conf ec2.NetworkInterface
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckAWSENIDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
resource.TestStep{
|
||||
Config: testAccAWSENIConfigWithNoPrivateIPs,
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckAWSENIExists("aws_network_interface.bar", &conf),
|
||||
resource.TestCheckResourceAttr(
|
||||
"aws_network_interface.bar", "private_ips.#", "1"),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func testAccCheckAWSENIExists(n string, res *ec2.NetworkInterface) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
rs, ok := s.RootModule().Resources[n]
|
||||
|
@ -108,6 +148,10 @@ func testAccCheckAWSENIAttributes(conf *ec2.NetworkInterface) resource.TestCheck
|
|||
return fmt.Errorf("expected private ip to be 172.16.10.100, but was %s", *conf.PrivateIPAddress)
|
||||
}
|
||||
|
||||
if *conf.SourceDestCheck != true {
|
||||
return fmt.Errorf("expected source_dest_check to be true, but was %t", *conf.SourceDestCheck)
|
||||
}
|
||||
|
||||
if len(conf.TagSet) == 0 {
|
||||
return fmt.Errorf("expected tags")
|
||||
}
|
||||
|
@ -201,6 +245,41 @@ resource "aws_network_interface" "bar" {
|
|||
}
|
||||
`
|
||||
|
||||
const testAccAWSENIConfigWithSourceDestCheck = `
|
||||
resource "aws_vpc" "foo" {
|
||||
cidr_block = "172.16.0.0/16"
|
||||
}
|
||||
|
||||
resource "aws_subnet" "foo" {
|
||||
vpc_id = "${aws_vpc.foo.id}"
|
||||
cidr_block = "172.16.10.0/24"
|
||||
availability_zone = "us-west-2a"
|
||||
}
|
||||
|
||||
resource "aws_network_interface" "bar" {
|
||||
subnet_id = "${aws_subnet.foo.id}"
|
||||
source_dest_check = false
|
||||
private_ips = ["172.16.10.100"]
|
||||
}
|
||||
`
|
||||
|
||||
const testAccAWSENIConfigWithNoPrivateIPs = `
|
||||
resource "aws_vpc" "foo" {
|
||||
cidr_block = "172.16.0.0/16"
|
||||
}
|
||||
|
||||
resource "aws_subnet" "foo" {
|
||||
vpc_id = "${aws_vpc.foo.id}"
|
||||
cidr_block = "172.16.10.0/24"
|
||||
availability_zone = "us-west-2a"
|
||||
}
|
||||
|
||||
resource "aws_network_interface" "bar" {
|
||||
subnet_id = "${aws_subnet.foo.id}"
|
||||
source_dest_check = false
|
||||
}
|
||||
`
|
||||
|
||||
const testAccAWSENIConfigWithAttachment = `
|
||||
resource "aws_vpc" "foo" {
|
||||
cidr_block = "172.16.0.0/16"
|
||||
|
|
|
@ -13,7 +13,7 @@ import (
|
|||
"github.com/aws/aws-sdk-go/service/route53"
|
||||
)
|
||||
|
||||
func TestAccRoute53DelegationSet_basic(t *testing.T) {
|
||||
func TestAccAWSRoute53DelegationSet_basic(t *testing.T) {
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
|
@ -29,7 +29,7 @@ func TestAccRoute53DelegationSet_basic(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestAccRoute53DelegationSet_withZones(t *testing.T) {
|
||||
func TestAccAWSRoute53DelegationSet_withZones(t *testing.T) {
|
||||
var zone route53.GetHostedZoneOutput
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
|
|
|
@ -68,7 +68,7 @@ func resourceAwsRoute53HealthCheckUpdate(d *schema.ResourceData, meta interface{
|
|||
}
|
||||
|
||||
if d.HasChange("failure_threshold") {
|
||||
updateHealthCheck.FailureThreshold = aws.Long(int64(d.Get("failure_threshold").(int)))
|
||||
updateHealthCheck.FailureThreshold = aws.Int64(int64(d.Get("failure_threshold").(int)))
|
||||
}
|
||||
|
||||
if d.HasChange("fqdn") {
|
||||
|
@ -76,7 +76,7 @@ func resourceAwsRoute53HealthCheckUpdate(d *schema.ResourceData, meta interface{
|
|||
}
|
||||
|
||||
if d.HasChange("port") {
|
||||
updateHealthCheck.Port = aws.Long(int64(d.Get("port").(int)))
|
||||
updateHealthCheck.Port = aws.Int64(int64(d.Get("port").(int)))
|
||||
}
|
||||
|
||||
if d.HasChange("resource_path") {
|
||||
|
@ -104,8 +104,8 @@ func resourceAwsRoute53HealthCheckCreate(d *schema.ResourceData, meta interface{
|
|||
|
||||
healthConfig := &route53.HealthCheckConfig{
|
||||
Type: aws.String(d.Get("type").(string)),
|
||||
FailureThreshold: aws.Long(int64(d.Get("failure_threshold").(int))),
|
||||
RequestInterval: aws.Long(int64(d.Get("request_interval").(int))),
|
||||
FailureThreshold: aws.Int64(int64(d.Get("failure_threshold").(int))),
|
||||
RequestInterval: aws.Int64(int64(d.Get("request_interval").(int))),
|
||||
}
|
||||
|
||||
if v, ok := d.GetOk("fqdn"); ok {
|
||||
|
@ -121,7 +121,7 @@ func resourceAwsRoute53HealthCheckCreate(d *schema.ResourceData, meta interface{
|
|||
}
|
||||
|
||||
if v, ok := d.GetOk("port"); ok {
|
||||
healthConfig.Port = aws.Long(int64(v.(int)))
|
||||
healthConfig.Port = aws.Int64(int64(v.(int)))
|
||||
}
|
||||
|
||||
if v, ok := d.GetOk("resource_path"); ok {
|
||||
|
|
|
@ -10,7 +10,7 @@ import (
|
|||
"github.com/aws/aws-sdk-go/service/route53"
|
||||
)
|
||||
|
||||
func TestAccRoute53HealthCheck_basic(t *testing.T) {
|
||||
func TestAccAWSRoute53HealthCheck_basic(t *testing.T) {
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
|
@ -34,7 +34,7 @@ func TestAccRoute53HealthCheck_basic(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestAccRoute53HealthCheck_IpConfig(t *testing.T) {
|
||||
func TestAccAWSRoute53HealthCheck_IpConfig(t *testing.T) {
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
|
|
|
@ -367,7 +367,7 @@ func resourceAwsRoute53RecordBuildSet(d *schema.ResourceData, zoneName string) (
|
|||
}
|
||||
|
||||
if v, ok := d.GetOk("ttl"); ok {
|
||||
rec.TTL = aws.Long(int64(v.(int)))
|
||||
rec.TTL = aws.Int64(int64(v.(int)))
|
||||
}
|
||||
|
||||
// Resource records
|
||||
|
@ -385,7 +385,7 @@ func resourceAwsRoute53RecordBuildSet(d *schema.ResourceData, zoneName string) (
|
|||
alias := aliases[0].(map[string]interface{})
|
||||
rec.AliasTarget = &route53.AliasTarget{
|
||||
DNSName: aws.String(alias["name"].(string)),
|
||||
EvaluateTargetHealth: aws.Boolean(alias["evaluate_target_health"].(bool)),
|
||||
EvaluateTargetHealth: aws.Bool(alias["evaluate_target_health"].(bool)),
|
||||
HostedZoneID: aws.String(alias["zone_id"].(string)),
|
||||
}
|
||||
log.Printf("[DEBUG] Creating alias: %#v", alias)
|
||||
|
@ -408,7 +408,7 @@ func resourceAwsRoute53RecordBuildSet(d *schema.ResourceData, zoneName string) (
|
|||
}
|
||||
|
||||
if v, ok := d.GetOk("weight"); ok {
|
||||
rec.Weight = aws.Long(int64(v.(int)))
|
||||
rec.Weight = aws.Int64(int64(v.(int)))
|
||||
}
|
||||
|
||||
if v, ok := d.GetOk("set_identifier"); ok {
|
||||
|
|
|
@ -50,7 +50,7 @@ func TestExpandRecordName(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestAccRoute53Record_basic(t *testing.T) {
|
||||
func TestAccAWSRoute53Record_basic(t *testing.T) {
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
|
@ -66,7 +66,7 @@ func TestAccRoute53Record_basic(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestAccRoute53Record_txtSupport(t *testing.T) {
|
||||
func TestAccAWSRoute53Record_txtSupport(t *testing.T) {
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
|
@ -82,7 +82,7 @@ func TestAccRoute53Record_txtSupport(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestAccRoute53Record_generatesSuffix(t *testing.T) {
|
||||
func TestAccAWSRoute53Record_generatesSuffix(t *testing.T) {
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
|
@ -98,7 +98,7 @@ func TestAccRoute53Record_generatesSuffix(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestAccRoute53Record_wildcard(t *testing.T) {
|
||||
func TestAccAWSRoute53Record_wildcard(t *testing.T) {
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
|
@ -122,7 +122,7 @@ func TestAccRoute53Record_wildcard(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestAccRoute53Record_weighted(t *testing.T) {
|
||||
func TestAccAWSRoute53Record_weighted(t *testing.T) {
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
|
@ -139,7 +139,7 @@ func TestAccRoute53Record_weighted(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestAccRoute53Record_alias(t *testing.T) {
|
||||
func TestAccAWSRoute53Record_alias(t *testing.T) {
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
|
@ -155,7 +155,23 @@ func TestAccRoute53Record_alias(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestAccRoute53Record_weighted_alias(t *testing.T) {
|
||||
func TestAccAWSRoute53Record_s3_alias(t *testing.T) {
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckRoute53RecordDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
resource.TestStep{
|
||||
Config: testAccRoute53S3AliasRecord,
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckRoute53RecordExists("aws_route53_record.alias"),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestAccAWSRoute53Record_weighted_alias(t *testing.T) {
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
|
@ -182,7 +198,7 @@ func TestAccRoute53Record_weighted_alias(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestAccRoute53Record_TypeChange(t *testing.T) {
|
||||
func TestAccAWSRoute53Record_TypeChange(t *testing.T) {
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
|
@ -449,6 +465,32 @@ resource "aws_route53_record" "alias" {
|
|||
}
|
||||
`
|
||||
|
||||
const testAccRoute53S3AliasRecord = `
|
||||
resource "aws_route53_zone" "main" {
|
||||
name = "notexample.com"
|
||||
}
|
||||
|
||||
resource "aws_s3_bucket" "website" {
|
||||
bucket = "website.notexample.com"
|
||||
acl = "public-read"
|
||||
website {
|
||||
index_document = "index.html"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_route53_record" "alias" {
|
||||
zone_id = "${aws_route53_zone.main.zone_id}"
|
||||
name = "www"
|
||||
type = "A"
|
||||
|
||||
alias {
|
||||
zone_id = "${aws_s3_bucket.website.hosted_zone_id}"
|
||||
name = "${aws_s3_bucket.website.website_domain}"
|
||||
evaluate_target_health = true
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
const testAccRoute53WeightedElbAliasRecord = `
|
||||
resource "aws_route53_zone" "main" {
|
||||
name = "notexample.com"
|
||||
|
|
|
@ -12,7 +12,7 @@ import (
|
|||
"github.com/aws/aws-sdk-go/service/route53"
|
||||
)
|
||||
|
||||
func TestAccRoute53ZoneAssociation_basic(t *testing.T) {
|
||||
func TestAccAWSRoute53ZoneAssociation_basic(t *testing.T) {
|
||||
var zone route53.HostedZone
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
|
@ -30,7 +30,7 @@ func TestAccRoute53ZoneAssociation_basic(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestAccRoute53ZoneAssociation_region(t *testing.T) {
|
||||
func TestAccAWSRoute53ZoneAssociation_region(t *testing.T) {
|
||||
var zone route53.HostedZone
|
||||
|
||||
// record the initialized providers so that we can use them to
|
||||
|
|
|
@ -64,7 +64,7 @@ func TestCleanChangeID(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestAccRoute53Zone_basic(t *testing.T) {
|
||||
func TestAccAWSRoute53Zone_basic(t *testing.T) {
|
||||
var zone route53.GetHostedZoneOutput
|
||||
var td route53.ResourceTagSet
|
||||
|
||||
|
@ -85,7 +85,7 @@ func TestAccRoute53Zone_basic(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestAccRoute53Zone_private_basic(t *testing.T) {
|
||||
func TestAccAWSRoute53Zone_private_basic(t *testing.T) {
|
||||
var zone route53.GetHostedZoneOutput
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
|
@ -104,7 +104,7 @@ func TestAccRoute53Zone_private_basic(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestAccRoute53Zone_private_region(t *testing.T) {
|
||||
func TestAccAWSRoute53Zone_private_region(t *testing.T) {
|
||||
var zone route53.GetHostedZoneOutput
|
||||
|
||||
// record the initialized providers so that we can use them to
|
||||
|
|
|
@ -77,12 +77,16 @@ func resourceAwsS3Bucket() *schema.Resource {
|
|||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
|
||||
"website_endpoint": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
"website_domain": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
|
||||
"tags": tagsSchema(),
|
||||
|
||||
|
@ -237,12 +241,17 @@ func resourceAwsS3BucketRead(d *schema.ResourceData, meta interface{}) error {
|
|||
}
|
||||
|
||||
// Add website_endpoint as an attribute
|
||||
endpoint, err := websiteEndpoint(s3conn, d)
|
||||
websiteEndpoint, err := websiteEndpoint(s3conn, d)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := d.Set("website_endpoint", endpoint); err != nil {
|
||||
return err
|
||||
if websiteEndpoint != nil {
|
||||
if err := d.Set("website_endpoint", websiteEndpoint.Endpoint); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := d.Set("website_domain", websiteEndpoint.Domain); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
tagSet, err := getTagSetS3(s3conn, d.Id())
|
||||
|
@ -405,11 +414,11 @@ func resourceAwsS3BucketWebsiteDelete(s3conn *s3.S3, d *schema.ResourceData) err
|
|||
return nil
|
||||
}
|
||||
|
||||
func websiteEndpoint(s3conn *s3.S3, d *schema.ResourceData) (string, error) {
|
||||
func websiteEndpoint(s3conn *s3.S3, d *schema.ResourceData) (*S3Website, error) {
|
||||
// If the bucket doesn't have a website configuration, return an empty
|
||||
// endpoint
|
||||
if _, ok := d.GetOk("website"); !ok {
|
||||
return "", nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
bucket := d.Get("bucket").(string)
|
||||
|
@ -421,26 +430,31 @@ func websiteEndpoint(s3conn *s3.S3, d *schema.ResourceData) (string, error) {
|
|||
},
|
||||
)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return nil, err
|
||||
}
|
||||
var region string
|
||||
if location.LocationConstraint != nil {
|
||||
region = *location.LocationConstraint
|
||||
}
|
||||
|
||||
return WebsiteEndpointUrl(bucket, region), nil
|
||||
return WebsiteEndpoint(bucket, region), nil
|
||||
}
|
||||
|
||||
func WebsiteEndpointUrl(bucket string, region string) string {
|
||||
func WebsiteEndpoint(bucket string, region string) *S3Website {
|
||||
domain := WebsiteDomainUrl(region)
|
||||
return &S3Website{Endpoint: fmt.Sprintf("%s.%s", bucket, domain), Domain: domain}
|
||||
}
|
||||
|
||||
func WebsiteDomainUrl(region string) string {
|
||||
region = normalizeRegion(region)
|
||||
|
||||
// Frankfurt(and probably future) regions uses different syntax for website endpoints
|
||||
// http://docs.aws.amazon.com/AmazonS3/latest/dev/WebsiteEndpoints.html
|
||||
if region == "eu-central-1" {
|
||||
return fmt.Sprintf("%s.s3-website.%s.amazonaws.com", bucket, region)
|
||||
return fmt.Sprintf("s3-website.%s.amazonaws.com", region)
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s.s3-website-%s.amazonaws.com", bucket, region)
|
||||
return fmt.Sprintf("s3-website-%s.amazonaws.com", region)
|
||||
}
|
||||
|
||||
func normalizeJson(jsonString interface{}) string {
|
||||
|
@ -465,3 +479,7 @@ func normalizeRegion(region string) string {
|
|||
|
||||
return region
|
||||
}
|
||||
|
||||
type S3Website struct {
|
||||
Endpoint, Domain string
|
||||
}
|
||||
|
|
|
@ -223,8 +223,8 @@ func resourceAwsSecurityGroupCreate(d *schema.ResourceData, meta interface{}) er
|
|||
GroupID: createResp.GroupID,
|
||||
IPPermissions: []*ec2.IPPermission{
|
||||
&ec2.IPPermission{
|
||||
FromPort: aws.Long(int64(0)),
|
||||
ToPort: aws.Long(int64(0)),
|
||||
FromPort: aws.Int64(int64(0)),
|
||||
ToPort: aws.Int64(int64(0)),
|
||||
IPRanges: []*ec2.IPRange{
|
||||
&ec2.IPRange{
|
||||
CIDRIP: aws.String("0.0.0.0/0"),
|
||||
|
|
|
@ -9,7 +9,6 @@ import (
|
|||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/aws/awsutil"
|
||||
"github.com/aws/aws-sdk-go/service/ec2"
|
||||
"github.com/hashicorp/terraform/helper/hashcode"
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
|
@ -98,7 +97,7 @@ func resourceAwsSecurityGroupRuleCreate(d *schema.ResourceData, meta interface{}
|
|||
switch ruleType {
|
||||
case "ingress":
|
||||
log.Printf("[DEBUG] Authorizing security group %s %s rule: %s",
|
||||
sg_id, "Ingress", awsutil.StringValue(perm))
|
||||
sg_id, "Ingress", perm)
|
||||
|
||||
req := &ec2.AuthorizeSecurityGroupIngressInput{
|
||||
GroupID: sg.GroupID,
|
||||
|
@ -213,7 +212,7 @@ func resourceAwsSecurityGroupRuleDelete(d *schema.ResourceData, meta interface{}
|
|||
switch ruleType {
|
||||
case "ingress":
|
||||
log.Printf("[DEBUG] Revoking rule (%s) from security group %s:\n%s",
|
||||
"ingress", sg_id, awsutil.StringValue(perm))
|
||||
"ingress", sg_id, perm)
|
||||
req := &ec2.RevokeSecurityGroupIngressInput{
|
||||
GroupID: sg.GroupID,
|
||||
IPPermissions: []*ec2.IPPermission{perm},
|
||||
|
@ -330,8 +329,8 @@ func ipPermissionIDHash(ruleType string, ip *ec2.IPPermission) string {
|
|||
func expandIPPerm(d *schema.ResourceData, sg *ec2.SecurityGroup) *ec2.IPPermission {
|
||||
var perm ec2.IPPermission
|
||||
|
||||
perm.FromPort = aws.Long(int64(d.Get("from_port").(int)))
|
||||
perm.ToPort = aws.Long(int64(d.Get("to_port").(int)))
|
||||
perm.FromPort = aws.Int64(int64(d.Get("from_port").(int)))
|
||||
perm.ToPort = aws.Int64(int64(d.Get("to_port").(int)))
|
||||
perm.IPProtocol = aws.String(d.Get("protocol").(string))
|
||||
|
||||
// build a group map that behaves like a set
|
||||
|
|
|
@ -56,8 +56,8 @@ func migrateExpandIPPerm(attrs map[string]string) (*ec2.IPPermission, error) {
|
|||
return nil, fmt.Errorf("Error converting from_port in Security Group migration")
|
||||
}
|
||||
|
||||
perm.ToPort = aws.Long(int64(tp))
|
||||
perm.FromPort = aws.Long(int64(fp))
|
||||
perm.ToPort = aws.Int64(int64(tp))
|
||||
perm.FromPort = aws.Int64(int64(fp))
|
||||
perm.IPProtocol = aws.String(attrs["protocol"])
|
||||
|
||||
groups := make(map[string]bool)
|
||||
|
|
|
@ -7,7 +7,6 @@ import (
|
|||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/aws/awsutil"
|
||||
"github.com/aws/aws-sdk-go/service/ec2"
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"github.com/hashicorp/terraform/terraform"
|
||||
|
@ -16,8 +15,8 @@ import (
|
|||
func TestIpPermissionIDHash(t *testing.T) {
|
||||
simple := &ec2.IPPermission{
|
||||
IPProtocol: aws.String("tcp"),
|
||||
FromPort: aws.Long(int64(80)),
|
||||
ToPort: aws.Long(int64(8000)),
|
||||
FromPort: aws.Int64(int64(80)),
|
||||
ToPort: aws.Int64(int64(8000)),
|
||||
IPRanges: []*ec2.IPRange{
|
||||
&ec2.IPRange{
|
||||
CIDRIP: aws.String("10.0.0.0/8"),
|
||||
|
@ -27,8 +26,8 @@ func TestIpPermissionIDHash(t *testing.T) {
|
|||
|
||||
egress := &ec2.IPPermission{
|
||||
IPProtocol: aws.String("tcp"),
|
||||
FromPort: aws.Long(int64(80)),
|
||||
ToPort: aws.Long(int64(8000)),
|
||||
FromPort: aws.Int64(int64(80)),
|
||||
ToPort: aws.Int64(int64(8000)),
|
||||
IPRanges: []*ec2.IPRange{
|
||||
&ec2.IPRange{
|
||||
CIDRIP: aws.String("10.0.0.0/8"),
|
||||
|
@ -47,8 +46,8 @@ func TestIpPermissionIDHash(t *testing.T) {
|
|||
|
||||
vpc_security_group_source := &ec2.IPPermission{
|
||||
IPProtocol: aws.String("tcp"),
|
||||
FromPort: aws.Long(int64(80)),
|
||||
ToPort: aws.Long(int64(8000)),
|
||||
FromPort: aws.Int64(int64(80)),
|
||||
ToPort: aws.Int64(int64(8000)),
|
||||
UserIDGroupPairs: []*ec2.UserIDGroupPair{
|
||||
&ec2.UserIDGroupPair{
|
||||
UserID: aws.String("987654321"),
|
||||
|
@ -67,8 +66,8 @@ func TestIpPermissionIDHash(t *testing.T) {
|
|||
|
||||
security_group_source := &ec2.IPPermission{
|
||||
IPProtocol: aws.String("tcp"),
|
||||
FromPort: aws.Long(int64(80)),
|
||||
ToPort: aws.Long(int64(8000)),
|
||||
FromPort: aws.Int64(int64(80)),
|
||||
ToPort: aws.Int64(int64(8000)),
|
||||
UserIDGroupPairs: []*ec2.UserIDGroupPair{
|
||||
&ec2.UserIDGroupPair{
|
||||
UserID: aws.String("987654321"),
|
||||
|
@ -101,7 +100,7 @@ func TestIpPermissionIDHash(t *testing.T) {
|
|||
for _, tc := range cases {
|
||||
actual := ipPermissionIDHash(tc.Type, tc.Input)
|
||||
if actual != tc.Output {
|
||||
t.Errorf("input: %s - %s\noutput: %s", tc.Type, awsutil.StringValue(tc.Input), actual)
|
||||
t.Errorf("input: %s - %s\noutput: %s", tc.Type, tc.Input, actual)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -323,8 +322,8 @@ func testAccCheckAWSSecurityGroupRuleExists(n string, group *ec2.SecurityGroup)
|
|||
func testAccCheckAWSSecurityGroupRuleAttributes(group *ec2.SecurityGroup, ruleType string) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
p := &ec2.IPPermission{
|
||||
FromPort: aws.Long(80),
|
||||
ToPort: aws.Long(8000),
|
||||
FromPort: aws.Int64(80),
|
||||
ToPort: aws.Int64(8000),
|
||||
IPProtocol: aws.String("tcp"),
|
||||
IPRanges: []*ec2.IPRange{&ec2.IPRange{CIDRIP: aws.String("10.0.0.0/8")}},
|
||||
}
|
||||
|
|
|
@ -356,8 +356,8 @@ func testAccCheckAWSSecurityGroupExists(n string, group *ec2.SecurityGroup) reso
|
|||
func testAccCheckAWSSecurityGroupAttributes(group *ec2.SecurityGroup) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
p := &ec2.IPPermission{
|
||||
FromPort: aws.Long(80),
|
||||
ToPort: aws.Long(8000),
|
||||
FromPort: aws.Int64(80),
|
||||
ToPort: aws.Int64(8000),
|
||||
IPProtocol: aws.String("tcp"),
|
||||
IPRanges: []*ec2.IPRange{&ec2.IPRange{CIDRIP: aws.String("10.0.0.0/8")}},
|
||||
}
|
||||
|
@ -449,14 +449,14 @@ func testAccCheckAWSSecurityGroupAttributesChanged(group *ec2.SecurityGroup) res
|
|||
return func(s *terraform.State) error {
|
||||
p := []*ec2.IPPermission{
|
||||
&ec2.IPPermission{
|
||||
FromPort: aws.Long(80),
|
||||
ToPort: aws.Long(9000),
|
||||
FromPort: aws.Int64(80),
|
||||
ToPort: aws.Int64(9000),
|
||||
IPProtocol: aws.String("tcp"),
|
||||
IPRanges: []*ec2.IPRange{&ec2.IPRange{CIDRIP: aws.String("10.0.0.0/8")}},
|
||||
},
|
||||
&ec2.IPPermission{
|
||||
FromPort: aws.Long(80),
|
||||
ToPort: aws.Long(8000),
|
||||
FromPort: aws.Int64(80),
|
||||
ToPort: aws.Int64(8000),
|
||||
IPProtocol: aws.String("tcp"),
|
||||
IPRanges: []*ec2.IPRange{
|
||||
&ec2.IPRange{
|
||||
|
|
|
@ -7,7 +7,6 @@ import (
|
|||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/aws/awsutil"
|
||||
"github.com/aws/aws-sdk-go/service/ec2"
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
|
@ -78,7 +77,7 @@ func resourceAwsSpotInstanceRequestCreate(d *schema.ResourceData, meta interface
|
|||
// Though the AWS API supports creating spot instance requests for multiple
|
||||
// instances, for TF purposes we fix this to one instance per request.
|
||||
// Users can get equivalent behavior out of TF's "count" meta-parameter.
|
||||
InstanceCount: aws.Long(1),
|
||||
InstanceCount: aws.Int64(1),
|
||||
|
||||
LaunchSpecification: &ec2.RequestSpotLaunchSpecification{
|
||||
BlockDeviceMappings: instanceOpts.BlockDeviceMappings,
|
||||
|
@ -95,14 +94,14 @@ func resourceAwsSpotInstanceRequestCreate(d *schema.ResourceData, meta interface
|
|||
}
|
||||
|
||||
// Make the spot instance request
|
||||
log.Printf("[DEBUG] Requesting spot bid opts: %s", awsutil.StringValue(spotOpts))
|
||||
log.Printf("[DEBUG] Requesting spot bid opts: %s", spotOpts)
|
||||
resp, err := conn.RequestSpotInstances(spotOpts)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error requesting spot instances: %s", err)
|
||||
}
|
||||
if len(resp.SpotInstanceRequests) != 1 {
|
||||
return fmt.Errorf(
|
||||
"Expected response with length 1, got: %s", awsutil.StringValue(resp))
|
||||
"Expected response with length 1, got: %s", resp)
|
||||
}
|
||||
|
||||
sir := *resp.SpotInstanceRequests[0]
|
||||
|
@ -123,7 +122,7 @@ func resourceAwsSpotInstanceRequestCreate(d *schema.ResourceData, meta interface
|
|||
_, err = spotStateConf.WaitForState()
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error while waiting for spot request (%s) to resolve: %s", awsutil.StringValue(sir), err)
|
||||
return fmt.Errorf("Error while waiting for spot request (%s) to resolve: %s", sir, err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -160,7 +159,7 @@ func resourceAwsSpotInstanceRequestRead(d *schema.ResourceData, meta interface{}
|
|||
request := resp.SpotInstanceRequests[0]
|
||||
|
||||
// if the request is cancelled, then it is gone
|
||||
if *request.State == "canceled" {
|
||||
if *request.State == "cancelled" {
|
||||
d.SetId("")
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -137,7 +137,7 @@ func resourceAwsSubnetUpdate(d *schema.ResourceData, meta interface{}) error {
|
|||
modifyOpts := &ec2.ModifySubnetAttributeInput{
|
||||
SubnetID: aws.String(d.Id()),
|
||||
MapPublicIPOnLaunch: &ec2.AttributeBooleanValue{
|
||||
Value: aws.Boolean(d.Get("map_public_ip_on_launch").(bool)),
|
||||
Value: aws.Bool(d.Get("map_public_ip_on_launch").(bool)),
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -157,7 +157,7 @@ func resourceAwsVolumeAttachmentDelete(d *schema.ResourceData, meta interface{})
|
|||
Device: aws.String(d.Get("device_name").(string)),
|
||||
InstanceID: aws.String(iID),
|
||||
VolumeID: aws.String(vID),
|
||||
Force: aws.Boolean(d.Get("force_detach").(bool)),
|
||||
Force: aws.Bool(d.Get("force_detach").(bool)),
|
||||
}
|
||||
|
||||
_, err := conn.DetachVolume(opts)
|
||||
|
|
|
@ -11,7 +11,7 @@ import (
|
|||
"github.com/hashicorp/terraform/terraform"
|
||||
)
|
||||
|
||||
func TestAccDHCPOptions_basic(t *testing.T) {
|
||||
func TestAccAWSDHCPOptions_basic(t *testing.T) {
|
||||
var d ec2.DHCPOptions
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
|
|
|
@ -11,7 +11,7 @@ import (
|
|||
"github.com/hashicorp/terraform/terraform"
|
||||
)
|
||||
|
||||
func TestAccVpcEndpoint_basic(t *testing.T) {
|
||||
func TestAccAWSVpcEndpoint_basic(t *testing.T) {
|
||||
var endpoint ec2.VPCEndpoint
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
|
@ -29,7 +29,7 @@ func TestAccVpcEndpoint_basic(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestAccVpcEndpoint_withRouteTableAndPolicy(t *testing.T) {
|
||||
func TestAccAWSVpcEndpoint_withRouteTableAndPolicy(t *testing.T) {
|
||||
var endpoint ec2.VPCEndpoint
|
||||
var routeTable ec2.RouteTable
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ import (
|
|||
"github.com/hashicorp/terraform/terraform"
|
||||
)
|
||||
|
||||
func TestAccVpc_basic(t *testing.T) {
|
||||
func TestAccAWSVpc_basic(t *testing.T) {
|
||||
var vpc ec2.VPC
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
|
@ -32,7 +32,7 @@ func TestAccVpc_basic(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestAccVpc_dedicatedTenancy(t *testing.T) {
|
||||
func TestAccAWSVpc_dedicatedTenancy(t *testing.T) {
|
||||
var vpc ec2.VPC
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
|
@ -52,7 +52,7 @@ func TestAccVpc_dedicatedTenancy(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestAccVpc_tags(t *testing.T) {
|
||||
func TestAccAWSVpc_tags(t *testing.T) {
|
||||
var vpc ec2.VPC
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
|
@ -83,7 +83,7 @@ func TestAccVpc_tags(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestAccVpcUpdate(t *testing.T) {
|
||||
func TestAccAWSVpc_update(t *testing.T) {
|
||||
var vpc ec2.VPC
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
|
@ -187,7 +187,7 @@ func testAccCheckVpcExists(n string, vpc *ec2.VPC) resource.TestCheckFunc {
|
|||
}
|
||||
|
||||
// https://github.com/hashicorp/terraform/issues/1301
|
||||
func TestAccVpc_bothDnsOptionsSet(t *testing.T) {
|
||||
func TestAccAWSVpc_bothDnsOptionsSet(t *testing.T) {
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
|
|
|
@ -143,7 +143,7 @@ func resourceAwsVpnConnectionCreate(d *schema.ResourceData, meta interface{}) er
|
|||
conn := meta.(*AWSClient).ec2conn
|
||||
|
||||
connectOpts := &ec2.VPNConnectionOptionsSpecification{
|
||||
StaticRoutesOnly: aws.Boolean(d.Get("static_routes_only").(bool)),
|
||||
StaticRoutesOnly: aws.Bool(d.Get("static_routes_only").(bool)),
|
||||
}
|
||||
|
||||
createOpts := &ec2.CreateVPNConnectionInput{
|
||||
|
|
|
@ -87,7 +87,7 @@ func TestAccAWSVpnGateway_delete(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestAccVpnGateway_tags(t *testing.T) {
|
||||
func TestAccAWSVpnGateway_tags(t *testing.T) {
|
||||
var v ec2.VPNGateway
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
|
|
|
@ -94,7 +94,7 @@ func expandEcsLoadBalancers(configured []interface{}) []*ecs.LoadBalancer {
|
|||
|
||||
l := &ecs.LoadBalancer{
|
||||
ContainerName: aws.String(data["container_name"].(string)),
|
||||
ContainerPort: aws.Long(int64(data["container_port"].(int))),
|
||||
ContainerPort: aws.Int64(int64(data["container_port"].(int))),
|
||||
LoadBalancerName: aws.String(data["elb_name"].(string)),
|
||||
}
|
||||
|
||||
|
@ -117,8 +117,8 @@ func expandIPPerms(
|
|||
var perm ec2.IPPermission
|
||||
m := mRaw.(map[string]interface{})
|
||||
|
||||
perm.FromPort = aws.Long(int64(m["from_port"].(int)))
|
||||
perm.ToPort = aws.Long(int64(m["to_port"].(int)))
|
||||
perm.FromPort = aws.Int64(int64(m["from_port"].(int)))
|
||||
perm.ToPort = aws.Int64(int64(m["to_port"].(int)))
|
||||
perm.IPProtocol = aws.String(m["protocol"].(string))
|
||||
|
||||
// When protocol is "-1", AWS won't store any ports for the
|
||||
|
@ -405,7 +405,7 @@ func expandPrivateIPAddesses(ips []interface{}) []*ec2.PrivateIPAddressSpecifica
|
|||
PrivateIPAddress: aws.String(v.(string)),
|
||||
}
|
||||
|
||||
new_private_ip.Primary = aws.Boolean(i == 0)
|
||||
new_private_ip.Primary = aws.Bool(i == 0)
|
||||
|
||||
dtos = append(dtos, new_private_ip)
|
||||
}
|
||||
|
|
|
@ -70,8 +70,8 @@ func TestexpandIPPerms(t *testing.T) {
|
|||
expected := []ec2.IPPermission{
|
||||
ec2.IPPermission{
|
||||
IPProtocol: aws.String("icmp"),
|
||||
FromPort: aws.Long(int64(1)),
|
||||
ToPort: aws.Long(int64(-1)),
|
||||
FromPort: aws.Int64(int64(1)),
|
||||
ToPort: aws.Int64(int64(-1)),
|
||||
IPRanges: []*ec2.IPRange{&ec2.IPRange{CIDRIP: aws.String("0.0.0.0/0")}},
|
||||
UserIDGroupPairs: []*ec2.UserIDGroupPair{
|
||||
&ec2.UserIDGroupPair{
|
||||
|
@ -85,8 +85,8 @@ func TestexpandIPPerms(t *testing.T) {
|
|||
},
|
||||
ec2.IPPermission{
|
||||
IPProtocol: aws.String("icmp"),
|
||||
FromPort: aws.Long(int64(1)),
|
||||
ToPort: aws.Long(int64(-1)),
|
||||
FromPort: aws.Int64(int64(1)),
|
||||
ToPort: aws.Int64(int64(-1)),
|
||||
UserIDGroupPairs: []*ec2.UserIDGroupPair{
|
||||
&ec2.UserIDGroupPair{
|
||||
UserID: aws.String("foo"),
|
||||
|
@ -149,8 +149,8 @@ func TestExpandIPPerms_NegOneProtocol(t *testing.T) {
|
|||
expected := []ec2.IPPermission{
|
||||
ec2.IPPermission{
|
||||
IPProtocol: aws.String("-1"),
|
||||
FromPort: aws.Long(int64(0)),
|
||||
ToPort: aws.Long(int64(0)),
|
||||
FromPort: aws.Int64(int64(0)),
|
||||
ToPort: aws.Int64(int64(0)),
|
||||
IPRanges: []*ec2.IPRange{&ec2.IPRange{CIDRIP: aws.String("0.0.0.0/0")}},
|
||||
UserIDGroupPairs: []*ec2.UserIDGroupPair{
|
||||
&ec2.UserIDGroupPair{
|
||||
|
@ -245,8 +245,8 @@ func TestExpandIPPerms_nonVPC(t *testing.T) {
|
|||
expected := []ec2.IPPermission{
|
||||
ec2.IPPermission{
|
||||
IPProtocol: aws.String("icmp"),
|
||||
FromPort: aws.Long(int64(1)),
|
||||
ToPort: aws.Long(int64(-1)),
|
||||
FromPort: aws.Int64(int64(1)),
|
||||
ToPort: aws.Int64(int64(-1)),
|
||||
IPRanges: []*ec2.IPRange{&ec2.IPRange{CIDRIP: aws.String("0.0.0.0/0")}},
|
||||
UserIDGroupPairs: []*ec2.UserIDGroupPair{
|
||||
&ec2.UserIDGroupPair{
|
||||
|
@ -259,8 +259,8 @@ func TestExpandIPPerms_nonVPC(t *testing.T) {
|
|||
},
|
||||
ec2.IPPermission{
|
||||
IPProtocol: aws.String("icmp"),
|
||||
FromPort: aws.Long(int64(1)),
|
||||
ToPort: aws.Long(int64(-1)),
|
||||
FromPort: aws.Int64(int64(1)),
|
||||
ToPort: aws.Int64(int64(-1)),
|
||||
UserIDGroupPairs: []*ec2.UserIDGroupPair{
|
||||
&ec2.UserIDGroupPair{
|
||||
GroupName: aws.String("foo"),
|
||||
|
@ -302,8 +302,8 @@ func TestexpandListeners(t *testing.T) {
|
|||
}
|
||||
|
||||
expected := &elb.Listener{
|
||||
InstancePort: aws.Long(int64(8000)),
|
||||
LoadBalancerPort: aws.Long(int64(80)),
|
||||
InstancePort: aws.Int64(int64(8000)),
|
||||
LoadBalancerPort: aws.Int64(int64(80)),
|
||||
InstanceProtocol: aws.String("http"),
|
||||
Protocol: aws.String("http"),
|
||||
}
|
||||
|
@ -324,11 +324,11 @@ func TestflattenHealthCheck(t *testing.T) {
|
|||
}{
|
||||
{
|
||||
Input: &elb.HealthCheck{
|
||||
UnhealthyThreshold: aws.Long(int64(10)),
|
||||
HealthyThreshold: aws.Long(int64(10)),
|
||||
UnhealthyThreshold: aws.Int64(int64(10)),
|
||||
HealthyThreshold: aws.Int64(int64(10)),
|
||||
Target: aws.String("HTTP:80/"),
|
||||
Timeout: aws.Long(int64(30)),
|
||||
Interval: aws.Long(int64(30)),
|
||||
Timeout: aws.Int64(int64(30)),
|
||||
Interval: aws.Int64(int64(30)),
|
||||
},
|
||||
Output: []map[string]interface{}{
|
||||
map[string]interface{}{
|
||||
|
@ -570,7 +570,7 @@ func TestexpandPrivateIPAddesses(t *testing.T) {
|
|||
func TestflattenAttachment(t *testing.T) {
|
||||
expanded := &ec2.NetworkInterfaceAttachment{
|
||||
InstanceID: aws.String("i-00001"),
|
||||
DeviceIndex: aws.Long(int64(1)),
|
||||
DeviceIndex: aws.Int64(int64(1)),
|
||||
AttachmentID: aws.String("at-002"),
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@ import (
|
|||
"log"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awsutil"
|
||||
"github.com/aws/aws-sdk-go/service/ec2"
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
)
|
||||
|
@ -39,7 +38,7 @@ func setTags(conn *ec2.EC2, d *schema.ResourceData) error {
|
|||
}
|
||||
}
|
||||
if len(create) > 0 {
|
||||
log.Printf("[DEBUG] Creating tags: %s for %s", awsutil.StringValue(create), d.Id())
|
||||
log.Printf("[DEBUG] Creating tags: %s for %s", create, d.Id())
|
||||
_, err := conn.CreateTags(&ec2.CreateTagsInput{
|
||||
Resources: []*string{aws.String(d.Id())},
|
||||
Tags: create,
|
||||
|
|
|
@ -20,9 +20,9 @@ var websiteEndpoints = []struct {
|
|||
|
||||
func TestWebsiteEndpointUrl(t *testing.T) {
|
||||
for _, tt := range websiteEndpoints {
|
||||
s := WebsiteEndpointUrl("bucket-name", tt.in)
|
||||
if s != tt.out {
|
||||
t.Errorf("WebsiteEndpointUrl(\"bucket-name\", %q) => %q, want %q", tt.in, s, tt.out)
|
||||
s := WebsiteEndpoint("bucket-name", tt.in)
|
||||
if s.Endpoint != tt.out {
|
||||
t.Errorf("WebsiteEndpointUrl(\"bucket-name\", %q) => %q, want %q", tt.in, s.Endpoint, tt.out)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
package azure
|
||||
|
||||
import "errors"
|
||||
|
||||
var PlatformStorageError = errors.New("When using a platform image, the 'storage' parameter is required")
|
|
@ -591,6 +591,10 @@ func retrieveImageDetails(
|
|||
return configureForImage, osType, nil
|
||||
}
|
||||
|
||||
if err == PlatformStorageError {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
return nil, "", fmt.Errorf("Could not find image with label '%s'. Available images are: %s",
|
||||
label, strings.Join(append(VMLabels, OSLabels...), ", "))
|
||||
}
|
||||
|
@ -646,8 +650,7 @@ func retrieveOSImageDetails(
|
|||
}
|
||||
if img.MediaLink == "" {
|
||||
if storage == "" {
|
||||
return nil, "", nil,
|
||||
fmt.Errorf("When using a platform image, the 'storage' parameter is required")
|
||||
return nil, "", nil, PlatformStorageError
|
||||
}
|
||||
img.MediaLink = fmt.Sprintf(osDiskBlobStorageURL, storage, name)
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ func resourceDNSimpleRecord() *schema.Resource {
|
|||
"domain": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
},
|
||||
|
||||
"domain_id": &schema.Schema{
|
||||
|
@ -39,6 +40,7 @@ func resourceDNSimpleRecord() *schema.Resource {
|
|||
"type": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
},
|
||||
|
||||
"value": &schema.Schema{
|
||||
|
@ -74,12 +76,12 @@ func resourceDNSimpleRecordCreate(d *schema.ResourceData, meta interface{}) erro
|
|||
newRecord.Ttl = ttl.(string)
|
||||
}
|
||||
|
||||
log.Printf("[DEBUG] DNS Simple Record create configuration: %#v", newRecord)
|
||||
log.Printf("[DEBUG] DNSimple Record create configuration: %#v", newRecord)
|
||||
|
||||
recId, err := client.CreateRecord(d.Get("domain").(string), newRecord)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to create DNS Simple Record: %s", err)
|
||||
return fmt.Errorf("Failed to create DNSimple Record: %s", err)
|
||||
}
|
||||
|
||||
d.SetId(recId)
|
||||
|
@ -93,7 +95,7 @@ func resourceDNSimpleRecordRead(d *schema.ResourceData, meta interface{}) error
|
|||
|
||||
rec, err := client.RetrieveRecord(d.Get("domain").(string), d.Id())
|
||||
if err != nil {
|
||||
return fmt.Errorf("Couldn't find DNS Simple Record: %s", err)
|
||||
return fmt.Errorf("Couldn't find DNSimple Record: %s", err)
|
||||
}
|
||||
|
||||
d.Set("domain_id", rec.StringDomainId())
|
||||
|
@ -133,11 +135,11 @@ func resourceDNSimpleRecordUpdate(d *schema.ResourceData, meta interface{}) erro
|
|||
updateRecord.Ttl = attr.(string)
|
||||
}
|
||||
|
||||
log.Printf("[DEBUG] DNS Simple Record update configuration: %#v", updateRecord)
|
||||
log.Printf("[DEBUG] DNSimple Record update configuration: %#v", updateRecord)
|
||||
|
||||
_, err := client.UpdateRecord(d.Get("domain").(string), d.Id(), updateRecord)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to update DNS Simple Record: %s", err)
|
||||
return fmt.Errorf("Failed to update DNSimple Record: %s", err)
|
||||
}
|
||||
|
||||
return resourceDNSimpleRecordRead(d, meta)
|
||||
|
@ -146,12 +148,12 @@ func resourceDNSimpleRecordUpdate(d *schema.ResourceData, meta interface{}) erro
|
|||
func resourceDNSimpleRecordDelete(d *schema.ResourceData, meta interface{}) error {
|
||||
client := meta.(*dnsimple.Client)
|
||||
|
||||
log.Printf("[INFO] Deleting DNS Simple Record: %s, %s", d.Get("domain").(string), d.Id())
|
||||
log.Printf("[INFO] Deleting DNSimple Record: %s, %s", d.Get("domain").(string), d.Id())
|
||||
|
||||
err := client.DestroyRecord(d.Get("domain").(string), d.Id())
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error deleting DNS Simple Record: %s", err)
|
||||
return fmt.Errorf("Error deleting DNSimple Record: %s", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
@ -3,10 +3,13 @@ package google
|
|||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
|
||||
// TODO(dcunnin): Use version code from version.go
|
||||
// "github.com/hashicorp/terraform"
|
||||
|
@ -26,16 +29,15 @@ type Config struct {
|
|||
Project string
|
||||
Region string
|
||||
|
||||
clientCompute *compute.Service
|
||||
clientCompute *compute.Service
|
||||
clientContainer *container.Service
|
||||
clientDns *dns.Service
|
||||
clientStorage *storage.Service
|
||||
clientDns *dns.Service
|
||||
clientStorage *storage.Service
|
||||
}
|
||||
|
||||
func (c *Config) loadAndValidate() error {
|
||||
var account accountFile
|
||||
|
||||
// TODO: validation that it isn't blank
|
||||
if c.AccountFile == "" {
|
||||
c.AccountFile = os.Getenv("GOOGLE_ACCOUNT_FILE")
|
||||
}
|
||||
|
@ -49,11 +51,33 @@ func (c *Config) loadAndValidate() error {
|
|||
var client *http.Client
|
||||
|
||||
if c.AccountFile != "" {
|
||||
if err := loadJSON(&account, c.AccountFile); err != nil {
|
||||
return fmt.Errorf(
|
||||
"Error loading account file '%s': %s",
|
||||
c.AccountFile,
|
||||
err)
|
||||
contents := c.AccountFile
|
||||
|
||||
// Assume account_file is a JSON string
|
||||
if err := parseJSON(&account, contents); err != nil {
|
||||
// If account_file was not JSON, assume it is a file path instead
|
||||
if _, err := os.Stat(c.AccountFile); os.IsNotExist(err) {
|
||||
return fmt.Errorf(
|
||||
"account_file path does not exist: %s",
|
||||
c.AccountFile)
|
||||
}
|
||||
|
||||
b, err := ioutil.ReadFile(c.AccountFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf(
|
||||
"Error reading account_file from path '%s': %s",
|
||||
c.AccountFile,
|
||||
err)
|
||||
}
|
||||
|
||||
contents = string(b)
|
||||
|
||||
if err := parseJSON(&account, contents); err != nil {
|
||||
return fmt.Errorf(
|
||||
"Error parsing account file '%s': %s",
|
||||
contents,
|
||||
err)
|
||||
}
|
||||
}
|
||||
|
||||
clientScopes := []string{
|
||||
|
@ -145,13 +169,9 @@ type accountFile struct {
|
|||
ClientId string `json:"client_id"`
|
||||
}
|
||||
|
||||
func loadJSON(result interface{}, path string) error {
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
func parseJSON(result interface{}, contents string) error {
|
||||
r := strings.NewReader(contents)
|
||||
dec := json.NewDecoder(r)
|
||||
|
||||
dec := json.NewDecoder(f)
|
||||
return dec.Decode(result)
|
||||
}
|
||||
|
|
|
@ -1,24 +1,50 @@
|
|||
package google
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestConfigLoadJSON_account(t *testing.T) {
|
||||
var actual accountFile
|
||||
if err := loadJSON(&actual, "./test-fixtures/fake_account.json"); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
const testFakeAccountFilePath = "./test-fixtures/fake_account.json"
|
||||
|
||||
func TestConfigLoadAndValidate_accountFilePath(t *testing.T) {
|
||||
config := Config{
|
||||
AccountFile: testFakeAccountFilePath,
|
||||
Project: "my-gce-project",
|
||||
Region: "us-central1",
|
||||
}
|
||||
|
||||
expected := accountFile{
|
||||
PrivateKeyId: "foo",
|
||||
PrivateKey: "bar",
|
||||
ClientEmail: "foo@bar.com",
|
||||
ClientId: "id@foo.com",
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(actual, expected) {
|
||||
t.Fatalf("bad: %#v", actual)
|
||||
err := config.loadAndValidate()
|
||||
if err != nil {
|
||||
t.Fatalf("error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfigLoadAndValidate_accountFileJSON(t *testing.T) {
|
||||
contents, err := ioutil.ReadFile(testFakeAccountFilePath)
|
||||
if err != nil {
|
||||
t.Fatalf("error: %v", err)
|
||||
}
|
||||
config := Config{
|
||||
AccountFile: string(contents),
|
||||
Project: "my-gce-project",
|
||||
Region: "us-central1",
|
||||
}
|
||||
|
||||
err = config.loadAndValidate()
|
||||
if err != nil {
|
||||
t.Fatalf("error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfigLoadAndValidate_accountFileJSONInvalid(t *testing.T) {
|
||||
config := Config{
|
||||
AccountFile: "{this is not json}",
|
||||
Project: "my-gce-project",
|
||||
Region: "us-central1",
|
||||
}
|
||||
|
||||
if config.loadAndValidate() == nil {
|
||||
t.Fatalf("expected error, but got nil")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ import (
|
|||
"fmt"
|
||||
|
||||
"google.golang.org/api/compute/v1"
|
||||
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
)
|
||||
|
||||
|
@ -25,8 +24,8 @@ type OperationWaiter struct {
|
|||
Op *compute.Operation
|
||||
Project string
|
||||
Region string
|
||||
Zone string
|
||||
Type OperationWaitType
|
||||
Zone string
|
||||
}
|
||||
|
||||
func (w *OperationWaiter) RefreshFunc() resource.StateRefreshFunc {
|
||||
|
@ -78,3 +77,4 @@ func (e OperationError) Error() string {
|
|||
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
package google
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
"github.com/hashicorp/terraform/terraform"
|
||||
)
|
||||
|
@ -10,9 +14,10 @@ func Provider() terraform.ResourceProvider {
|
|||
return &schema.Provider{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"account_file": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
DefaultFunc: schema.EnvDefaultFunc("GOOGLE_ACCOUNT_FILE", nil),
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
DefaultFunc: schema.EnvDefaultFunc("GOOGLE_ACCOUNT_FILE", nil),
|
||||
ValidateFunc: validateAccountFile,
|
||||
},
|
||||
|
||||
"project": &schema.Schema{
|
||||
|
@ -29,20 +34,22 @@ func Provider() terraform.ResourceProvider {
|
|||
},
|
||||
|
||||
ResourcesMap: map[string]*schema.Resource{
|
||||
"google_compute_address": resourceComputeAddress(),
|
||||
"google_compute_disk": resourceComputeDisk(),
|
||||
"google_compute_firewall": resourceComputeFirewall(),
|
||||
"google_compute_forwarding_rule": resourceComputeForwardingRule(),
|
||||
"google_compute_autoscaler": resourceComputeAutoscaler(),
|
||||
"google_compute_address": resourceComputeAddress(),
|
||||
"google_compute_disk": resourceComputeDisk(),
|
||||
"google_compute_firewall": resourceComputeFirewall(),
|
||||
"google_compute_forwarding_rule": resourceComputeForwardingRule(),
|
||||
"google_compute_http_health_check": resourceComputeHttpHealthCheck(),
|
||||
"google_compute_instance": resourceComputeInstance(),
|
||||
"google_compute_instance": resourceComputeInstance(),
|
||||
"google_compute_instance_template": resourceComputeInstanceTemplate(),
|
||||
"google_compute_network": resourceComputeNetwork(),
|
||||
"google_compute_route": resourceComputeRoute(),
|
||||
"google_compute_target_pool": resourceComputeTargetPool(),
|
||||
"google_container_cluster": resourceContainerCluster(),
|
||||
"google_dns_managed_zone": resourceDnsManagedZone(),
|
||||
"google_dns_record_set": resourceDnsRecordSet(),
|
||||
"google_storage_bucket": resourceStorageBucket(),
|
||||
"google_compute_network": resourceComputeNetwork(),
|
||||
"google_compute_route": resourceComputeRoute(),
|
||||
"google_compute_target_pool": resourceComputeTargetPool(),
|
||||
"google_container_cluster": resourceContainerCluster(),
|
||||
"google_dns_managed_zone": resourceDnsManagedZone(),
|
||||
"google_dns_record_set": resourceDnsRecordSet(),
|
||||
"google_compute_instance_group_manager": resourceComputeInstanceGroupManager(),
|
||||
"google_storage_bucket": resourceStorageBucket(),
|
||||
},
|
||||
|
||||
ConfigureFunc: providerConfigure,
|
||||
|
@ -62,3 +69,31 @@ func providerConfigure(d *schema.ResourceData) (interface{}, error) {
|
|||
|
||||
return &config, nil
|
||||
}
|
||||
|
||||
func validateAccountFile(v interface{}, k string) (warnings []string, errors []error) {
|
||||
value := v.(string)
|
||||
|
||||
if value == "" {
|
||||
return
|
||||
}
|
||||
|
||||
var account accountFile
|
||||
if err := json.Unmarshal([]byte(value), &account); err != nil {
|
||||
warnings = append(warnings, `
|
||||
account_file is not valid JSON, so we are assuming it is a file path. This
|
||||
support will be removed in the future. Please update your configuration to use
|
||||
${file("filename.json")} instead.`)
|
||||
} else {
|
||||
return
|
||||
}
|
||||
|
||||
if _, err := os.Stat(value); err != nil {
|
||||
errors = append(errors,
|
||||
fmt.Errorf(
|
||||
"account_file path could not be read from '%s': %s",
|
||||
value,
|
||||
err))
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
|
|
@ -0,0 +1,352 @@
|
|||
package google
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"google.golang.org/api/googleapi"
|
||||
"google.golang.org/api/compute/v1"
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
)
|
||||
|
||||
func resourceComputeAutoscaler() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
Create: resourceComputeAutoscalerCreate,
|
||||
Read: resourceComputeAutoscalerRead,
|
||||
Update: resourceComputeAutoscalerUpdate,
|
||||
Delete: resourceComputeAutoscalerDelete,
|
||||
|
||||
Schema: map[string]*schema.Schema{
|
||||
"name": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
ForceNew: true,
|
||||
Required: true,
|
||||
},
|
||||
|
||||
"description": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
|
||||
"target": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
},
|
||||
|
||||
"autoscaling_policy": &schema.Schema{
|
||||
Type: schema.TypeList,
|
||||
Optional: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"min_replicas": &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
},
|
||||
|
||||
"max_replicas": &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
},
|
||||
|
||||
"cooldown_period": &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Default: 60,
|
||||
},
|
||||
|
||||
"cpu_utilization": &schema.Schema{
|
||||
Type: schema.TypeList,
|
||||
Optional: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"target": &schema.Schema{
|
||||
Type: schema.TypeFloat,
|
||||
Required: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
"metric": &schema.Schema{
|
||||
Type: schema.TypeList,
|
||||
Optional: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"name": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
},
|
||||
"target": &schema.Schema{
|
||||
Type: schema.TypeFloat,
|
||||
Required: true,
|
||||
},
|
||||
|
||||
"type": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
"load_balancing_utilization": &schema.Schema{
|
||||
Type: schema.TypeList,
|
||||
Optional: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"target": &schema.Schema{
|
||||
Type: schema.TypeFloat,
|
||||
Required: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
"zone": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
},
|
||||
|
||||
"self_link": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func buildAutoscaler(d *schema.ResourceData) (*compute.Autoscaler, error) {
|
||||
|
||||
// Build the parameter
|
||||
scaler := &compute.Autoscaler{
|
||||
Name: d.Get("name").(string),
|
||||
Target: d.Get("target").(string),
|
||||
}
|
||||
|
||||
// Optional fields
|
||||
if v, ok := d.GetOk("description"); ok {
|
||||
scaler.Description = v.(string)
|
||||
}
|
||||
|
||||
aspCount := d.Get("autoscaling_policy.#").(int)
|
||||
if aspCount != 1 {
|
||||
return nil, fmt.Errorf("The autoscaler must have exactly one autoscaling_policy, found %d.", aspCount)
|
||||
}
|
||||
|
||||
prefix := "autoscaling_policy.0."
|
||||
|
||||
scaler.AutoscalingPolicy = &compute.AutoscalingPolicy{
|
||||
MaxNumReplicas: int64(d.Get(prefix + "max_replicas").(int)),
|
||||
MinNumReplicas: int64(d.Get(prefix + "min_replicas").(int)),
|
||||
CoolDownPeriodSec: int64(d.Get(prefix + "cooldown_period").(int)),
|
||||
}
|
||||
|
||||
// Check that only one autoscaling policy is defined
|
||||
|
||||
policyCounter := 0
|
||||
if _, ok := d.GetOk(prefix + "cpu_utilization"); ok {
|
||||
if d.Get(prefix+"cpu_utilization.0.target").(float64) != 0 {
|
||||
cpuUtilCount := d.Get(prefix + "cpu_utilization.#").(int)
|
||||
if cpuUtilCount != 1 {
|
||||
return nil, fmt.Errorf("The autoscaling_policy must have exactly one cpu_utilization, found %d.", cpuUtilCount)
|
||||
}
|
||||
policyCounter++
|
||||
scaler.AutoscalingPolicy.CpuUtilization = &compute.AutoscalingPolicyCpuUtilization{
|
||||
UtilizationTarget: d.Get(prefix + "cpu_utilization.0.target").(float64),
|
||||
}
|
||||
}
|
||||
}
|
||||
if _, ok := d.GetOk("autoscaling_policy.0.metric"); ok {
|
||||
if d.Get(prefix+"metric.0.name") != "" {
|
||||
policyCounter++
|
||||
metricCount := d.Get(prefix + "metric.#").(int)
|
||||
if metricCount != 1 {
|
||||
return nil, fmt.Errorf("The autoscaling_policy must have exactly one metric, found %d.", metricCount)
|
||||
}
|
||||
scaler.AutoscalingPolicy.CustomMetricUtilizations = []*compute.AutoscalingPolicyCustomMetricUtilization{
|
||||
{
|
||||
Metric: d.Get(prefix + "metric.0.name").(string),
|
||||
UtilizationTarget: d.Get(prefix + "metric.0.target").(float64),
|
||||
UtilizationTargetType: d.Get(prefix + "metric.0.type").(string),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if _, ok := d.GetOk("autoscaling_policy.0.load_balancing_utilization"); ok {
|
||||
if d.Get(prefix+"load_balancing_utilization.0.target").(float64) != 0 {
|
||||
policyCounter++
|
||||
lbuCount := d.Get(prefix + "load_balancing_utilization.#").(int)
|
||||
if lbuCount != 1 {
|
||||
return nil, fmt.Errorf("The autoscaling_policy must have exactly one load_balancing_utilization, found %d.", lbuCount)
|
||||
}
|
||||
scaler.AutoscalingPolicy.LoadBalancingUtilization = &compute.AutoscalingPolicyLoadBalancingUtilization{
|
||||
UtilizationTarget: d.Get(prefix + "load_balancing_utilization.0.target").(float64),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if policyCounter != 1 {
|
||||
return nil, fmt.Errorf("One policy must be defined for an autoscaler.")
|
||||
}
|
||||
|
||||
return scaler, nil
|
||||
}
|
||||
|
||||
func resourceComputeAutoscalerCreate(d *schema.ResourceData, meta interface{}) error {
|
||||
config := meta.(*Config)
|
||||
|
||||
// Get the zone
|
||||
log.Printf("[DEBUG] Loading zone: %s", d.Get("zone").(string))
|
||||
zone, err := config.clientCompute.Zones.Get(
|
||||
config.Project, d.Get("zone").(string)).Do()
|
||||
if err != nil {
|
||||
return fmt.Errorf(
|
||||
"Error loading zone '%s': %s", d.Get("zone").(string), err)
|
||||
}
|
||||
|
||||
scaler, err := buildAutoscaler(d)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
op, err := config.clientCompute.Autoscalers.Insert(
|
||||
config.Project, zone.Name, scaler).Do()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error creating Autoscaler: %s", err)
|
||||
}
|
||||
|
||||
// It probably maybe worked, so store the ID now
|
||||
d.SetId(scaler.Name)
|
||||
|
||||
// Wait for the operation to complete
|
||||
w := &OperationWaiter{
|
||||
Service: config.clientCompute,
|
||||
Op: op,
|
||||
Project: config.Project,
|
||||
Type: OperationWaitZone,
|
||||
Zone: zone.Name,
|
||||
}
|
||||
state := w.Conf()
|
||||
state.Timeout = 2 * time.Minute
|
||||
state.MinTimeout = 1 * time.Second
|
||||
opRaw, err := state.WaitForState()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error waiting for Autoscaler to create: %s", err)
|
||||
}
|
||||
op = opRaw.(*compute.Operation)
|
||||
if op.Error != nil {
|
||||
// The resource didn't actually create
|
||||
d.SetId("")
|
||||
|
||||
// Return the error
|
||||
return OperationError(*op.Error)
|
||||
}
|
||||
|
||||
return resourceComputeAutoscalerRead(d, meta)
|
||||
}
|
||||
|
||||
func resourceComputeAutoscalerRead(d *schema.ResourceData, meta interface{}) error {
|
||||
config := meta.(*Config)
|
||||
|
||||
zone := d.Get("zone").(string)
|
||||
scaler, err := config.clientCompute.Autoscalers.Get(
|
||||
config.Project, zone, d.Id()).Do()
|
||||
if err != nil {
|
||||
if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 404 {
|
||||
// The resource doesn't exist anymore
|
||||
d.SetId("")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
return fmt.Errorf("Error reading Autoscaler: %s", err)
|
||||
}
|
||||
|
||||
d.Set("self_link", scaler.SelfLink)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceComputeAutoscalerUpdate(d *schema.ResourceData, meta interface{}) error {
|
||||
config := meta.(*Config)
|
||||
|
||||
zone := d.Get("zone").(string)
|
||||
|
||||
scaler, err := buildAutoscaler(d)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
op, err := config.clientCompute.Autoscalers.Patch(
|
||||
config.Project, zone, d.Id(), scaler).Do()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error updating Autoscaler: %s", err)
|
||||
}
|
||||
|
||||
// It probably maybe worked, so store the ID now
|
||||
d.SetId(scaler.Name)
|
||||
|
||||
// Wait for the operation to complete
|
||||
w := &OperationWaiter{
|
||||
Service: config.clientCompute,
|
||||
Op: op,
|
||||
Project: config.Project,
|
||||
Type: OperationWaitZone,
|
||||
Zone: zone,
|
||||
}
|
||||
state := w.Conf()
|
||||
state.Timeout = 2 * time.Minute
|
||||
state.MinTimeout = 1 * time.Second
|
||||
opRaw, err := state.WaitForState()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error waiting for Autoscaler to update: %s", err)
|
||||
}
|
||||
op = opRaw.(*compute.Operation)
|
||||
if op.Error != nil {
|
||||
// Return the error
|
||||
return OperationError(*op.Error)
|
||||
}
|
||||
|
||||
return resourceComputeAutoscalerRead(d, meta)
|
||||
}
|
||||
|
||||
func resourceComputeAutoscalerDelete(d *schema.ResourceData, meta interface{}) error {
|
||||
config := meta.(*Config)
|
||||
|
||||
zone := d.Get("zone").(string)
|
||||
op, err := config.clientCompute.Autoscalers.Delete(
|
||||
config.Project, zone, d.Id()).Do()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error deleting autoscaler: %s", err)
|
||||
}
|
||||
|
||||
// Wait for the operation to complete
|
||||
w := &OperationWaiter{
|
||||
Service: config.clientCompute,
|
||||
Op: op,
|
||||
Project: config.Project,
|
||||
Type: OperationWaitZone,
|
||||
Zone: zone,
|
||||
}
|
||||
state := w.Conf()
|
||||
state.Timeout = 2 * time.Minute
|
||||
state.MinTimeout = 1 * time.Second
|
||||
opRaw, err := state.WaitForState()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error waiting for Autoscaler to delete: %s", err)
|
||||
}
|
||||
op = opRaw.(*compute.Operation)
|
||||
if op.Error != nil {
|
||||
// Return the error
|
||||
return OperationError(*op.Error)
|
||||
}
|
||||
|
||||
d.SetId("")
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,245 @@
|
|||
package google
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"google.golang.org/api/compute/v1"
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"github.com/hashicorp/terraform/terraform"
|
||||
)
|
||||
|
||||
func TestAccAutoscaler_basic(t *testing.T) {
|
||||
var ascaler compute.Autoscaler
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckAutoscalerDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
resource.TestStep{
|
||||
Config: testAccAutoscaler_basic,
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckAutoscalerExists(
|
||||
"google_compute_autoscaler.foobar", &ascaler),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestAccAutoscaler_update(t *testing.T) {
|
||||
var ascaler compute.Autoscaler
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckAutoscalerDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
resource.TestStep{
|
||||
Config: testAccAutoscaler_basic,
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckAutoscalerExists(
|
||||
"google_compute_autoscaler.foobar", &ascaler),
|
||||
),
|
||||
},
|
||||
resource.TestStep{
|
||||
Config: testAccAutoscaler_update,
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckAutoscalerExists(
|
||||
"google_compute_autoscaler.foobar", &ascaler),
|
||||
testAccCheckAutoscalerUpdated(
|
||||
"google_compute_autoscaler.foobar", 10),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func testAccCheckAutoscalerDestroy(s *terraform.State) error {
|
||||
config := testAccProvider.Meta().(*Config)
|
||||
|
||||
for _, rs := range s.RootModule().Resources {
|
||||
if rs.Type != "google_compute_autoscaler" {
|
||||
continue
|
||||
}
|
||||
|
||||
_, err := config.clientCompute.Autoscalers.Get(
|
||||
config.Project, rs.Primary.Attributes["zone"], rs.Primary.ID).Do()
|
||||
if err == nil {
|
||||
return fmt.Errorf("Autoscaler still exists")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func testAccCheckAutoscalerExists(n string, ascaler *compute.Autoscaler) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
rs, ok := s.RootModule().Resources[n]
|
||||
if !ok {
|
||||
return fmt.Errorf("Not found: %s", n)
|
||||
}
|
||||
|
||||
if rs.Primary.ID == "" {
|
||||
return fmt.Errorf("No ID is set")
|
||||
}
|
||||
|
||||
config := testAccProvider.Meta().(*Config)
|
||||
|
||||
found, err := config.clientCompute.Autoscalers.Get(
|
||||
config.Project, rs.Primary.Attributes["zone"], rs.Primary.ID).Do()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if found.Name != rs.Primary.ID {
|
||||
return fmt.Errorf("Autoscaler not found")
|
||||
}
|
||||
|
||||
*ascaler = *found
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func testAccCheckAutoscalerUpdated(n string, max int64) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
rs, ok := s.RootModule().Resources[n]
|
||||
if !ok {
|
||||
return fmt.Errorf("Not found: %s", n)
|
||||
}
|
||||
|
||||
if rs.Primary.ID == "" {
|
||||
return fmt.Errorf("No ID is set")
|
||||
}
|
||||
|
||||
config := testAccProvider.Meta().(*Config)
|
||||
|
||||
ascaler, err := config.clientCompute.Autoscalers.Get(
|
||||
config.Project, rs.Primary.Attributes["zone"], rs.Primary.ID).Do()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if ascaler.AutoscalingPolicy.MaxNumReplicas != max {
|
||||
return fmt.Errorf("maximum replicas incorrect")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
const testAccAutoscaler_basic = `
|
||||
resource "google_compute_instance_template" "foobar" {
|
||||
name = "terraform-test-template-foobar"
|
||||
machine_type = "n1-standard-1"
|
||||
can_ip_forward = false
|
||||
tags = ["foo", "bar"]
|
||||
|
||||
disk {
|
||||
source_image = "debian-cloud/debian-7-wheezy-v20140814"
|
||||
auto_delete = true
|
||||
boot = true
|
||||
}
|
||||
|
||||
network_interface {
|
||||
network = "default"
|
||||
}
|
||||
|
||||
metadata {
|
||||
foo = "bar"
|
||||
}
|
||||
|
||||
service_account {
|
||||
scopes = ["userinfo-email", "compute-ro", "storage-ro"]
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_compute_target_pool" "foobar" {
|
||||
description = "Resource created for Terraform acceptance testing"
|
||||
name = "terraform-test-tpool-foobar"
|
||||
session_affinity = "CLIENT_IP_PROTO"
|
||||
}
|
||||
|
||||
resource "google_compute_instance_group_manager" "foobar" {
|
||||
description = "Terraform test instance group manager"
|
||||
name = "terraform-test-groupmanager"
|
||||
instance_template = "${google_compute_instance_template.foobar.self_link}"
|
||||
target_pools = ["${google_compute_target_pool.foobar.self_link}"]
|
||||
base_instance_name = "foobar"
|
||||
zone = "us-central1-a"
|
||||
}
|
||||
|
||||
resource "google_compute_autoscaler" "foobar" {
|
||||
description = "Resource created for Terraform acceptance testing"
|
||||
name = "terraform-test-ascaler"
|
||||
zone = "us-central1-a"
|
||||
target = "${google_compute_instance_group_manager.foobar.self_link}"
|
||||
autoscaling_policy = {
|
||||
max_replicas = 5
|
||||
min_replicas = 0
|
||||
cooldown_period = 60
|
||||
cpu_utilization = {
|
||||
target = 0.5
|
||||
}
|
||||
}
|
||||
|
||||
}`
|
||||
|
||||
const testAccAutoscaler_update = `
|
||||
resource "google_compute_instance_template" "foobar" {
|
||||
name = "terraform-test-template-foobar"
|
||||
machine_type = "n1-standard-1"
|
||||
can_ip_forward = false
|
||||
tags = ["foo", "bar"]
|
||||
|
||||
disk {
|
||||
source_image = "debian-cloud/debian-7-wheezy-v20140814"
|
||||
auto_delete = true
|
||||
boot = true
|
||||
}
|
||||
|
||||
network_interface {
|
||||
network = "default"
|
||||
}
|
||||
|
||||
metadata {
|
||||
foo = "bar"
|
||||
}
|
||||
|
||||
service_account {
|
||||
scopes = ["userinfo-email", "compute-ro", "storage-ro"]
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_compute_target_pool" "foobar" {
|
||||
description = "Resource created for Terraform acceptance testing"
|
||||
name = "terraform-test-tpool-foobar"
|
||||
session_affinity = "CLIENT_IP_PROTO"
|
||||
}
|
||||
|
||||
resource "google_compute_instance_group_manager" "foobar" {
|
||||
description = "Terraform test instance group manager"
|
||||
name = "terraform-test-groupmanager"
|
||||
instance_template = "${google_compute_instance_template.foobar.self_link}"
|
||||
target_pools = ["${google_compute_target_pool.foobar.self_link}"]
|
||||
base_instance_name = "foobar"
|
||||
zone = "us-central1-a"
|
||||
}
|
||||
|
||||
resource "google_compute_autoscaler" "foobar" {
|
||||
description = "Resource created for Terraform acceptance testing"
|
||||
name = "terraform-test-ascaler"
|
||||
zone = "us-central1-a"
|
||||
target = "${google_compute_instance_group_manager.foobar.self_link}"
|
||||
autoscaling_policy = {
|
||||
max_replicas = 10
|
||||
min_replicas = 0
|
||||
cooldown_period = 60
|
||||
cpu_utilization = {
|
||||
target = 0.5
|
||||
}
|
||||
}
|
||||
|
||||
}`
|
|
@ -0,0 +1,301 @@
|
|||
package google
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"google.golang.org/api/googleapi"
|
||||
"google.golang.org/api/compute/v1"
|
||||
|
||||
"github.com/hashicorp/terraform/helper/hashcode"
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
)
|
||||
|
||||
func resourceComputeInstanceGroupManager() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
Create: resourceComputeInstanceGroupManagerCreate,
|
||||
Read: resourceComputeInstanceGroupManagerRead,
|
||||
Update: resourceComputeInstanceGroupManagerUpdate,
|
||||
Delete: resourceComputeInstanceGroupManagerDelete,
|
||||
|
||||
Schema: map[string]*schema.Schema{
|
||||
"name": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
},
|
||||
|
||||
"description": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
ForceNew: true,
|
||||
},
|
||||
|
||||
"base_instance_name": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
},
|
||||
|
||||
"fingerprint": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
|
||||
"instance_group": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
|
||||
"instance_template": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
},
|
||||
|
||||
"target_pools": &schema.Schema{
|
||||
Type: schema.TypeSet,
|
||||
Required: true,
|
||||
Elem: &schema.Schema{Type: schema.TypeString},
|
||||
Set: func(v interface{}) int {
|
||||
return hashcode.String(v.(string))
|
||||
},
|
||||
},
|
||||
|
||||
"target_size": &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Optional: true,
|
||||
},
|
||||
|
||||
"zone": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
},
|
||||
|
||||
"self_link": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func waitOpZone(config *Config, op *compute.Operation, zone string,
|
||||
resource string, action string) (*compute.Operation, error) {
|
||||
|
||||
w := &OperationWaiter{
|
||||
Service: config.clientCompute,
|
||||
Op: op,
|
||||
Project: config.Project,
|
||||
Zone: zone,
|
||||
Type: OperationWaitZone,
|
||||
}
|
||||
state := w.Conf()
|
||||
state.Timeout = 8 * time.Minute
|
||||
state.MinTimeout = 1 * time.Second
|
||||
opRaw, err := state.WaitForState()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error waiting for %s to %s: %s", resource, action, err)
|
||||
}
|
||||
return opRaw.(*compute.Operation), nil
|
||||
}
|
||||
|
||||
func resourceComputeInstanceGroupManagerCreate(d *schema.ResourceData, meta interface{}) error {
|
||||
config := meta.(*Config)
|
||||
|
||||
// Get group size, default to 1 if not given
|
||||
var target_size int64 = 1
|
||||
if v, ok := d.GetOk("target_size"); ok {
|
||||
target_size = int64(v.(int))
|
||||
}
|
||||
|
||||
// Build the parameter
|
||||
manager := &compute.InstanceGroupManager{
|
||||
Name: d.Get("name").(string),
|
||||
BaseInstanceName: d.Get("base_instance_name").(string),
|
||||
InstanceTemplate: d.Get("instance_template").(string),
|
||||
TargetSize: target_size,
|
||||
}
|
||||
|
||||
// Set optional fields
|
||||
if v, ok := d.GetOk("description"); ok {
|
||||
manager.Description = v.(string)
|
||||
}
|
||||
|
||||
if attr := d.Get("target_pools").(*schema.Set); attr.Len() > 0 {
|
||||
var s []string
|
||||
for _, v := range attr.List() {
|
||||
s = append(s, v.(string))
|
||||
}
|
||||
manager.TargetPools = s
|
||||
}
|
||||
|
||||
log.Printf("[DEBUG] InstanceGroupManager insert request: %#v", manager)
|
||||
op, err := config.clientCompute.InstanceGroupManagers.Insert(
|
||||
config.Project, d.Get("zone").(string), manager).Do()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error creating InstanceGroupManager: %s", err)
|
||||
}
|
||||
|
||||
// It probably maybe worked, so store the ID now
|
||||
d.SetId(manager.Name)
|
||||
|
||||
// Wait for the operation to complete
|
||||
op, err = waitOpZone(config, op, d.Get("zone").(string), "InstanceGroupManager", "create")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if op.Error != nil {
|
||||
// The resource didn't actually create
|
||||
d.SetId("")
|
||||
// Return the error
|
||||
return OperationError(*op.Error)
|
||||
}
|
||||
|
||||
return resourceComputeInstanceGroupManagerRead(d, meta)
|
||||
}
|
||||
|
||||
func resourceComputeInstanceGroupManagerRead(d *schema.ResourceData, meta interface{}) error {
|
||||
config := meta.(*Config)
|
||||
|
||||
manager, err := config.clientCompute.InstanceGroupManagers.Get(
|
||||
config.Project, d.Get("zone").(string), d.Id()).Do()
|
||||
if err != nil {
|
||||
if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 404 {
|
||||
// The resource doesn't exist anymore
|
||||
d.SetId("")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
return fmt.Errorf("Error reading instance group manager: %s", err)
|
||||
}
|
||||
|
||||
// Set computed fields
|
||||
d.Set("fingerprint", manager.Fingerprint)
|
||||
d.Set("instance_group", manager.InstanceGroup)
|
||||
d.Set("target_size", manager.TargetSize)
|
||||
d.Set("self_link", manager.SelfLink)
|
||||
|
||||
return nil
|
||||
}
|
||||
func resourceComputeInstanceGroupManagerUpdate(d *schema.ResourceData, meta interface{}) error {
|
||||
config := meta.(*Config)
|
||||
|
||||
d.Partial(true)
|
||||
|
||||
// If target_pools changes then update
|
||||
if d.HasChange("target_pools") {
|
||||
var targetPools []string
|
||||
if attr := d.Get("target_pools").(*schema.Set); attr.Len() > 0 {
|
||||
for _, v := range attr.List() {
|
||||
targetPools = append(targetPools, v.(string))
|
||||
}
|
||||
}
|
||||
|
||||
// Build the parameter
|
||||
setTargetPools := &compute.InstanceGroupManagersSetTargetPoolsRequest{
|
||||
Fingerprint: d.Get("fingerprint").(string),
|
||||
TargetPools: targetPools,
|
||||
}
|
||||
|
||||
op, err := config.clientCompute.InstanceGroupManagers.SetTargetPools(
|
||||
config.Project, d.Get("zone").(string), d.Id(), setTargetPools).Do()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error updating InstanceGroupManager: %s", err)
|
||||
}
|
||||
|
||||
// Wait for the operation to complete
|
||||
op, err = waitOpZone(config, op, d.Get("zone").(string), "InstanceGroupManager", "update TargetPools")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if op.Error != nil {
|
||||
return OperationError(*op.Error)
|
||||
}
|
||||
|
||||
d.SetPartial("target_pools")
|
||||
}
|
||||
|
||||
// If instance_template changes then update
|
||||
if d.HasChange("instance_template") {
|
||||
// Build the parameter
|
||||
setInstanceTemplate := &compute.InstanceGroupManagersSetInstanceTemplateRequest{
|
||||
InstanceTemplate: d.Get("instance_template").(string),
|
||||
}
|
||||
|
||||
op, err := config.clientCompute.InstanceGroupManagers.SetInstanceTemplate(
|
||||
config.Project, d.Get("zone").(string), d.Id(), setInstanceTemplate).Do()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error updating InstanceGroupManager: %s", err)
|
||||
}
|
||||
|
||||
// Wait for the operation to complete
|
||||
op, err = waitOpZone(config, op, d.Get("zone").(string), "InstanceGroupManager", "update instance template")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if op.Error != nil {
|
||||
return OperationError(*op.Error)
|
||||
}
|
||||
|
||||
d.SetPartial("instance_template")
|
||||
}
|
||||
|
||||
// If size changes trigger a resize
|
||||
if d.HasChange("target_size") {
|
||||
if v, ok := d.GetOk("target_size"); ok {
|
||||
// Only do anything if the new size is set
|
||||
target_size := int64(v.(int))
|
||||
|
||||
op, err := config.clientCompute.InstanceGroupManagers.Resize(
|
||||
config.Project, d.Get("zone").(string), d.Id(), target_size).Do()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error updating InstanceGroupManager: %s", err)
|
||||
}
|
||||
|
||||
// Wait for the operation to complete
|
||||
op, err = waitOpZone(config, op, d.Get("zone").(string), "InstanceGroupManager", "update target_size")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if op.Error != nil {
|
||||
return OperationError(*op.Error)
|
||||
}
|
||||
}
|
||||
|
||||
d.SetPartial("target_size")
|
||||
}
|
||||
|
||||
d.Partial(false)
|
||||
|
||||
return resourceComputeInstanceGroupManagerRead(d, meta)
|
||||
}
|
||||
|
||||
func resourceComputeInstanceGroupManagerDelete(d *schema.ResourceData, meta interface{}) error {
|
||||
config := meta.(*Config)
|
||||
|
||||
zone := d.Get("zone").(string)
|
||||
op, err := config.clientCompute.InstanceGroupManagers.Delete(config.Project, zone, d.Id()).Do()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error deleting instance group manager: %s", err)
|
||||
}
|
||||
|
||||
// Wait for the operation to complete
|
||||
op, err = waitOpZone(config, op, d.Get("zone").(string), "InstanceGroupManager", "delete")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if op.Error != nil {
|
||||
// The resource didn't actually create
|
||||
d.SetId("")
|
||||
|
||||
// Return the error
|
||||
return OperationError(*op.Error)
|
||||
}
|
||||
|
||||
d.SetId("")
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,298 @@
|
|||
package google
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"google.golang.org/api/compute/v1"
|
||||
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"github.com/hashicorp/terraform/terraform"
|
||||
)
|
||||
|
||||
func TestAccInstanceGroupManager_basic(t *testing.T) {
|
||||
var manager compute.InstanceGroupManager
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckInstanceGroupManagerDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
resource.TestStep{
|
||||
Config: testAccInstanceGroupManager_basic,
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckInstanceGroupManagerExists(
|
||||
"google_compute_instance_group_manager.igm-basic", &manager),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestAccInstanceGroupManager_update(t *testing.T) {
|
||||
var manager compute.InstanceGroupManager
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckInstanceGroupManagerDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
resource.TestStep{
|
||||
Config: testAccInstanceGroupManager_update,
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckInstanceGroupManagerExists(
|
||||
"google_compute_instance_group_manager.igm-update", &manager),
|
||||
),
|
||||
},
|
||||
resource.TestStep{
|
||||
Config: testAccInstanceGroupManager_update2,
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckInstanceGroupManagerExists(
|
||||
"google_compute_instance_group_manager.igm-update", &manager),
|
||||
testAccCheckInstanceGroupManagerUpdated(
|
||||
"google_compute_instance_group_manager.igm-update", 3,
|
||||
"google_compute_target_pool.igm-update", "terraform-test-igm-update2"),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func testAccCheckInstanceGroupManagerDestroy(s *terraform.State) error {
|
||||
config := testAccProvider.Meta().(*Config)
|
||||
|
||||
for _, rs := range s.RootModule().Resources {
|
||||
if rs.Type != "google_compute_instance_group_manager" {
|
||||
continue
|
||||
}
|
||||
_, err := config.clientCompute.InstanceGroupManagers.Get(
|
||||
config.Project, rs.Primary.Attributes["zone"], rs.Primary.ID).Do()
|
||||
if err != nil {
|
||||
return fmt.Errorf("InstanceGroupManager still exists")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func testAccCheckInstanceGroupManagerExists(n string, manager *compute.InstanceGroupManager) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
rs, ok := s.RootModule().Resources[n]
|
||||
if !ok {
|
||||
return fmt.Errorf("Not found: %s", n)
|
||||
}
|
||||
|
||||
if rs.Primary.ID == "" {
|
||||
return fmt.Errorf("No ID is set")
|
||||
}
|
||||
|
||||
config := testAccProvider.Meta().(*Config)
|
||||
|
||||
found, err := config.clientCompute.InstanceGroupManagers.Get(
|
||||
config.Project, rs.Primary.Attributes["zone"], rs.Primary.ID).Do()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if found.Name != rs.Primary.ID {
|
||||
return fmt.Errorf("InstanceGroupManager not found")
|
||||
}
|
||||
|
||||
*manager = *found
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func testAccCheckInstanceGroupManagerUpdated(n string, size int64, targetPool string, template string) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
rs, ok := s.RootModule().Resources[n]
|
||||
if !ok {
|
||||
return fmt.Errorf("Not found: %s", n)
|
||||
}
|
||||
|
||||
if rs.Primary.ID == "" {
|
||||
return fmt.Errorf("No ID is set")
|
||||
}
|
||||
|
||||
config := testAccProvider.Meta().(*Config)
|
||||
|
||||
manager, err := config.clientCompute.InstanceGroupManagers.Get(
|
||||
config.Project, rs.Primary.Attributes["zone"], rs.Primary.ID).Do()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Cannot check the target pool as the instance creation is asynchronous. However, can
|
||||
// check the target_size.
|
||||
if manager.TargetSize != size {
|
||||
return fmt.Errorf("instance count incorrect")
|
||||
}
|
||||
|
||||
// check that the instance template updated
|
||||
instanceTemplate, err := config.clientCompute.InstanceTemplates.Get(
|
||||
config.Project, template).Do()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error reading instance template: %s", err)
|
||||
}
|
||||
|
||||
if instanceTemplate.Name != template {
|
||||
return fmt.Errorf("instance template not updated")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
const testAccInstanceGroupManager_basic = `
|
||||
resource "google_compute_instance_template" "igm-basic" {
|
||||
name = "terraform-test-igm-basic"
|
||||
machine_type = "n1-standard-1"
|
||||
can_ip_forward = false
|
||||
tags = ["foo", "bar"]
|
||||
|
||||
disk {
|
||||
source_image = "debian-cloud/debian-7-wheezy-v20140814"
|
||||
auto_delete = true
|
||||
boot = true
|
||||
}
|
||||
|
||||
network_interface {
|
||||
network = "default"
|
||||
}
|
||||
|
||||
metadata {
|
||||
foo = "bar"
|
||||
}
|
||||
|
||||
service_account {
|
||||
scopes = ["userinfo-email", "compute-ro", "storage-ro"]
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_compute_target_pool" "igm-basic" {
|
||||
description = "Resource created for Terraform acceptance testing"
|
||||
name = "terraform-test-igm-basic"
|
||||
session_affinity = "CLIENT_IP_PROTO"
|
||||
}
|
||||
|
||||
resource "google_compute_instance_group_manager" "igm-basic" {
|
||||
description = "Terraform test instance group manager"
|
||||
name = "terraform-test-igm-basic"
|
||||
instance_template = "${google_compute_instance_template.igm-basic.self_link}"
|
||||
target_pools = ["${google_compute_target_pool.igm-basic.self_link}"]
|
||||
base_instance_name = "igm-basic"
|
||||
zone = "us-central1-c"
|
||||
target_size = 2
|
||||
}`
|
||||
|
||||
const testAccInstanceGroupManager_update = `
|
||||
resource "google_compute_instance_template" "igm-update" {
|
||||
name = "terraform-test-igm-update"
|
||||
machine_type = "n1-standard-1"
|
||||
can_ip_forward = false
|
||||
tags = ["foo", "bar"]
|
||||
|
||||
disk {
|
||||
source_image = "debian-cloud/debian-7-wheezy-v20140814"
|
||||
auto_delete = true
|
||||
boot = true
|
||||
}
|
||||
|
||||
network_interface {
|
||||
network = "default"
|
||||
}
|
||||
|
||||
metadata {
|
||||
foo = "bar"
|
||||
}
|
||||
|
||||
service_account {
|
||||
scopes = ["userinfo-email", "compute-ro", "storage-ro"]
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_compute_target_pool" "igm-update" {
|
||||
description = "Resource created for Terraform acceptance testing"
|
||||
name = "terraform-test-igm-update"
|
||||
session_affinity = "CLIENT_IP_PROTO"
|
||||
}
|
||||
|
||||
resource "google_compute_instance_group_manager" "igm-update" {
|
||||
description = "Terraform test instance group manager"
|
||||
name = "terraform-test-igm-update"
|
||||
instance_template = "${google_compute_instance_template.igm-update.self_link}"
|
||||
target_pools = ["${google_compute_target_pool.igm-update.self_link}"]
|
||||
base_instance_name = "igm-update"
|
||||
zone = "us-central1-c"
|
||||
target_size = 2
|
||||
}`
|
||||
|
||||
// Change IGM's instance template and target size
|
||||
const testAccInstanceGroupManager_update2 = `
|
||||
resource "google_compute_instance_template" "igm-update" {
|
||||
name = "terraform-test-igm-update"
|
||||
machine_type = "n1-standard-1"
|
||||
can_ip_forward = false
|
||||
tags = ["foo", "bar"]
|
||||
|
||||
disk {
|
||||
source_image = "debian-cloud/debian-7-wheezy-v20140814"
|
||||
auto_delete = true
|
||||
boot = true
|
||||
}
|
||||
|
||||
network_interface {
|
||||
network = "default"
|
||||
}
|
||||
|
||||
metadata {
|
||||
foo = "bar"
|
||||
}
|
||||
|
||||
service_account {
|
||||
scopes = ["userinfo-email", "compute-ro", "storage-ro"]
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_compute_target_pool" "igm-update" {
|
||||
description = "Resource created for Terraform acceptance testing"
|
||||
name = "terraform-test-igm-update"
|
||||
session_affinity = "CLIENT_IP_PROTO"
|
||||
}
|
||||
|
||||
resource "google_compute_instance_template" "igm-update2" {
|
||||
name = "terraform-test-igm-update2"
|
||||
machine_type = "n1-standard-1"
|
||||
can_ip_forward = false
|
||||
tags = ["foo", "bar"]
|
||||
|
||||
disk {
|
||||
source_image = "debian-cloud/debian-7-wheezy-v20140814"
|
||||
auto_delete = true
|
||||
boot = true
|
||||
}
|
||||
|
||||
network_interface {
|
||||
network = "default"
|
||||
}
|
||||
|
||||
metadata {
|
||||
foo = "bar"
|
||||
}
|
||||
|
||||
service_account {
|
||||
scopes = ["userinfo-email", "compute-ro", "storage-ro"]
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_compute_instance_group_manager" "igm-update" {
|
||||
description = "Terraform test instance group manager"
|
||||
name = "terraform-test-igm-update"
|
||||
instance_template = "${google_compute_instance_template.igm-update2.self_link}"
|
||||
target_pools = ["${google_compute_target_pool.igm-update.self_link}"]
|
||||
base_instance_name = "igm-update"
|
||||
zone = "us-central1-c"
|
||||
target_size = 3
|
||||
}`
|
||||
|
|
@ -227,7 +227,9 @@ func resourceComputeInstanceTemplate() *schema.Resource {
|
|||
}
|
||||
}
|
||||
|
||||
func buildDisks(d *schema.ResourceData, meta interface{}) []*compute.AttachedDisk {
|
||||
func buildDisks(d *schema.ResourceData, meta interface{}) ([]*compute.AttachedDisk, error) {
|
||||
config := meta.(*Config)
|
||||
|
||||
disksCount := d.Get("disk.#").(int)
|
||||
|
||||
disks := make([]*compute.AttachedDisk, 0, disksCount)
|
||||
|
@ -267,7 +269,14 @@ func buildDisks(d *schema.ResourceData, meta interface{}) []*compute.AttachedDis
|
|||
}
|
||||
|
||||
if v, ok := d.GetOk(prefix + ".source_image"); ok {
|
||||
disk.InitializeParams.SourceImage = v.(string)
|
||||
imageName := v.(string)
|
||||
imageUrl, err := resolveImage(config, imageName)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf(
|
||||
"Error resolving image name '%s': %s",
|
||||
imageName, err)
|
||||
}
|
||||
disk.InitializeParams.SourceImage = imageUrl
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -286,7 +295,7 @@ func buildDisks(d *schema.ResourceData, meta interface{}) []*compute.AttachedDis
|
|||
disks = append(disks, &disk)
|
||||
}
|
||||
|
||||
return disks
|
||||
return disks, nil
|
||||
}
|
||||
|
||||
func buildNetworks(d *schema.ResourceData, meta interface{}) (error, []*compute.NetworkInterface) {
|
||||
|
@ -330,7 +339,11 @@ func resourceComputeInstanceTemplateCreate(d *schema.ResourceData, meta interfac
|
|||
instanceProperties.CanIpForward = d.Get("can_ip_forward").(bool)
|
||||
instanceProperties.Description = d.Get("instance_description").(string)
|
||||
instanceProperties.MachineType = d.Get("machine_type").(string)
|
||||
instanceProperties.Disks = buildDisks(d, meta)
|
||||
disks, err := buildDisks(d, meta)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
instanceProperties.Disks = disks
|
||||
metadata, err := resourceInstanceMetadata(d)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -24,7 +24,7 @@ func TestAccComputeInstanceTemplate_basic(t *testing.T) {
|
|||
"google_compute_instance_template.foobar", &instanceTemplate),
|
||||
testAccCheckComputeInstanceTemplateTag(&instanceTemplate, "foo"),
|
||||
testAccCheckComputeInstanceTemplateMetadata(&instanceTemplate, "foo", "bar"),
|
||||
testAccCheckComputeInstanceTemplateDisk(&instanceTemplate, "debian-7-wheezy-v20140814", true, true),
|
||||
testAccCheckComputeInstanceTemplateDisk(&instanceTemplate, "https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/debian-7-wheezy-v20140814", true, true),
|
||||
),
|
||||
},
|
||||
},
|
||||
|
@ -64,7 +64,7 @@ func TestAccComputeInstanceTemplate_disks(t *testing.T) {
|
|||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckComputeInstanceTemplateExists(
|
||||
"google_compute_instance_template.foobar", &instanceTemplate),
|
||||
testAccCheckComputeInstanceTemplateDisk(&instanceTemplate, "debian-7-wheezy-v20140814", true, true),
|
||||
testAccCheckComputeInstanceTemplateDisk(&instanceTemplate, "https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/debian-7-wheezy-v20140814", true, true),
|
||||
testAccCheckComputeInstanceTemplateDisk(&instanceTemplate, "terraform-test-foobar", false, false),
|
||||
),
|
||||
},
|
||||
|
|
|
@ -140,7 +140,8 @@ func (h *UiHook) PostApply(
|
|||
}
|
||||
|
||||
if applyerr != nil {
|
||||
msg = fmt.Sprintf("Error: %s", applyerr)
|
||||
// Errors are collected and printed in ApplyCommand, no need to duplicate
|
||||
return terraform.HookActionContinue, nil
|
||||
}
|
||||
|
||||
h.ui.Output(h.Colorize.Color(fmt.Sprintf(
|
||||
|
|
|
@ -0,0 +1,385 @@
|
|||
{
|
||||
"ImportPath": "github.com/hashicorp/terraform",
|
||||
"GoVersion": "go1.4.2",
|
||||
"Packages": [
|
||||
"./..."
|
||||
],
|
||||
"Deps": [
|
||||
{
|
||||
"ImportPath": "code.google.com/p/go-uuid/uuid",
|
||||
"Comment": "null-15",
|
||||
"Rev": "35bc42037350f0078e3c974c6ea690f1926603ab"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/Azure/azure-sdk-for-go/core/http",
|
||||
"Comment": "v1.2-216-g9197765",
|
||||
"Rev": "91977650587a7bc48318c0430649d7fea886f111"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/Azure/azure-sdk-for-go/core/tls",
|
||||
"Comment": "v1.2-216-g9197765",
|
||||
"Rev": "91977650587a7bc48318c0430649d7fea886f111"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/Azure/azure-sdk-for-go/management",
|
||||
"Comment": "v1.2-216-g9197765",
|
||||
"Rev": "91977650587a7bc48318c0430649d7fea886f111"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/Azure/azure-sdk-for-go/storage",
|
||||
"Comment": "v1.2-216-g9197765",
|
||||
"Rev": "91977650587a7bc48318c0430649d7fea886f111"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/Azure/go-pkcs12",
|
||||
"Rev": "a635c0684cd517745ca5c9552a312627791d5ba0"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/armon/circbuf",
|
||||
"Rev": "f092b4f207b6e5cce0569056fba9e1a2735cb6cf"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/aws",
|
||||
"Comment": "v0.6.7-3-g2a6648c",
|
||||
"Rev": "2a6648c479175ce005bca95780f948a196a46062"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/internal/endpoints",
|
||||
"Comment": "v0.6.7-3-g2a6648c",
|
||||
"Rev": "2a6648c479175ce005bca95780f948a196a46062"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/internal/protocol/ec2query",
|
||||
"Comment": "v0.6.7-3-g2a6648c",
|
||||
"Rev": "2a6648c479175ce005bca95780f948a196a46062"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/internal/protocol/json/jsonutil",
|
||||
"Comment": "v0.6.7-3-g2a6648c",
|
||||
"Rev": "2a6648c479175ce005bca95780f948a196a46062"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/internal/protocol/jsonrpc",
|
||||
"Comment": "v0.6.7-3-g2a6648c",
|
||||
"Rev": "2a6648c479175ce005bca95780f948a196a46062"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/internal/protocol/query",
|
||||
"Comment": "v0.6.7-3-g2a6648c",
|
||||
"Rev": "2a6648c479175ce005bca95780f948a196a46062"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/internal/protocol/rest",
|
||||
"Comment": "v0.6.7-3-g2a6648c",
|
||||
"Rev": "2a6648c479175ce005bca95780f948a196a46062"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/internal/protocol/restjson",
|
||||
"Comment": "v0.6.7-3-g2a6648c",
|
||||
"Rev": "2a6648c479175ce005bca95780f948a196a46062"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/internal/protocol/restxml",
|
||||
"Comment": "v0.6.7-3-g2a6648c",
|
||||
"Rev": "2a6648c479175ce005bca95780f948a196a46062"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/internal/protocol/xml/xmlutil",
|
||||
"Comment": "v0.6.7-3-g2a6648c",
|
||||
"Rev": "2a6648c479175ce005bca95780f948a196a46062"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/internal/signer/v4",
|
||||
"Comment": "v0.6.7-3-g2a6648c",
|
||||
"Rev": "2a6648c479175ce005bca95780f948a196a46062"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/service/autoscaling",
|
||||
"Comment": "v0.6.7-3-g2a6648c",
|
||||
"Rev": "2a6648c479175ce005bca95780f948a196a46062"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/service/cloudwatch",
|
||||
"Comment": "v0.6.7-3-g2a6648c",
|
||||
"Rev": "2a6648c479175ce005bca95780f948a196a46062"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/service/dynamodb",
|
||||
"Comment": "v0.6.7-3-g2a6648c",
|
||||
"Rev": "2a6648c479175ce005bca95780f948a196a46062"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/service/ec2",
|
||||
"Comment": "v0.6.7-3-g2a6648c",
|
||||
"Rev": "2a6648c479175ce005bca95780f948a196a46062"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/service/ecs",
|
||||
"Comment": "v0.6.7-3-g2a6648c",
|
||||
"Rev": "2a6648c479175ce005bca95780f948a196a46062"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/service/elasticache",
|
||||
"Comment": "v0.6.7-3-g2a6648c",
|
||||
"Rev": "2a6648c479175ce005bca95780f948a196a46062"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/service/elb",
|
||||
"Comment": "v0.6.7-3-g2a6648c",
|
||||
"Rev": "2a6648c479175ce005bca95780f948a196a46062"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/service/iam",
|
||||
"Comment": "v0.6.7-3-g2a6648c",
|
||||
"Rev": "2a6648c479175ce005bca95780f948a196a46062"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/service/kinesis",
|
||||
"Comment": "v0.6.7-3-g2a6648c",
|
||||
"Rev": "2a6648c479175ce005bca95780f948a196a46062"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/service/lambda",
|
||||
"Comment": "v0.6.7-3-g2a6648c",
|
||||
"Rev": "2a6648c479175ce005bca95780f948a196a46062"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/service/rds",
|
||||
"Comment": "v0.6.7-3-g2a6648c",
|
||||
"Rev": "2a6648c479175ce005bca95780f948a196a46062"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/service/route53",
|
||||
"Comment": "v0.6.7-3-g2a6648c",
|
||||
"Rev": "2a6648c479175ce005bca95780f948a196a46062"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/service/s3",
|
||||
"Comment": "v0.6.7-3-g2a6648c",
|
||||
"Rev": "2a6648c479175ce005bca95780f948a196a46062"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/service/sns",
|
||||
"Comment": "v0.6.7-3-g2a6648c",
|
||||
"Rev": "2a6648c479175ce005bca95780f948a196a46062"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/aws/aws-sdk-go/service/sqs",
|
||||
"Comment": "v0.6.7-3-g2a6648c",
|
||||
"Rev": "2a6648c479175ce005bca95780f948a196a46062"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/awslabs/aws-sdk-go/aws/credentials",
|
||||
"Comment": "v0.6.7-3-g2a6648c",
|
||||
"Rev": "2a6648c479175ce005bca95780f948a196a46062"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/cyberdelia/heroku-go/v3",
|
||||
"Rev": "594d483b9b6a8ddc7cd2f1e3e7d1de92fa2de665"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/dylanmei/iso8601",
|
||||
"Rev": "2075bf119b58e5576c6ed9f867b8f3d17f2e54d4"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/dylanmei/winrmtest",
|
||||
"Rev": "3e9661c52c45dab9a8528966a23d421922fca9b9"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/fsouza/go-dockerclient",
|
||||
"Rev": "f6e9f5396e0e8f34472efe443d0cb7f9af162b88"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/hashicorp/atlas-go/archive",
|
||||
"Comment": "20141209094003-71-g785958f",
|
||||
"Rev": "785958ffcd6a8857890651f3f4d9a289ddc27633"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/hashicorp/atlas-go/v1",
|
||||
"Comment": "20141209094003-71-g785958f",
|
||||
"Rev": "785958ffcd6a8857890651f3f4d9a289ddc27633"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/hashicorp/consul/api",
|
||||
"Comment": "v0.5.2-159-gc34bcb4",
|
||||
"Rev": "c34bcb45c670af076846826ea72c436fbd0e2c35"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/hashicorp/errwrap",
|
||||
"Rev": "7554cd9344cec97297fa6649b055a8c98c2a1e55"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/hashicorp/go-checkpoint",
|
||||
"Rev": "88326f6851319068e7b34981032128c0b1a6524d"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/hashicorp/go-multierror",
|
||||
"Rev": "56912fb08d85084aa318edcf2bba735b97cf35c5"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/hashicorp/go-version",
|
||||
"Rev": "999359b6b7a041ce16e695d51e92145b83f01087"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/hashicorp/hcl",
|
||||
"Rev": "54864211433d45cb780682431585b3e573b49e4a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/hashicorp/yamux",
|
||||
"Rev": "8e00b30457b1486b012f204b82ec92ae6b547de8"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/imdario/mergo",
|
||||
"Comment": "0.2.0-5-g61a5285",
|
||||
"Rev": "61a52852277811e93e06d28e0d0c396284a7730b"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/masterzen/simplexml/dom",
|
||||
"Rev": "95ba30457eb1121fa27753627c774c7cd4e90083"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/masterzen/winrm/soap",
|
||||
"Rev": "23128e7b3dc1f8091aeff7aae82cb2112ce53c75"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/masterzen/winrm/winrm",
|
||||
"Rev": "23128e7b3dc1f8091aeff7aae82cb2112ce53c75"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/masterzen/xmlpath",
|
||||
"Rev": "13f4951698adc0fa9c1dda3e275d489a24201161"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/mitchellh/cli",
|
||||
"Rev": "8102d0ed5ea2709ade1243798785888175f6e415"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/mitchellh/colorstring",
|
||||
"Rev": "61164e49940b423ba1f12ddbdf01632ac793e5e9"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/mitchellh/copystructure",
|
||||
"Rev": "6fc66267e9da7d155a9d3bd489e00dad02666dc6"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/mitchellh/go-homedir",
|
||||
"Rev": "1f6da4a72e57d4e7edd4a7295a585e0a3999a2d4"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/mitchellh/go-linereader",
|
||||
"Rev": "07bab5fdd9580500aea6ada0e09df4aa28e68abd"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/mitchellh/mapstructure",
|
||||
"Rev": "281073eb9eb092240d33ef253c404f1cca550309"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/mitchellh/osext",
|
||||
"Rev": "0dd3f918b21bec95ace9dc86c7e70266cfc5c702"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/mitchellh/packer/common/uuid",
|
||||
"Comment": "v0.8.2-4-g2010a0c",
|
||||
"Rev": "2010a0c966175b3c0fa8d158a879c10acbba0d76"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/mitchellh/panicwrap",
|
||||
"Rev": "45cbfd3bae250c7676c077fb275be1a2968e066a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/mitchellh/prefixedio",
|
||||
"Rev": "89d9b535996bf0a185f85b59578f2e245f9e1724"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/mitchellh/reflectwalk",
|
||||
"Rev": "eecf4c70c626c7cfbb95c90195bc34d386c74ac6"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/nu7hatch/gouuid",
|
||||
"Rev": "179d4d0c4d8d407a32af483c2354df1d2c91e6c3"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/packer-community/winrmcp/winrmcp",
|
||||
"Rev": "743b1afe5ee3f6d5ba71a0d50673fa0ba2123d6b"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/pearkes/cloudflare",
|
||||
"Rev": "19e280b056f3742e535ea12ae92a37ea7767ea82"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/pearkes/digitalocean",
|
||||
"Rev": "e966f00c2d9de5743e87697ab77c7278f5998914"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/pearkes/dnsimple",
|
||||
"Rev": "2a807d118c9e52e94819f414a6ec0293b45cad01"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/pearkes/mailgun",
|
||||
"Rev": "5b02e7e9ffee9869f81393e80db138f6ff726260"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/rackspace/gophercloud",
|
||||
"Comment": "v1.0.0-623-ge83aa01",
|
||||
"Rev": "e83aa011e019917c7bd951444d61c42431b4d21d"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/satori/go.uuid",
|
||||
"Rev": "afe1e2ddf0f05b7c29d388a3f8e76cb15c2231ca"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/soniah/dnsmadeeasy",
|
||||
"Comment": "v1.1-2-g5578a8c",
|
||||
"Rev": "5578a8c15e33958c61cf7db720b6181af65f4a9e"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vaughan0/go-ini",
|
||||
"Rev": "a98ad7ee00ec53921f08832bc06ecf7fd600e6a1"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/xanzy/go-cloudstack/cloudstack",
|
||||
"Comment": "v1.2.0-36-g0031956",
|
||||
"Rev": "00319560eeca5e6ffef3ba048c97c126a465854f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/crypto/ssh",
|
||||
"Rev": "7d5b0be716b9d6d4269afdaae10032bb296d3cdf"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/net/context",
|
||||
"Rev": "f0cf018861e2b54077eced91659e255072b5f215"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/oauth2",
|
||||
"Rev": "8914e5017ca260f2a3a1575b1e6868874050d95e"
|
||||
},
|
||||
{
|
||||
"ImportPath": "google.golang.org/api/compute/v1",
|
||||
"Rev": "18450f4e95c7e76ce3a5dc3a8cb7178ab6d56121"
|
||||
},
|
||||
{
|
||||
"ImportPath": "google.golang.org/api/container/v1",
|
||||
"Rev": "18450f4e95c7e76ce3a5dc3a8cb7178ab6d56121"
|
||||
},
|
||||
{
|
||||
"ImportPath": "google.golang.org/api/dns/v1",
|
||||
"Rev": "18450f4e95c7e76ce3a5dc3a8cb7178ab6d56121"
|
||||
},
|
||||
{
|
||||
"ImportPath": "google.golang.org/api/googleapi",
|
||||
"Rev": "18450f4e95c7e76ce3a5dc3a8cb7178ab6d56121"
|
||||
},
|
||||
{
|
||||
"ImportPath": "google.golang.org/api/storage/v1",
|
||||
"Rev": "18450f4e95c7e76ce3a5dc3a8cb7178ab6d56121"
|
||||
},
|
||||
{
|
||||
"ImportPath": "google.golang.org/cloud/compute/metadata",
|
||||
"Rev": "522a8ceb4bb83c2def27baccf31d646bce11a4b2"
|
||||
},
|
||||
{
|
||||
"ImportPath": "google.golang.org/cloud/internal",
|
||||
"Rev": "522a8ceb4bb83c2def27baccf31d646bce11a4b2"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -9,13 +9,18 @@ import (
|
|||
|
||||
const UniqueIdPrefix = `terraform-`
|
||||
|
||||
// Helper for a resource to generate a unique identifier
|
||||
// Helper for a resource to generate a unique identifier w/ default prefix
|
||||
func UniqueId() string {
|
||||
return PrefixedUniqueId(UniqueIdPrefix)
|
||||
}
|
||||
|
||||
// Helper for a resource to generate a unique identifier w/ given prefix
|
||||
//
|
||||
// This uses a simple RFC 4122 v4 UUID with some basic cosmetic filters
|
||||
// applied (base32, remove padding, downcase) to make visually distinguishing
|
||||
// identifiers easier.
|
||||
func UniqueId() string {
|
||||
return fmt.Sprintf("%s%s", UniqueIdPrefix,
|
||||
func PrefixedUniqueId(prefix string) string {
|
||||
return fmt.Sprintf("%s%s", prefix,
|
||||
strings.ToLower(
|
||||
strings.Replace(
|
||||
base32.StdEncoding.EncodeToString(uuidV4()),
|
||||
|
|
|
@ -9,4 +9,4 @@ DIR="$( cd -P "$( dirname "$SOURCE" )/.." && pwd )"
|
|||
cd $DIR
|
||||
|
||||
# Push the subtree (force)
|
||||
git push heroku `git subtree split --prefix website master`:master --force
|
||||
git push heroku `git subtree split --prefix website HEAD`:master --force
|
||||
|
|
|
@ -67,7 +67,7 @@ func s3Factory(conf map[string]string) (Client, error) {
|
|||
|
||||
awsConfig := &aws.Config{
|
||||
Credentials: credentialsProvider,
|
||||
Region: regionName,
|
||||
Region: aws.String(regionName),
|
||||
}
|
||||
nativeClient := s3.New(awsConfig)
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ func TestS3Factory(t *testing.T) {
|
|||
|
||||
s3Client := client.(*S3Client)
|
||||
|
||||
if s3Client.nativeClient.Config.Region != "us-west-1" {
|
||||
if *s3Client.nativeClient.Config.Region != "us-west-1" {
|
||||
t.Fatalf("Incorrect region was populated")
|
||||
}
|
||||
if s3Client.bucketName != "foo" {
|
||||
|
|
|
@ -78,6 +78,46 @@ func TestContext2Apply_providerAlias(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// GH-2870
|
||||
func TestContext2Apply_providerWarning(t *testing.T) {
|
||||
m := testModule(t, "apply-provider-warning")
|
||||
p := testProvider("aws")
|
||||
p.ApplyFn = testApplyFn
|
||||
p.DiffFn = testDiffFn
|
||||
p.ValidateFn = func(c *ResourceConfig) (ws []string, es []error) {
|
||||
ws = append(ws, "Just a warning")
|
||||
return
|
||||
}
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Module: m,
|
||||
Providers: map[string]ResourceProviderFactory{
|
||||
"aws": testProviderFuncFixed(p),
|
||||
},
|
||||
})
|
||||
|
||||
if _, err := ctx.Plan(); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
state, err := ctx.Apply()
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
actual := strings.TrimSpace(state.String())
|
||||
expected := strings.TrimSpace(`
|
||||
aws_instance.foo:
|
||||
ID = foo
|
||||
`)
|
||||
if actual != expected {
|
||||
t.Fatalf("got: \n%s\n\nexpected:\n%s", actual, expected)
|
||||
}
|
||||
|
||||
if !p.ConfigureCalled {
|
||||
t.Fatalf("provider Configure() was never called!")
|
||||
}
|
||||
}
|
||||
|
||||
func TestContext2Apply_emptyModule(t *testing.T) {
|
||||
m := testModule(t, "apply-empty-module")
|
||||
p := testProvider("aws")
|
||||
|
|
|
@ -94,7 +94,8 @@ func (n *EvalApply) Eval(ctx EvalContext) (interface{}, error) {
|
|||
// if we have one, otherwise we just output it.
|
||||
if err != nil {
|
||||
if n.Error != nil {
|
||||
*n.Error = multierror.Append(*n.Error, err)
|
||||
helpfulErr := fmt.Errorf("%s: %s", n.Info.Id, err.Error())
|
||||
*n.Error = multierror.Append(*n.Error, helpfulErr)
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package terraform
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
)
|
||||
|
||||
|
@ -35,7 +36,7 @@ func (n *EvalRefresh) Eval(ctx EvalContext) (interface{}, error) {
|
|||
// Refresh!
|
||||
state, err = provider.Refresh(n.Info, state)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, fmt.Errorf("%s: %s", n.Info.Id, err.Error())
|
||||
}
|
||||
|
||||
// Call post-refresh hook
|
||||
|
|
|
@ -40,9 +40,8 @@ func ProviderEvalTree(n string, config *config.RawConfig) EvalNode {
|
|||
},
|
||||
})
|
||||
|
||||
// Apply stuff
|
||||
seq = append(seq, &EvalOpFilter{
|
||||
Ops: []walkOperation{walkValidate, walkRefresh, walkPlan, walkApply},
|
||||
Ops: []walkOperation{walkValidate},
|
||||
Node: &EvalSequence{
|
||||
Nodes: []EvalNode{
|
||||
&EvalGetProvider{
|
||||
|
@ -70,6 +69,32 @@ func ProviderEvalTree(n string, config *config.RawConfig) EvalNode {
|
|||
},
|
||||
})
|
||||
|
||||
// Apply stuff
|
||||
seq = append(seq, &EvalOpFilter{
|
||||
Ops: []walkOperation{walkRefresh, walkPlan, walkApply},
|
||||
Node: &EvalSequence{
|
||||
Nodes: []EvalNode{
|
||||
&EvalGetProvider{
|
||||
Name: n,
|
||||
Output: &provider,
|
||||
},
|
||||
&EvalInterpolate{
|
||||
Config: config,
|
||||
Output: &resourceConfig,
|
||||
},
|
||||
&EvalBuildProviderConfig{
|
||||
Provider: n,
|
||||
Config: &resourceConfig,
|
||||
Output: &resourceConfig,
|
||||
},
|
||||
&EvalSetProviderConfig{
|
||||
Provider: n,
|
||||
Config: &resourceConfig,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
// We configure on everything but validate, since validate may
|
||||
// not have access to all the variables.
|
||||
seq = append(seq, &EvalOpFilter{
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
resource "aws_instance" "foo" {}
|
|
@ -1,7 +1,7 @@
|
|||
package terraform
|
||||
|
||||
// The main version number that is being run at the moment.
|
||||
const Version = "0.6.1"
|
||||
const Version = "0.6.2"
|
||||
|
||||
// A pre-release marker for the version. If this is "" (empty string)
|
||||
// then it means that it is a final release. Otherwise, this is a pre-release
|
||||
|
|
|
@ -57,7 +57,7 @@ resource "aws_elb" "bar" {
|
|||
|
||||
The following arguments are supported:
|
||||
|
||||
* `name` - (Required) The name of the ELB
|
||||
* `name` - (Optional) The name of the ELB. By default generated by terraform.
|
||||
* `availability_zones` - (Required for an EC2-classic ELB) The AZ's to serve traffic in.
|
||||
* `security_groups` - (Optional) A list of security group IDs to assign to the ELB.
|
||||
* `subnets` - (Required for a VPC ELB) A list of subnet IDs to attach to the ELB.
|
||||
|
|
|
@ -32,6 +32,7 @@ The following arguments are supported:
|
|||
* `private_ips` - (Optional) List of private IPs to assign to the ENI.
|
||||
* `security_groups` - (Optional) List of security group IDs to assign to the ENI.
|
||||
* `attachment` - (Required) Block to define the attachment of the ENI. Documented below.
|
||||
* `source_dest_check` - (Optional) Whether to enable source destination checking for the ENI. Default true.
|
||||
* `tags` - (Optional) A mapping of tags to assign to the resource.
|
||||
|
||||
The `attachment` block supports:
|
||||
|
@ -47,5 +48,6 @@ The following attributes are exported:
|
|||
* `private_ips` - List of private IPs assigned to the ENI.
|
||||
* `security_groups` - List of security groups attached to the ENI.
|
||||
* `attachment` - Block defining the attachment of the ENI.
|
||||
* `source_dest_check` - Whether source destination checking is enabled
|
||||
* `tags` - Tags assigned to the ENI.
|
||||
|
||||
|
|
|
@ -67,3 +67,4 @@ The following attributes are exported:
|
|||
* `hosted_zone_id` - The [Route 53 Hosted Zone ID](http://docs.aws.amazon.com/general/latest/gr/rande.html#s3_website_region_endpoints) for this bucket's region.
|
||||
* `region` - The AWS region this bucket resides in.
|
||||
* `website_endpoint` - The website endpoint, if the bucket is configured with a website. If not, this will be an empty string.
|
||||
* `website_domain` - The domain of the website endpoint, if the bucket is configured with a website. If not, this will be an empty string. This is used to create Route 53 alias records.
|
||||
|
|
|
@ -25,10 +25,10 @@ resource "aws_sqs_queue" "terraform_queue" {
|
|||
The following arguments are supported:
|
||||
|
||||
* `name` - (Required) This is the human-readable name of the queue
|
||||
* `visibility_timeout_seconds` - (Optional) The time in seconds that the delivery of all messages in the queue will be delayed. An integer from 0 to 900 (15 minutes). The default for this attribute is 30 seconds
|
||||
* `visibility_timeout_seconds` - (Optional) The visibility timeout for the queue. An integer from 0 to 43200 (12 hours). The default for this attribute is 30. For more information about visibility timeout see AWS docs.
|
||||
* `message_retention_seconds` - (Optional) The number of seconds Amazon SQS retains a message. Integer representing seconds, from 60 (1 minute) to 1209600 (14 days). The default for this attribute is 345600 (4 days).
|
||||
* `max_message_size` - (Optional) The limit of how many bytes a message can contain before Amazon SQS rejects it. An integer from 1024 bytes (1 KiB) up to 262144 bytes (256 KiB). The default for this attribute is 262144 (256 KiB).
|
||||
* `delay_seconds` - (Optional) The visibility timeout for the queue. An integer from 0 to 43200 (12 hours). The default for this attribute is 30. For more information about visibility timeout.
|
||||
* `delay_seconds` - (Optional) The time in seconds that the delivery of all messages in the queue will be delayed. An integer from 0 to 900 (15 minutes). The default for this attribute is 30 seconds.
|
||||
* `receive_wait_time_seconds` - (Optional) The time for which a ReceiveMessage call will wait for a message to arrive (long polling) before returning. An integer from 0 to 20 (seconds). The default for this attribute is 0, meaning that the call will return immediately.
|
||||
* `policy` - (Optional) The JSON policy for the SQS queue
|
||||
|
||||
|
|
|
@ -72,7 +72,8 @@ The following arguments are supported:
|
|||
|
||||
* `storage_service_name` - (Optional) The name of an existing storage account
|
||||
within the subscription which will be used to store the VHDs of this
|
||||
instance. Changing this forces a new resource to be created.
|
||||
instance. Changing this forces a new resource to be created. **A Storage
|
||||
Service is required if you are using a Platform Image**
|
||||
|
||||
* `reverse_dns` - (Optional) The DNS address to which the IP address of the
|
||||
hosted service resolves when queried using a reverse DNS query. Changing
|
||||
|
|
|
@ -26,7 +26,7 @@ resource "azure_storage_service" "tfstor" {
|
|||
The following arguments are supported:
|
||||
|
||||
* `name` - (Required) The name of the storage service. Must be between 4 and 24
|
||||
lowercase-only characters or digits Must be unique on Azure.
|
||||
lowercase-only characters or digits. Must be unique on Azure.
|
||||
|
||||
* `location` - (Required) The location where the storage service should be created.
|
||||
For a list of all Azure locations, please consult [this link](http://azure.microsoft.com/en-us/regions/).
|
||||
|
|
|
@ -19,7 +19,7 @@ Use the navigation to the left to read about the available resources.
|
|||
```
|
||||
# Configure the Google Cloud provider
|
||||
provider "google" {
|
||||
account_file = "account.json"
|
||||
account_file = "${file("account.json")}"
|
||||
project = "my-gce-project"
|
||||
region = "us-central1"
|
||||
}
|
||||
|
@ -34,12 +34,12 @@ resource "google_compute_instance" "default" {
|
|||
|
||||
The following keys can be used to configure the provider.
|
||||
|
||||
* `account_file` - (Required) Path to the JSON file used to describe your
|
||||
* `account_file` - (Required) Contents of the JSON file used to describe your
|
||||
account credentials, downloaded from Google Cloud Console. More details on
|
||||
retrieving this file are below. The _account file_ can be "" if you
|
||||
are running terraform from a GCE instance with a properly-configured [Compute
|
||||
Engine Service Account](https://cloud.google.com/compute/docs/authentication).
|
||||
This can also be specified with the `GOOGLE_ACCOUNT_FILE` shell environment
|
||||
retrieving this file are below. The `account file` can be "" if you are running
|
||||
terraform from a GCE instance with a properly-configured [Compute Engine
|
||||
Service Account](https://cloud.google.com/compute/docs/authentication). This
|
||||
can also be specified with the `GOOGLE_ACCOUNT_FILE` shell environment
|
||||
variable.
|
||||
|
||||
* `project` - (Required) The ID of the project to apply any resources to. This
|
||||
|
|
|
@ -0,0 +1,135 @@
|
|||
---
|
||||
layout: "google"
|
||||
page_title: "Google: google_compute_autoscaler"
|
||||
sidebar_current: "docs-google-resource-compute-autoscaler"
|
||||
description: |-
|
||||
Manages an Autoscaler within GCE.
|
||||
---
|
||||
|
||||
# google\_compute\_autoscaler
|
||||
|
||||
A Compute Engine Autoscaler automatically adds or removes virtual machines from
|
||||
a managed instance group based on increases or decreases in load. This allows
|
||||
your applications to gracefully handle increases in traffic and reduces cost
|
||||
when the need for resources is lower. You just define the autoscaling policy and
|
||||
the autoscaler performs automatic scaling based on the measured load. For more
|
||||
information, see [the official
|
||||
documentation](https://cloud.google.com/compute/docs/autoscaler/) and
|
||||
[API](https://cloud.google.com/compute/docs/autoscaler/v1beta2/autoscalers)
|
||||
|
||||
|
||||
## Example Usage
|
||||
|
||||
```
|
||||
resource "google_compute_instance_template" "foobar" {
|
||||
name = "foobar"
|
||||
machine_type = "n1-standard-1"
|
||||
can_ip_forward = false
|
||||
tags = ["foo", "bar"]
|
||||
|
||||
disk {
|
||||
source_image = "debian-cloud/debian-7-wheezy-v20140814"
|
||||
}
|
||||
|
||||
network_interface {
|
||||
network = "default"
|
||||
}
|
||||
|
||||
metadata {
|
||||
foo = "bar"
|
||||
}
|
||||
|
||||
service_account {
|
||||
scopes = ["userinfo-email", "compute-ro", "storage-ro"]
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_compute_target_pool" "foobar" {
|
||||
name = "foobar"
|
||||
}
|
||||
|
||||
resource "google_compute_instance_group_manager" "foobar" {
|
||||
name = "foobar"
|
||||
instance_template = "${google_compute_instance_template.foobar.self_link}"
|
||||
target_pools = ["${google_compute_target_pool.foobar.self_link}"]
|
||||
base_instance_name = "foobar"
|
||||
zone = "us-central1-f"
|
||||
}
|
||||
|
||||
resource "google_compute_autoscaler" "foobar" {
|
||||
name = "foobar"
|
||||
zone = "us-central1-f"
|
||||
target = "${google_compute_instance_group_manager.foobar.self_link}"
|
||||
autoscaling_policy = {
|
||||
max_replicas = 5
|
||||
min_replicas = 1
|
||||
cooldown_period = 60
|
||||
cpu_utilization = {
|
||||
target = 0.5
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Argument Refernce
|
||||
|
||||
The following arguments are supported:
|
||||
|
||||
* `description` - (Optional) An optional textual description of the instance
|
||||
group manager.
|
||||
|
||||
* `target` - (Required) The full URL to the instance group manager whose size we
|
||||
control.
|
||||
|
||||
* `autoscaling_policy.` - (Required) The parameters of the autoscaling
|
||||
algorithm. Structure is documented below.
|
||||
|
||||
* `zone` - (Required) The zone of the target.
|
||||
|
||||
The `autoscaling_policy` block contains:
|
||||
|
||||
* `max_replicas` - (Required) The group will never be larger than this.
|
||||
|
||||
* `min_replicas` - (Required) The group will never be smaller than this.
|
||||
|
||||
* `cooldown_period` - (Optional) Period to wait between changes. This should be
|
||||
at least double the time your instances take to start up.
|
||||
|
||||
* `cpu_utilization` - (Optional) A policy that scales when the cluster's average
|
||||
CPU is above or below a given threshold. Structure is documented below.
|
||||
|
||||
* `metric` - (Optional) A policy that scales according to Google Cloud
|
||||
Monitoring metrics Structure is documented below.
|
||||
|
||||
* `load_balancing_utilization` - (Optional) A policy that scales when the load
|
||||
reaches a proportion of a limit defined in the HTTP load balancer. Structure
|
||||
is documented below.
|
||||
|
||||
The `cpu_utilization` block contains:
|
||||
|
||||
* `target` - The floating point threshold where CPU utilization should be. E.g.
|
||||
for 50% one would specify 0.5.
|
||||
|
||||
The `metric` block contains (more documentation
|
||||
[here](https://cloud.google.com/monitoring/api/metrics)):
|
||||
|
||||
* `name` - The name of the Google Cloud Monitoring metric to follow, e.g.
|
||||
compute.googleapis.com/instance/network/received_bytes_count
|
||||
|
||||
* `type` - Either "cumulative", "delta", or "gauge".
|
||||
|
||||
* `target` - The desired metric value per instance. Must be a positive value.
|
||||
|
||||
The `load_balancing_utilization` block contains:
|
||||
|
||||
* `target` - The floating point threshold where load balancing utilization
|
||||
should be. E.g. if the load balancer's `maxRatePerInstance` is 10 requests
|
||||
per second (RPS) then setting this to 0.5 would cause the group to be scaled
|
||||
such that each instance receives 5 RPS.
|
||||
|
||||
|
||||
## Attributes Reference
|
||||
|
||||
The following attributes are exported:
|
||||
|
||||
* `self_link` - The URL of the created resource.
|
|
@ -0,0 +1,65 @@
|
|||
---
|
||||
layout: "google"
|
||||
page_title: "Google: google_compute_instance_group_manager"
|
||||
sidebar_current: "docs-google-resource-compute-instance_group_manager"
|
||||
description: |-
|
||||
Manages an Instance Group within GCE.
|
||||
---
|
||||
|
||||
# google\_compute\_instance\_group\_manager
|
||||
|
||||
The Google Compute Engine Instance Group Manager API creates and manages pools
|
||||
of homogeneous Compute Engine virtual machine instances from a common instance
|
||||
template. For more information, see [the official documentation](https://cloud.google.com/compute/docs/instance-groups/manager
|
||||
and [API](https://cloud.google.com/compute/docs/instance-groups/manager/v1beta2/instanceGroupManagers)
|
||||
|
||||
## Example Usage
|
||||
|
||||
```
|
||||
resource "google_compute_instance_group_manager" "foobar" {
|
||||
description = "Terraform test instance group manager"
|
||||
name = "terraform-test"
|
||||
instance_template = "${google_compute_instance_template.foobar.self_link}"
|
||||
target_pools = ["${google_compute_target_pool.foobar.self_link}"]
|
||||
base_instance_name = "foobar"
|
||||
zone = "us-central1-a"
|
||||
target_size = 2
|
||||
}
|
||||
```
|
||||
|
||||
## Argument Refernce
|
||||
|
||||
The following arguments are supported:
|
||||
|
||||
* `base_instance_name` - (Required) The base instance name to use for
|
||||
instances in this group. The value must be a valid [RFC1035](https://www.ietf.org/rfc/rfc1035.txt) name.
|
||||
Supported characters are lowercase letters, numbers, and hyphens (-). Instances
|
||||
are named by appending a hyphen and a random four-character string to the base
|
||||
instance name.
|
||||
|
||||
* `description` - (Optional) An optional textual description of the instance
|
||||
group manager.
|
||||
|
||||
* `instance_template` - (Required) The full URL to an instance template from
|
||||
which all new instances will be created.
|
||||
|
||||
* `name` - (Required) The name of the instance group manager. Must be 1-63
|
||||
characters long and comply with [RFC1035](https://www.ietf.org/rfc/rfc1035.txt).
|
||||
Supported characters include lowercase letters, numbers, and hyphens.
|
||||
|
||||
* `target_size` - (Optional) If not given at creation time, this defaults to 1. Do not specify this
|
||||
if you are managing the group with an autoscaler, as this will cause fighting.
|
||||
|
||||
* `target_pools` - (Required) The full URL of all target pools to which new
|
||||
instances in the group are added. Updating the target pool values does not
|
||||
affect existing instances.
|
||||
|
||||
* `zone` - (Required) The zone that instances in this group should be created in.
|
||||
|
||||
## Attributes Reference
|
||||
|
||||
The following attributes are exported:
|
||||
|
||||
* `instance_group` - The full URL of the instance group created by the manager.
|
||||
|
||||
* `self_link` - The URL of the created resource.
|
|
@ -32,6 +32,24 @@
|
|||
ga('send', 'pageview');
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
adroll_adv_id = "6QAAFJDIWBG3DJBDRJ7BEX";
|
||||
adroll_pix_id = "PYT5HSNKNRDS7LMUR5B6YG";
|
||||
(function () {
|
||||
var oldonload = window.onload;
|
||||
window.onload = function(){
|
||||
__adroll_loaded=true;
|
||||
var scr = document.createElement("script");
|
||||
var host = (("https:" == document.location.protocol) ? "https://s.adroll.com" : "http://a.adroll.com");
|
||||
scr.setAttribute('async', 'true');
|
||||
scr.type = "text/javascript";
|
||||
scr.src = host + "/j/roundtrip.js";
|
||||
((document.getElementsByTagName('head') || [null])[0] ||
|
||||
document.getElementsByTagName('script')[0].parentNode).appendChild(scr);
|
||||
if(oldonload){oldonload()}};
|
||||
}());
|
||||
</script>
|
||||
|
||||
<%= javascript_include_tag "application" %>
|
||||
|
||||
</body>
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue