Last active
April 23, 2024 23:54
-
-
Save niski84/cd68872554c091671b7b53b2f1a2ce06 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"log" | |
"github.com/aws/aws-sdk-go/aws/session" | |
"github.com/aws/aws-sdk-go/service/elasticbeanstalk" | |
"github.com/aws/aws-sdk-go/service/elbv2" | |
) | |
func main() { | |
sess := session.Must(session.NewSessionWithOptions(session.Options{ | |
SharedConfigState: session.SharedConfigEnable, | |
})) | |
envName := "my-elasticbeanstalk-env" | |
// Get Load Balancer Name | |
lbName, err := GetLoadBalancerName(sess, envName) | |
if err != nil { | |
log.Fatalf("Error fetching load balancer name: %v", err) | |
} | |
// Get ALB Details | |
ruleArn, targetGroupArn, err := GetALBDetails(sess, lbName) | |
if err != nil { | |
log.Fatalf("Error fetching ALB details: %v", err) | |
} | |
fmt.Printf("Rule ARN: %s\n", ruleArn) | |
fmt.Printf("Target Group ARN: %s\n", targetGroupArn) | |
// Redirect traffic to ipchicken.com during maintenance | |
redirectURL := "ipchicken.com" | |
if err := RedirectTraffic(sess, ruleArn, redirectURL); err != nil { | |
log.Fatalf("Error redirecting traffic: %v", err) | |
} | |
fmt.Println("Traffic is now redirected to:", redirectURL) | |
// Include logic or monitoring to determine when to switch back | |
// Restore original routing | |
if err := RestoreOriginalTraffic(sess, ruleArn, targetGroupArn); err != nil { | |
log.Fatalf("Error restoring original traffic: %v", err) | |
} | |
fmt.Println("Traffic is now restored to the original site") | |
} | |
// GetLoadBalancerName retrieves the name of the Load Balancer associated with a given Elastic Beanstalk environment. | |
func GetLoadBalancerName(sess *session.Session, envName string) (string, error) { | |
ebSvc := elasticbeanstalk.New(sess) | |
input := &elasticbeanstalk.DescribeEnvironmentResourcesInput{ | |
EnvironmentName: aws.String(envName), | |
} | |
resp, err := ebSvc.DescribeEnvironmentResources(input) | |
if err != nil { | |
return "", err | |
} | |
if len(resp.EnvironmentResources.LoadBalancers) == 0 { | |
return "", fmt.Errorf("no load balancer found for environment %s", envName) | |
} | |
return *resp.EnvironmentResources.LoadBalancers[0].Name, nil | |
} | |
// GetALBDetails retrieves the rule ARN and target group ARN for the given load balancer name. | |
func GetALBDetails(sess *session.Session, lbName string) (string, string, error) { | |
elbSvc := elbv2.New(sess) | |
// Retrieve load balancer details using its name | |
lbInput := &elbv2.DescribeLoadBalancersInput{ | |
Names: []*string{aws.String(lbName)}, | |
} | |
lbOutput, err := elbSvc.DescribeLoadBalancers(lbInput) | |
if err != nil { | |
return "", "", err | |
} | |
if len(lbOutput.LoadBalancers) == 0 { | |
return "", "", fmt.Errorf("load balancer %s not found", lbName) | |
} | |
lbArn := lbOutput.LoadBalancers[0].LoadBalancerArn | |
// Retrieve the listener using the Load Balancer ARN | |
listenerInput := &elbv2.DescribeListenersInput{ | |
LoadBalancerArn: lbArn, | |
} | |
listenerOutput, err := elbSvc.DescribeListeners(listenerInput) | |
if err != nil { | |
return "", "", err | |
} | |
if len(listenerOutput.Listeners) == 0 { | |
return "", "", fmt.Errorf("no listeners found for load balancer %s", lbName) | |
} | |
// Assuming the first listener and the first rule | |
// For more complex setups, you might need to iterate or filter based on specific conditions | |
listenerArn := listenerOutput.Listeners[0].ListenerArn | |
ruleInput := &elbv2.DescribeRulesInput{ | |
ListenerArn: listenerArn, | |
} | |
ruleOutput, err := elbSvc.DescribeRules(ruleInput) | |
if err != nil { | |
return "", "", err | |
} | |
if len(ruleOutput.Rules) == 0 { | |
return "", "", fmt.Errorf("no rules found for listener %s", *listenerArn) | |
} | |
ruleArn := *ruleOutput.Rules[0].RuleArn | |
var targetGroupArn string | |
for _, action := range ruleOutput.Rules[0].Actions { | |
if *action.Type == "forward" { | |
targetGroupArn = *action.TargetGroupArn | |
break | |
} | |
} | |
if targetGroupArn == "" { | |
return "", "", fmt.Errorf("no forwarding actions found in rules for listener %s", *listenerArn) | |
} | |
return ruleArn, targetGroupArn, nil | |
} | |
// RedirectTraffic sets up an ALB rule to redirect all traffic to a specified URL. | |
func RedirectTraffic(sess *session.Session, ruleArn string, redirectURL string) error { | |
svc := elbv2.New(sess) | |
modifyRuleInput := &elbv2.ModifyRuleInput{ | |
RuleArn: aws.String(ruleArn), | |
Actions: []*elbv2.Action{ | |
{ | |
Type: aws.String("redirect"), | |
RedirectConfig: &elbv2.RedirectActionConfig{ | |
Protocol: aws.String("HTTPS"), // Ensure the protocol matches your requirements | |
Host: aws.String(redirectURL), // No need to specify the entire URL, just the host | |
Port: aws.String("443"), // Standard HTTPS port | |
Path: aws.String("/#{path}"), | |
Query: aws.String("#{query}"), | |
StatusCode: aws.String("HTTP_302"), | |
}, | |
}, | |
}, | |
} | |
_, err := svc.ModifyRule(modifyRuleInput) | |
return err | |
} | |
// RestoreOriginalTraffic restores the original rule to forward traffic to the primary target group. | |
func RestoreOriginalTraffic(sess *session.Session, ruleArn string, targetGroupArn string) error { | |
svc := elbv2.New(sess) | |
modifyRuleInput := &elbv2.ModifyRuleInput{ | |
RuleArn: aws.String(ruleArn), | |
Actions: []*elbv2.Action{ | |
{ | |
Type: aws.String("forward"), | |
TargetGroupArn: aws.String(targetGroupArn), | |
}, | |
}, | |
} | |
_, err := svc.ModifyRule(modifyRuleInput) | |
return err | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment