Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Resources: aws_lightsail_lb and aws_lightsail_lb_attachment #27339

Merged
merged 42 commits into from
Oct 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
26862f2
Added Lightsail load balancer resource, fixed 'disapear' typo in ligh…
akonrath Nov 24, 2019
3e88cf8
Action Required: Removal of website/aws.erb File
brittandeyoung Feb 24, 2021
4fa9805
Fixed: Action Required: Terraform Plugin SDK V2
Feb 24, 2021
a4dcde1
Merge pull request #83 from brittandeyoung/patch-1
akonrath Feb 25, 2021
43bbaf4
Removed conflicting changes
brittandeyoung Feb 25, 2021
7f65c40
* Fixed usage of SetPartial
Feb 25, 2021
955b12f
Merge pull request #88 from brittandeyoung/patch-2
akonrath Feb 25, 2021
9e4d71b
Fixed:
Feb 26, 2021
b48d5c6
Merge branch 'main' of https://github.com/hashicorp/terraform-provide…
Feb 26, 2021
7c24c54
fixed: AWSR002
Feb 26, 2021
89b5467
Merge pull request #91 from brittandeyoung/patch-2
akonrath Feb 27, 2021
a2c4807
Created Internal Waiter files
Mar 2, 2021
6a146ba
FIxed:
Mar 2, 2021
df2e0e3
added aws sdk import
Mar 2, 2021
26ae514
Fixed: Waiter input type
Mar 2, 2021
d9beabd
Updated healthcheckpath test name
Mar 2, 2021
be02e54
fixed import order an String format
Mar 2, 2021
72ad656
switched to aws.stringvalue
Mar 2, 2021
cb72b94
resolved import order
Mar 2, 2021
9c4e385
Merge pull request #96 from brittandeyoung/patch-2
akonrath Mar 4, 2021
5551236
Merge branch 'feature/lightsail-akonrath'
brittandeyoung Oct 19, 2022
acffe67
lightsail: Amend consts add ResLoadBalancer
brittandeyoung Oct 19, 2022
841e27b
lightsail: Amend find add FindLoadBalancerByName
brittandeyoung Oct 19, 2022
d2157fd
lightsail: Add lb resource
brittandeyoung Oct 19, 2022
57a637d
provider: Amend provider to add aws_lightsail_lb
brittandeyoung Oct 19, 2022
cd77a7d
lightsail: Add aws_lightsail_lb_test
brittandeyoung Oct 19, 2022
ce6167c
Lightsail: Amend lb remove d.SetId()
brittandeyoung Oct 19, 2022
23a85d3
Docs: Add lightsail_lb resource docs
brittandeyoung Oct 19, 2022
6d5b368
lightsail: Amend consts add ResLoadBalancerAttachment
brittandeyoung Oct 19, 2022
4aa9f69
lightsail: Amend find Add FindLoadBalancerAttachmentById
brittandeyoung Oct 19, 2022
01d66ce
lightsail: Add lb_attachment resource
brittandeyoung Oct 19, 2022
0866119
lightsail: Add lb_attachment_test
brittandeyoung Oct 19, 2022
3bbbd59
lightsail: Amend lb
brittandeyoung Oct 19, 2022
325636b
docs: Add lightsail_lb_attachment docs
brittandeyoung Oct 19, 2022
213498f
Merge branch 'main' into f-aws_lightsail_lb
brittandeyoung Oct 19, 2022
5ef7ced
lightsail: terrafmt tests
brittandeyoung Oct 19, 2022
b5635b8
lightsail: Amend lb_attachement_test testdestroy
brittandeyoung Oct 19, 2022
13c380a
changelog: add 27339 changelog
brittandeyoung Oct 19, 2022
f5e8a55
lightsail: Amend lb_test and lb_attachment_test
brittandeyoung Oct 19, 2022
5e79a0b
lightsail: Amend lb and lb_attachment
brittandeyoung Oct 20, 2022
e9b5e1a
docs: lightsail lb and lb_attachment lint fix
brittandeyoung Oct 20, 2022
d59ab53
lightsail: Amend lb and lb_attachment golangci-lint
brittandeyoung Oct 20, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changelog/27339.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
```release-note:new-resource
aws_lightsail_lb
```

```release-note:new-resource
aws_lightsail_lb_attachment
```
2 changes: 2 additions & 0 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -1715,6 +1715,8 @@ func New(_ context.Context) (*schema.Provider, error) {
"aws_lightsail_instance": lightsail.ResourceInstance(),
"aws_lightsail_instance_public_ports": lightsail.ResourceInstancePublicPorts(),
"aws_lightsail_key_pair": lightsail.ResourceKeyPair(),
"aws_lightsail_lb": lightsail.ResourceLoadBalancer(),
"aws_lightsail_lb_attachment": lightsail.ResourceLoadBalancerAttachment(),
"aws_lightsail_static_ip": lightsail.ResourceStaticIP(),
"aws_lightsail_static_ip_attachment": lightsail.ResourceStaticIPAttachment(),

Expand Down
10 changes: 6 additions & 4 deletions internal/service/lightsail/consts.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package lightsail

const (
ResCertificate = "Certificate"
ResDatabase = "Database"
ResTags = "Tags"
ResDomainEntry = "Domain Entry"
ResCertificate = "Certificate"
ResDatabase = "Database"
ResTags = "Tags"
ResDomainEntry = "Domain Entry"
ResLoadBalancer = "Load Balancer"
ResLoadBalancerAttachment = "Load Balancer Attachment"
)
66 changes: 66 additions & 0 deletions internal/service/lightsail/find.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package lightsail

import (
"context"
"errors"
"strings"

"github.com/aws/aws-sdk-go/aws"
Expand Down Expand Up @@ -155,3 +156,68 @@ func FindDomainEntryById(ctx context.Context, conn *lightsail.Lightsail, id stri

return entry, nil
}

func FindLoadBalancerByName(ctx context.Context, conn *lightsail.Lightsail, name string) (*lightsail.LoadBalancer, error) {
in := &lightsail.GetLoadBalancerInput{LoadBalancerName: aws.String(name)}
out, err := conn.GetLoadBalancerWithContext(ctx, in)

if tfawserr.ErrCodeEquals(err, lightsail.ErrCodeNotFoundException) {
return nil, &resource.NotFoundError{
LastError: err,
LastRequest: in,
}
}

if err != nil {
return nil, err
}

if out == nil || out.LoadBalancer == nil {
return nil, tfresource.NewEmptyResultError(in)
}

lb := out.LoadBalancer

return lb, nil
}

func FindLoadBalancerAttachmentById(ctx context.Context, conn *lightsail.Lightsail, id string) (*string, error) {
id_parts := strings.SplitN(id, ",", -1)
if len(id_parts) != 2 {
return nil, errors.New("invalid load balancer attachment id")
}

lbName := id_parts[0]
iName := id_parts[1]

in := &lightsail.GetLoadBalancerInput{LoadBalancerName: aws.String(lbName)}
out, err := conn.GetLoadBalancerWithContext(ctx, in)

if tfawserr.ErrCodeEquals(err, lightsail.ErrCodeNotFoundException) {
return nil, &resource.NotFoundError{
LastError: err,
LastRequest: in,
}
}

if err != nil {
return nil, err
}

var entry *string
entryExists := false

for _, n := range out.LoadBalancer.InstanceHealthSummary {
if iName == aws.StringValue(n.InstanceName) {
entry = n.InstanceName
entryExists = true
break
}
}

if !entryExists {
return nil, tfresource.NewEmptyResultError(in)
}

return entry, nil
}
246 changes: 246 additions & 0 deletions internal/service/lightsail/lb.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,246 @@
package lightsail

import (
"context"
"errors"
"regexp"
"time"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/lightsail"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
"github.com/hashicorp/terraform-provider-aws/internal/conns"
"github.com/hashicorp/terraform-provider-aws/internal/create"
tftags "github.com/hashicorp/terraform-provider-aws/internal/tags"
"github.com/hashicorp/terraform-provider-aws/internal/tfresource"
"github.com/hashicorp/terraform-provider-aws/internal/verify"
"github.com/hashicorp/terraform-provider-aws/names"
)

func ResourceLoadBalancer() *schema.Resource {
return &schema.Resource{
CreateWithoutTimeout: resourceLoadBalancerCreate,
ReadWithoutTimeout: resourceLoadBalancerRead,
UpdateWithoutTimeout: resourceLoadBalancerUpdate,
DeleteWithoutTimeout: resourceLoadBalancerDelete,

Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
},

Schema: map[string]*schema.Schema{
"arn": {
Type: schema.TypeString,
Computed: true,
},
"created_at": {
Type: schema.TypeString,
Computed: true,
},
"dns_name": {
Type: schema.TypeString,
Computed: true,
},
"health_check_path": {
Type: schema.TypeString,
Optional: true,
Default: "/",
},
"instance_port": {
Type: schema.TypeInt,
Required: true,
ForceNew: true,
ValidateFunc: validation.IntBetween(0, 65535),
},
"ip_address_type": {
Type: schema.TypeString,
Optional: true,
Default: "dualstack",
ValidateFunc: validation.StringInSlice([]string{
"dualstack",
"ipv4",
}, false),
},
"protocol": {
Type: schema.TypeString,
Computed: true,
},
"public_ports": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeInt},
},
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.All(
validation.StringLenBetween(2, 255),
validation.StringMatch(regexp.MustCompile(`^[a-zA-Z]`), "must begin with an alphabetic character"),
validation.StringMatch(regexp.MustCompile(`^[a-zA-Z0-9_\-.]+[^._\-]$`), "must contain only alphanumeric characters, underscores, hyphens, and dots"),
),
},
"support_code": {
Type: schema.TypeString,
Computed: true,
},
"tags": tftags.TagsSchema(),
"tags_all": tftags.TagsSchemaComputed(),
},
CustomizeDiff: verify.SetTagsDiff,
}
}

func resourceLoadBalancerCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
conn := meta.(*conns.AWSClient).LightsailConn
defaultTagsConfig := meta.(*conns.AWSClient).DefaultTagsConfig
tags := defaultTagsConfig.MergeTags(tftags.New(d.Get("tags").(map[string]interface{})))

in := lightsail.CreateLoadBalancerInput{
HealthCheckPath: aws.String(d.Get("health_check_path").(string)),
InstancePort: aws.Int64(int64(d.Get("instance_port").(int))),
LoadBalancerName: aws.String(d.Get("name").(string)),
}

if len(tags) > 0 {
in.Tags = Tags(tags.IgnoreAWS())
}

out, err := conn.CreateLoadBalancerWithContext(ctx, &in)

if err != nil {
return create.DiagError(names.Lightsail, lightsail.OperationTypeCreateLoadBalancer, ResLoadBalancer, d.Get("name").(string), err)
}

if len(out.Operations) == 0 {
return create.DiagError(names.Lightsail, lightsail.OperationTypeCreateLoadBalancer, ResLoadBalancer, d.Get("name").(string), errors.New("No operations found for Create Load Balancer request"))
}

op := out.Operations[0]
d.SetId(d.Get("name").(string))

err = waitOperation(conn, op.Id)
if err != nil {
return create.DiagError(names.Lightsail, lightsail.OperationTypeCreateLoadBalancer, ResLoadBalancer, d.Get("name").(string), errors.New("Error waiting for Create Load Balancer request operation"))
}

return resourceLoadBalancerRead(ctx, d, meta)
}

func resourceLoadBalancerRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
conn := meta.(*conns.AWSClient).LightsailConn
defaultTagsConfig := meta.(*conns.AWSClient).DefaultTagsConfig
ignoreTagsConfig := meta.(*conns.AWSClient).IgnoreTagsConfig

lb, err := FindLoadBalancerByName(ctx, conn, d.Id())

if !d.IsNewResource() && tfresource.NotFound(err) {
create.LogNotFoundRemoveState(names.Lightsail, create.ErrActionReading, ResLoadBalancer, d.Id())
d.SetId("")
return nil
}

if err != nil {
return create.DiagError(names.Lightsail, create.ErrActionReading, ResLoadBalancer, d.Id(), err)
}

d.Set("arn", lb.Arn)
d.Set("created_at", lb.CreatedAt.Format(time.RFC3339))
d.Set("dns_name", lb.DnsName)
d.Set("health_check_path", lb.HealthCheckPath)
d.Set("instance_port", lb.InstancePort)
d.Set("ip_address_type", lb.IpAddressType)
d.Set("protocol", lb.Protocol)
d.Set("public_ports", lb.PublicPorts)
d.Set("name", lb.Name)
d.Set("support_code", lb.SupportCode)

tags := KeyValueTags(lb.Tags).IgnoreAWS().IgnoreConfig(ignoreTagsConfig)

//lintignore:AWSR002
if err := d.Set("tags", tags.RemoveDefaultConfig(defaultTagsConfig).Map()); err != nil {
return create.DiagError(names.Lightsail, create.ErrActionReading, ResLoadBalancer, d.Id(), err)
}

if err := d.Set("tags_all", tags.Map()); err != nil {
return create.DiagError(names.Lightsail, create.ErrActionReading, ResLoadBalancer, d.Id(), err)
}

return nil
}

func resourceLoadBalancerUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
conn := meta.(*conns.AWSClient).LightsailConn

in := &lightsail.UpdateLoadBalancerAttributeInput{
LoadBalancerName: aws.String(d.Get("name").(string)),
}

if d.HasChange("health_check_path") {
healthCheckIn := in
healthCheckIn.AttributeName = aws.String("HealthCheckPath")
healthCheckIn.AttributeValue = aws.String(d.Get("health_check_path").(string))

out, err := conn.UpdateLoadBalancerAttributeWithContext(ctx, healthCheckIn)

if err != nil {
return create.DiagError(names.Lightsail, lightsail.OperationTypeCreateLoadBalancer, ResLoadBalancer, d.Get("name").(string), err)
}

if len(out.Operations) == 0 {
return create.DiagError(names.Lightsail, lightsail.OperationTypeCreateLoadBalancer, ResLoadBalancer, d.Get("name").(string), errors.New("No operations found for Create Load Balancer request"))
}

op := out.Operations[0]

err = waitOperation(conn, op.Id)
if err != nil {
return create.DiagError(names.Lightsail, lightsail.OperationTypeCreateLoadBalancer, ResLoadBalancer, d.Get("name").(string), errors.New("Error waiting for Create Load Balancer request operation"))
}
}

if d.HasChange("tags") {
o, n := d.GetChange("tags")

if err := UpdateTags(conn, d.Id(), o, n); err != nil {
return create.DiagError(names.Lightsail, create.ErrActionUpdating, ResLoadBalancer, d.Id(), err)
}
}

if d.HasChange("tags_all") {
o, n := d.GetChange("tags_all")

if err := UpdateTags(conn, d.Id(), o, n); err != nil {
return create.DiagError(names.Lightsail, create.ErrActionUpdating, ResLoadBalancer, d.Id(), err)
}
}

return resourceLoadBalancerRead(ctx, d, meta)
}

func resourceLoadBalancerDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
conn := meta.(*conns.AWSClient).LightsailConn

out, err := conn.DeleteLoadBalancerWithContext(ctx, &lightsail.DeleteLoadBalancerInput{
LoadBalancerName: aws.String(d.Id()),
})

if err != nil {
return create.DiagError(names.Lightsail, lightsail.OperationTypeCreateLoadBalancer, ResLoadBalancer, d.Get("name").(string), err)
}

if len(out.Operations) == 0 {
return create.DiagError(names.Lightsail, lightsail.OperationTypeCreateLoadBalancer, ResLoadBalancer, d.Get("name").(string), errors.New("No operations found for Create Load Balancer request"))
}

op := out.Operations[0]

err = waitOperation(conn, op.Id)
if err != nil {
return create.DiagError(names.Lightsail, lightsail.OperationTypeCreateLoadBalancer, ResLoadBalancer, d.Get("name").(string), errors.New("Error waiting for Create Load Balancer request operation"))
}

return nil
}
Loading