Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into issue-1146
Browse files Browse the repository at this point in the history
* origin/master: (59 commits)
  Update CHANGELOG for hashicorp#13935
  resource/aws_batch_compute_environment: Remove resource from Terraform state when not found instead of returning error (hashicorp#13935)
  resource/aws_dynamodb_table: Return error instead of panic on empty CreateTable response (hashicorp#13925)
  Update CHANGELOG for hashicorp#13918
  New Data Source: aws_efs_access_points (hashicorp#13918)
  tests/resource/aws_instance: Ensure sweeper has dependencies on resources that manage EC2 Instances (hashicorp#13917)
  Update CHANGELOG for hashicorp#13937
  Update CHANGELOG for hashicorp#5448
  resource/aws_cloudtrail: Handle single event selector in cloudtrail with non-default read_write_type (hashicorp#5448)
  Update CHANGELOG for hashicorp#13892
  correct retry message to match in error handling
  correct import resource name
  accept empty string in volume_type validation
  Update CHANGELOG for hashicorp#4855
  resource/aws_batch_compute_environment: Support fully optional desired_vcpus and wait for updates
  add retry error handling for SLR
  remove unused WebACL resource name in disappears test
  reference current AWS partition in iam role policy stmt
  remove duplicated disappears test step
  Update CHANGELOG for hashicorp#13926
  ...
  • Loading branch information
c4po committed Jun 25, 2020
2 parents 76c63f4 + 14fbdd6 commit 4e3fb60
Show file tree
Hide file tree
Showing 85 changed files with 2,882 additions and 555 deletions.
28 changes: 28 additions & 0 deletions CHANGELOG.md
@@ -1,31 +1,59 @@
## 2.68.0 (Unreleased)

FEATURES:

* **New Data Source:** `aws_efs_access_points` [GH-13918]
* **New Resource:** `aws_wafv2_web_acl_logging_configuration` [GH-13892]

ENHANCEMENTS:

* data-soruce/aws_ami: Add `arn` attribute [GH-12038]
* data-source/aws_customer_gateway: Add `arn` attribute [GH-13611]
* data-source/aws_ebs_snapshot: Add `arn` attribute [GH-13840]
* data-source/aws_vpc_endpoint: Add `arn` attribute [GH-13852]
* data-source/aws_vpc_endpoint_service: Add `arn` attribute [GH-13856]
* data-source/aws_vpn_gateway: Add `arn` attribute [GH-13827]
* resource/aws_ami: Add `arn` attribute and plan-time validations to `architecture`, `volume_type` and `virtualization_type` arguments [GH-12038]
* resource/aws_ami_copy: Add `arn` attribute [GH-12038]
* resource/aws_ami_from_instance: Add `arn` attribute [GH-12038]
* resource/aws_customer_gateway: Add `arn` attribute and plan-time validations for `bgp_asn`, `ip_address`, and `type` arguments [GH-13611]
* resource/aws_default_network_acl: Add `arn` attribute and plan-time validations for `ingress` and `egress` configuration block arguments [GH-13819]
* resource/aws_ebs_snapshot: Add `arn` attribute [GH-13840]
* resource/aws_ebs_snapshot: Support resource import [GH-13895]
* resource/aws_ebs_snapshot_copy: Add `arn` attribute [GH-13840]
* resource/aws_ec2_traffic_mirror_session: Add `arn` attribute [GH-13849]
* resource/aws_ecs_service: Support `deployment_controller` configuration block `type` argument value of `EXTERNAL` (support external deployments) [GH-8134] / [GH-8652]
* resource/aws_ecs_task_definition: Add `efs_volume_configuration` configuration block `authorization_config`, `transit_encryption`, and `transit_encryption_port` arguments (support EFS Access Points and transit encryption) [GH-13136]
* resource/aws_glue_catalog_database: Add `arn` attribute [GH-13452]
* resource/aws_iot_policy: Support resource import [GH-13707]
* resource/aws_iot_topic_rule: Add `error_action` configuration block [GH-11922]
* resource/aws_network_acl: Add `arn` attribute and plan-time validations for `ingress` and `egress` configuration block arguments [GH-13819]
* resource/aws_placement_group: Add `arn` attribute [GH-13838]
* resource/aws_ses_receipt_filter: Add `arn` attribute and plan-time validations for all arguments [GH-13811]
* resource/aws_vpn_connection: Add `arn` attribute [GH-13836]
* resource/aws_vpc_endpoint: Add `arn` attribute [GH-13853]
* resource/aws_vpc_endpoint_service: Add `arn` attribute [GH-13858]
* resource/aws_vpn_gateway: Add `arn` attribute [GH-13827]

BUG FIXES:

* resource/aws_batch_compute_environment: Ensure `desired_vcpus` is fully optional and wait for updates [GH-4855]
* resource/aws_batch_compute_environment: Remove resource from Terraform state when not found instead of returning error [GH-13935]
* resource/aws_cloudtrail: Properly configure single `event_selector` with no `data_resource` and `read_write_type` of `ReadOnly` or `WriteOnly` [GH-5448]
* resource/aws_cloudtrail: Prevent `InvalidEventSelectorsException` error when removing all `event_selector` configuration [GH-5448]
* resource/aws_default_route_table: Validate CIDR blocks for misalignment before attempting to create the route to ensure Terraform can read the information after EC2 API canonicalization [GH-13778]
* resource/aws_default_route_table: Ensure empty string (`""`) validation in `cidr_block` and `ipv6_cidr_block` arguments continues to work for Terraform 0.11 support [GH-13778]
* resource/aws_ecs_service: Add plan-time validation and prevent panics with empty `type` argument in `ordered_placement_strategy` configuration block [GH-13926]
* resource/aws_ecs_task_definition: Prevent showing API ordering differences in `container_definitions` environment variables during update plans [GH-11463]
* resource/aws_elasticsearch_domain: Ensure empty string (`""`) validation in `ebs_options` `volume_type` argument continues to work for Terraform 0.11 support [GH-13937]
* resource/aws_iot_policy: Ensure `name` argument updates recreate the resource [GH-13707]
* resource/aws_route: Validate CIDR blocks for misalignment before attempting to create the route to ensure Terraform can read the information after EC2 API canonicalization [GH-13778]
* resource/aws_route: Ensure empty string (`""`) validation in `destination_cidr_block` and `destination_ipv6_cidr_block` arguments continues to work for Terraform 0.11 support [GH-13778]
* resource/aws_route_table: Validate CIDR blocks for misalignment before attempting to create the route to ensure Terraform can read the information after EC2 API canonicalization [GH-13778]
* resource/aws_route_table: Ensure empty string (`""`) validation in `cidr_block` and `ipv6_cidr_block` arguments continues to work for Terraform 0.11 support [GH-13778]
* resource/aws_spot_fleet_request: Prevent crash with missing placement information [GH-13577]
* resource/aws_vpc_endpoint: Skip `ModifyVpcEndpoint` API call on tags only updates [GH-13853]
* resource/aws_vpc_endpoint: Wait for acceptance when `auto_accept` is enabled [GH-13876]
* resource/aws_wafv2_web_acl: Prevent unexpected `UpdateWebACL` API errors on tags only updates [GH-13871]

## 2.67.0 (June 19, 2020)
Expand Down
4 changes: 4 additions & 0 deletions aws/config.go
Expand Up @@ -729,6 +729,10 @@ func (c *Config) Client() (interface{}, error) {
r.Retryable = aws.Bool(true)
}

if isAWSErr(r.Error, wafv2.ErrCodeWAFServiceLinkedRoleErrorException, "Retry") {
r.Retryable = aws.Bool(true)
}

if r.Operation.Name == "CreateIPSet" || r.Operation.Name == "CreateRegexPatternSet" ||
r.Operation.Name == "CreateRuleGroup" || r.Operation.Name == "CreateWebACL" {
// WAFv2 supports tag on create which can result in the below error codes according to the documentation
Expand Down
35 changes: 26 additions & 9 deletions aws/data_source_aws_ami.go
Expand Up @@ -9,6 +9,7 @@ import (
"time"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/arn"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/hashicorp/terraform-plugin-sdk/helper/hashcode"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
Expand All @@ -21,6 +22,10 @@ func dataSourceAwsAmi() *schema.Resource {
Read: dataSourceAwsAmiRead,

Schema: map[string]*schema.Schema{
"arn": {
Type: schema.TypeString,
Computed: true,
},
"filter": dataSourceFiltersSchema(),
"executable_users": {
Type: schema.TypeList,
Expand Down Expand Up @@ -184,7 +189,6 @@ func dataSourceAwsAmi() *schema.Resource {
// dataSourceAwsAmiDescriptionRead performs the AMI lookup.
func dataSourceAwsAmiRead(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).ec2conn
ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig

params := &ec2.DescribeImagesInput{
Owners: expandStringList(d.Get("owners").([]interface{})),
Expand All @@ -210,13 +214,13 @@ func dataSourceAwsAmiRead(d *schema.ResourceData, meta interface{}) error {
// Check for a very rare case where the response would include no
// image name. No name means nothing to attempt a match against,
// therefore we are skipping such image.
if image.Name == nil || *image.Name == "" {
if image.Name == nil || aws.StringValue(image.Name) == "" {
log.Printf("[WARN] Unable to find AMI name to match against "+
"for image ID %q owned by %q, nothing to do.",
*image.ImageId, *image.OwnerId)
aws.StringValue(image.ImageId), aws.StringValue(image.OwnerId))
continue
}
if r.MatchString(*image.Name) {
if r.MatchString(aws.StringValue(image.Name)) {
filteredImages = append(filteredImages, image)
}
}
Expand All @@ -240,13 +244,15 @@ func dataSourceAwsAmiRead(d *schema.ResourceData, meta interface{}) error {
})
}

return amiDescriptionAttributes(d, filteredImages[0], ignoreTagsConfig)
return amiDescriptionAttributes(d, filteredImages[0], meta)
}

// populate the numerous fields that the image description returns.
func amiDescriptionAttributes(d *schema.ResourceData, image *ec2.Image, ignoreTagsConfig *keyvaluetags.IgnoreConfig) error {
func amiDescriptionAttributes(d *schema.ResourceData, image *ec2.Image, meta interface{}) error {
ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig

// Simple attributes first
d.SetId(*image.ImageId)
d.SetId(aws.StringValue(image.ImageId))
d.Set("architecture", image.Architecture)
d.Set("creation_date", image.CreationDate)
if image.Description != nil {
Expand Down Expand Up @@ -294,6 +300,16 @@ func amiDescriptionAttributes(d *schema.ResourceData, image *ec2.Image, ignoreTa
if err := d.Set("tags", keyvaluetags.Ec2KeyValueTags(image.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil {
return fmt.Errorf("error setting tags: %s", err)
}

imageArn := arn.ARN{
Partition: meta.(*AWSClient).partition,
Region: meta.(*AWSClient).region,
Resource: fmt.Sprintf("image/%s", d.Id()),
Service: "ec2",
}.String()

d.Set("arn", imageArn)

return nil
}

Expand Down Expand Up @@ -348,11 +364,12 @@ func amiRootSnapshotId(image *ec2.Image) string {
return ""
}
for _, bdm := range image.BlockDeviceMappings {
if bdm.DeviceName == nil || *bdm.DeviceName != *image.RootDeviceName {
if bdm.DeviceName == nil ||
aws.StringValue(bdm.DeviceName) != aws.StringValue(image.RootDeviceName) {
continue
}
if bdm.Ebs != nil && bdm.Ebs.SnapshotId != nil {
return *bdm.Ebs.SnapshotId
return aws.StringValue(bdm.Ebs.SnapshotId)
}
}
return ""
Expand Down
1 change: 1 addition & 0 deletions aws/data_source_aws_ami_test.go
Expand Up @@ -26,6 +26,7 @@ func TestAccAWSAmiDataSource_natInstance(t *testing.T) {
// deep inspection is not included, simply the count is checked.
// Tags and product codes may need more testing, but I'm having a hard time finding images with
// these attributes set.
testAccMatchResourceAttrRegionalARNNoAccount(resourceName, "arn", "ec2", regexp.MustCompile(`image/ami-.+`)),
resource.TestCheckResourceAttr(resourceName, "architecture", "x86_64"),
resource.TestCheckResourceAttr(resourceName, "block_device_mappings.#", "1"),
resource.TestMatchResourceAttr(resourceName, "creation_date", regexp.MustCompile("^20[0-9]{2}-")),
Expand Down
83 changes: 83 additions & 0 deletions aws/data_source_aws_efs_access_points.go
@@ -0,0 +1,83 @@
package aws

import (
"fmt"
"time"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/efs"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
)

func dataSourceAwsEfsAccessPoints() *schema.Resource {
return &schema.Resource{
Read: dataSourceAwsEfsAccessPointsRead,

Schema: map[string]*schema.Schema{
"arns": {
Type: schema.TypeSet,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"file_system_id": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.StringIsNotEmpty,
},
"ids": {
Type: schema.TypeSet,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
},
}
}

func dataSourceAwsEfsAccessPointsRead(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).efsconn

fileSystemId := d.Get("file_system_id").(string)
input := &efs.DescribeAccessPointsInput{
FileSystemId: aws.String(fileSystemId),
}

var accessPoints []*efs.AccessPointDescription

err := conn.DescribeAccessPointsPages(input, func(page *efs.DescribeAccessPointsOutput, lastPage bool) bool {
if page == nil {
return !lastPage
}

accessPoints = append(accessPoints, page.AccessPoints...)

return !lastPage
})

if err != nil {
return fmt.Errorf("error reading EFS Access Points for File System (%s): %w", fileSystemId, err)
}

if len(accessPoints) == 0 {
return fmt.Errorf("no matching EFS Access Points for File System (%s) found", fileSystemId)
}

d.SetId(time.Now().UTC().String())

var arns, ids []string

for _, accessPoint := range accessPoints {
arns = append(arns, aws.StringValue(accessPoint.AccessPointArn))
ids = append(ids, aws.StringValue(accessPoint.AccessPointId))
}

if err := d.Set("arns", arns); err != nil {
return fmt.Errorf("error setting arns: %w", err)
}

if err := d.Set("ids", ids); err != nil {
return fmt.Errorf("error setting ids: %w", err)
}

return nil
}
40 changes: 40 additions & 0 deletions aws/data_source_aws_efs_access_points_test.go
@@ -0,0 +1,40 @@
package aws

import (
"testing"

"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
)

func TestAccDataSourceAWSEFSAccessPoints_basic(t *testing.T) {
dataSourceName := "data.aws_efs_access_points.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckEfsAccessPointDestroy,
Steps: []resource.TestStep{
{
Config: testAccDataSourceAWSEFSAccessPointsConfig(),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(dataSourceName, "arns.#", "1"),
resource.TestCheckResourceAttr(dataSourceName, "ids.#", "1"),
),
},
},
})
}

func testAccDataSourceAWSEFSAccessPointsConfig() string {
return `
resource "aws_efs_file_system" "test" {}
resource "aws_efs_access_point" "test" {
file_system_id = aws_efs_file_system.test.id
}
data "aws_efs_access_points" "test" {
file_system_id = aws_efs_access_point.test.file_system_id
}
`
}
6 changes: 6 additions & 0 deletions aws/diff_suppress_funcs.go
Expand Up @@ -132,3 +132,9 @@ func suppressRoute53ZoneNameWithTrailingDot(k, old, new string, d *schema.Resour
}
return strings.TrimSuffix(old, ".") == strings.TrimSuffix(new, ".")
}

// suppressEqualCIDRBlockDiffs provides custom difference suppression for CIDR blocks
// that have different string values but represent the same CIDR.
func suppressEqualCIDRBlockDiffs(k, old, new string, d *schema.ResourceData) bool {
return cidrBlocksEqual(old, new)
}
16 changes: 11 additions & 5 deletions aws/ecs_task_definition_equivalency.go
Expand Up @@ -56,6 +56,9 @@ func EcsContainerDefinitionsAreEquivalent(def1, def2 string, isAWSVPC bool) (boo
type containerDefinitions []*ecs.ContainerDefinition

func (cd containerDefinitions) Reduce(isAWSVPC bool) error {
// Deal with fields which may be re-ordered in the API
cd.OrderEnvironmentVariables()

for i, def := range cd {
// Deal with special fields which have defaults
if def.Cpu != nil && *def.Cpu == 0 {
Expand All @@ -76,11 +79,6 @@ func (cd containerDefinitions) Reduce(isAWSVPC bool) error {
}
}

// Deal with fields which may be re-ordered in the API
sort.Slice(def.Environment, func(i, j int) bool {
return aws.StringValue(def.Environment[i].Name) < aws.StringValue(def.Environment[j].Name)
})

// Create a mutable copy
defCopy, err := copystructure.Copy(def)
if err != nil {
Expand All @@ -103,3 +101,11 @@ func (cd containerDefinitions) Reduce(isAWSVPC bool) error {
}
return nil
}

func (cd containerDefinitions) OrderEnvironmentVariables() {
for _, def := range cd {
sort.Slice(def.Environment, func(i, j int) bool {
return aws.StringValue(def.Environment[i].Name) < aws.StringValue(def.Environment[j].Name)
})
}
}
15 changes: 0 additions & 15 deletions aws/network_acl_entry.go
Expand Up @@ -2,7 +2,6 @@ package aws

import (
"fmt"
"net"
"strconv"

"github.com/aws/aws-sdk-go/aws"
Expand Down Expand Up @@ -233,17 +232,3 @@ func validatePorts(to int64, from int64, expected expectedPortPair) bool {

return true
}

// validateCIDRBlock ensures the passed CIDR block represents an implied
// network, and not an overly-specified IP address.
func validateCIDRBlock(cidr string) error {
_, ipnet, err := net.ParseCIDR(cidr)
if err != nil {
return err
}
if ipnet.String() != cidr {
return fmt.Errorf("%s is not a valid mask; did you mean %s?", cidr, ipnet)
}

return nil
}
20 changes: 0 additions & 20 deletions aws/network_acl_entry_test.go
Expand Up @@ -98,23 +98,3 @@ func Test_validatePorts(t *testing.T) {
}
}
}

func Test_validateCIDRBlock(t *testing.T) {
for _, ts := range []struct {
cidr string
shouldErr bool
}{
{"10.2.2.0/24", false},
{"10.2.2.0/1234", true},
{"10/24", true},
{"10.2.2.2/24", true},
} {
err := validateCIDRBlock(ts.cidr)
if ts.shouldErr && err == nil {
t.Fatalf("Input '%s' should error but didn't!", ts.cidr)
}
if !ts.shouldErr && err != nil {
t.Fatalf("Got unexpected error for '%s' input: %s", ts.cidr, err)
}
}
}

0 comments on commit 4e3fb60

Please sign in to comment.