-
Notifications
You must be signed in to change notification settings - Fork 505
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added step templates to support AMI Blue/Green deployments (#1581)
* Added step templates to support AMI Blue/Green deployments * Added parameter help text * Added another step * Deal with a null value * Show status in logs
- Loading branch information
1 parent
a3102d5
commit 93e93bc
Showing
5 changed files
with
392 additions
and
0 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
{ | ||
"Id": "6b72995e-500c-4b4b-9121-88f3a988ec71", | ||
"Name": "AWS - Find Blue-Green ASG", | ||
"Description": "Return the name of the online and offline blue and green Auto Scaling Groups", | ||
"ActionType": "Octopus.AwsRunScript", | ||
"Version": 1, | ||
"CommunityActionTemplateId": null, | ||
"Packages": [], | ||
"GitDependencies": [], | ||
"Properties": { | ||
"OctopusUseBundledTooling": "False", | ||
"Octopus.Action.Script.ScriptSource": "Inline", | ||
"Octopus.Action.Script.Syntax": "Bash", | ||
"Octopus.Action.Aws.AssumeRole": "False", | ||
"Octopus.Action.AwsAccount.UseInstanceRole": "False", | ||
"Octopus.Action.AwsAccount.Variable": "#{AWSBlueGreen.AWS.Account}", | ||
"Octopus.Action.Script.ScriptBody": "#!/bin/bash\n\nINACTIVECOLOR=${1:-'#{AWSBlueGreen.InactiveColor | Trim}'}\nGREENASG=${2:-'#{AWSBlueGreen.AWS.GreenASG | Trim}'}\nBLUEASG=${3:-'#{AWSBlueGreen.AWS.BlueASG | Trim}'}\n\nechoerror() { echo \"$@\" 1>&2; }\n\nif [[ -z \"${INACTIVECOLOR}\" ]]\nthen\n echoerror \"Please provide the color of the inactive Auto Scaling group (Green or Blue) as the first argument\"\n exit 1\nfi\n\nif [[ -z \"${GREENASG}\" ]]\nthen\n echoerror \"Please provide the name of the Green Auto Scaling group as the second argument\"\n exit 1\nfi\n\nif [[ -z \"${BLUEASG}\" ]]\nthen\n echoerror \"Please provide the name of the Blue Auto Scaling group as the third argument\"\n exit 1\nfi\n\nif [[ \"${INACTIVECOLOR^^}\" == \"GREEN\" ]]\nthen\n set_octopusvariable \"ActiveGroup\" \"${BLUEASG}\"\n set_octopusvariable \"InactiveGroup\" \"${GREENASG}\"\n echo \"Active group is Blue (${BLUEASG}), inactive group is Green (${GREENASG})\"\nelse\n set_octopusvariable \"ActiveGroup\" \"${GREENASG}\"\n set_octopusvariable \"InactiveGroup\" \"${BLUEASG}\"\n echo \"Active group is Green (${GREENASG}), inactive group is Blue (${BLUEASG})\"\nfi", | ||
"Octopus.Action.Aws.Region": "#{AWSBlueGreen.AWS.Region}" | ||
}, | ||
"Parameters": [ | ||
{ | ||
"Id": "f8522014-f1ba-4e4a-a06d-59ebdba6f276", | ||
"Name": "AWSBlueGreen.InactiveColor", | ||
"Label": "Inactive Color", | ||
"HelpText": "The color of the inactive group (Green or Blue). This value is usually found from the \"AWS - Find Blue-Green Target Group\" step.", | ||
"DefaultValue": "", | ||
"DisplaySettings": { | ||
"Octopus.ControlType": "SingleLineText" | ||
} | ||
}, | ||
{ | ||
"Id": "8753e6ed-0ae6-4a4c-ae5b-155139037633", | ||
"Name": "AWSBlueGreen.AWS.GreenASG", | ||
"Label": "Green ASG Name", | ||
"HelpText": "The name of the green auto scaler group. See https://docs.aws.amazon.com/autoscaling/ec2/userguide/auto-scaling-groups.html for more details.", | ||
"DefaultValue": "", | ||
"DisplaySettings": { | ||
"Octopus.ControlType": "SingleLineText" | ||
} | ||
}, | ||
{ | ||
"Id": "bf9187f5-62e9-4ad9-b53f-459466b84994", | ||
"Name": "AWSBlueGreen.AWS.BlueASG", | ||
"Label": "Blue ASG Name", | ||
"HelpText": "The name of the blue auto scaler group. See https://docs.aws.amazon.com/autoscaling/ec2/userguide/auto-scaling-groups.html for more details.", | ||
"DefaultValue": "", | ||
"DisplaySettings": { | ||
"Octopus.ControlType": "SingleLineText" | ||
} | ||
}, | ||
{ | ||
"Id": "eb02bbf2-e05a-4469-9359-c77d77d87dd2", | ||
"Name": "AWSBlueGreen.AWS.Region", | ||
"Label": "Region", | ||
"HelpText": "The AWS region. See https://aws.amazon.com/about-aws/global-infrastructure/regions_az/ for more information.", | ||
"DefaultValue": "", | ||
"DisplaySettings": { | ||
"Octopus.ControlType": "SingleLineText" | ||
} | ||
}, | ||
{ | ||
"Id": "99a74afc-ee67-4295-8281-3bb1c6e83d06", | ||
"Name": "AWSBlueGreen.AWS.Account", | ||
"Label": "Account", | ||
"HelpText": null, | ||
"DefaultValue": "", | ||
"DisplaySettings": { | ||
"Octopus.ControlType": "AmazonWebServicesAccount" | ||
} | ||
} | ||
], | ||
"StepPackageId": "Octopus.AwsRunScript", | ||
"$Meta": { | ||
"ExportedAt": "2025-01-10T03:42:14.665Z", | ||
"OctopusVersion": "2025.1.5319", | ||
"Type": "ActionTemplate" | ||
}, | ||
"LastModifiedBy": "mcasperson", | ||
"Category": "aws" | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
{ | ||
"Id": "2f5f8b7b-5deb-45a9-966b-bf52c6e7976c", | ||
"Name": "AWS - Find Blue-Green Target Group", | ||
"Description": "Find the online and offline target groups for a blue-green deployment", | ||
"ActionType": "Octopus.AwsRunScript", | ||
"Version": 1, | ||
"CommunityActionTemplateId": null, | ||
"Packages": [], | ||
"GitDependencies": [], | ||
"Properties": { | ||
"OctopusUseBundledTooling": "False", | ||
"Octopus.Action.Script.ScriptSource": "Inline", | ||
"Octopus.Action.Script.Syntax": "Bash", | ||
"Octopus.Action.Aws.AssumeRole": "False", | ||
"Octopus.Action.AwsAccount.UseInstanceRole": "False", | ||
"Octopus.Action.AwsAccount.Variable": "#{AWSBlueGreen.AWS.Account}", | ||
"Octopus.Action.Aws.Region": "#{AWSBlueGreen.AWS.Region}", | ||
"Octopus.Action.Script.ScriptBody": "#!/bin/bash\n\nLISTENER=${1:-'#{AWSBlueGreen.AWS.ListenerARN | Trim}'}\nRULE=${2:-'#{AWSBlueGreen.AWS.RuleArn | Trim}'}\nGREENTARGETGROUP=${3:-'#{AWSBlueGreen.AWS.GreenTargetGroup | Trim}'}\nBLUETARGETGROUP=${4:-'#{AWSBlueGreen.AWS.BlueTargetGroup | Trim}'}\n\nechoerror() { echo \"$@\" 1>&2; }\n\nif ! command -v \"aws\" &> /dev/null; then\n echoerror \"You must have the AWS CLI installed for this step. Consider using a Container Image - https://octopus.com/docs/projects/steps/execution-containers-for-workers#how-to-use-execution-containers-for-workers\"\n exit 1\nfi\n\nif ! command -v \"jq\" &> /dev/null; then\n echoerror \"You must have jq installed for this step. Consider using a Container Image - https://octopus.com/docs/projects/steps/execution-containers-for-workers#how-to-use-execution-containers-for-workers\"\n exit 1\nfi\n\n# Validate the arguments\n\nif [[ -z \"${LISTENER}\" ]]; then\n echoerror \"Please provide the ARN of the listener as the first argument\"\n exit 1\nfi\n\nif [[ -z \"${RULE}\" ]]; then\n echoerror \"Please provide the ARN of the listener rule as the second argument\"\n exit 1\nfi\n\nif [[ -z \"${GREENTARGETGROUP}\" ]]; then\n echoerror \"Please provide the ARN of the green target group as the third argument\"\n exit 1\nfi\n\nif [[ -z \"${BLUETARGETGROUP}\" ]]; then\n echoerror \"Please provide the ARN of the blue target group as the fourth argument\"\n exit 1\nfi\n\n# Get the JSON representation of the listener rules\n\nRULES=$(aws elbv2 describe-rules \\\n --listener-arn \"${LISTENER}\" \\\n --output json)\n\nwrite_verbose \"${RULES}\"\n\n# Find the weight assigned to each of the target groups.\n\nGREENWEIGHT=$(jq -r \".Rules[] | select(.RuleArn == \\\"${RULE}\\\") | .Actions[] | select(.Type == \\\"forward\\\") | .ForwardConfig | .TargetGroups[] | select(.TargetGroupArn == \\\"${GREENTARGETGROUP}\\\") | .Weight\" <<< \"${RULES}\")\nBLUEWEIGHT=$(jq -r \".Rules[] | select(.RuleArn == \\\"${RULE}\\\") | .Actions[] | select(.Type == \\\"forward\\\") | .ForwardConfig | .TargetGroups[] | select(.TargetGroupArn == \\\"${BLUETARGETGROUP}\\\") | .Weight\" <<< \"${RULES}\")\n\n# Validation that we found the green and blue target groups.\n\nif [[ -z \"${GREENWEIGHT}\" ]]; then\n echoerror \"Failed to find the target group ${GREENTARGETGROUP} in the listener rule ${RULE}\"\n echoerror \"Double check that the target group exists and has been associated with the load balancer\"\n exit 1\nfi\n\nif [[ -z \"${BLUEWEIGHT}\" ]]; then\n echoerror \"Failed to find the target group ${BLUETARGETGROUP} in the listener rule ${RULE}\"\n echoerror \"Double check that the target group exists and has been associated with the load balancer\"\n exit 1\nfi\n\necho \"Green weight: ${GREENWEIGHT}\"\necho \"Blue weight: ${BLUEWEIGHT}\"\n\n# Set the output variables identifying which target group is active and which is inactive.\n# Note that we assume the target groups are either active or inactive (i.e. all traffic and no traffic).\n# Load balancers support more complex routing rules, but we assume a simple blue-green deployment.\n# If the green target group has traffic, it is considered active, and the blue target group is considered inactive.\n# If the green target group has no traffic, it is considered inactive, and the blue target group is considered active.\n\nif [ \"${GREENWEIGHT}\" != \"0\" ]; then\n echo \"Green target group is active, blue target group is inactive\"\n set_octopusvariable \"ActiveGroupArn\" \"${GREENTARGETGROUP}\"\n set_octopusvariable \"ActiveGroupColor\" \"Green\"\n set_octopusvariable \"InactiveGroupArn\" \"${BLUETARGETGROUP}\"\n set_octopusvariable \"InactiveGroupColor\" \"Blue\"\nelse\n echo \"Blue target group is active, green target group is inactive\"\n set_octopusvariable \"ActiveGroupArn\" \"${BLUETARGETGROUP}\"\n set_octopusvariable \"ActiveGroupColor\" \"Blue\"\n set_octopusvariable \"InactiveGroupArn\" \"${GREENTARGETGROUP}\"\n set_octopusvariable \"InactiveGroupColor\" \"Green\"\nfi" | ||
}, | ||
"Parameters": [ | ||
{ | ||
"Id": "29cdfb7d-47fa-4c8a-837b-c58bb0d90c26", | ||
"Name": "AWSBlueGreen.AWS.Region", | ||
"Label": "Region", | ||
"HelpText": "The AWS region. See https://aws.amazon.com/about-aws/global-infrastructure/regions_az/ for more information.", | ||
"DefaultValue": "", | ||
"DisplaySettings": { | ||
"Octopus.ControlType": "SingleLineText" | ||
} | ||
}, | ||
{ | ||
"Id": "58a1ebcd-fd13-48e2-b8b9-fdfe4df8c35e", | ||
"Name": "AWSBlueGreen.AWS.Account", | ||
"Label": "Account", | ||
"HelpText": null, | ||
"DefaultValue": "", | ||
"DisplaySettings": { | ||
"Octopus.ControlType": "AmazonWebServicesAccount" | ||
} | ||
}, | ||
{ | ||
"Id": "80642a7b-ef3e-4db4-b969-d0148a1baa90", | ||
"Name": "AWSBlueGreen.AWS.ListenerARN", | ||
"Label": "Listener ARN", | ||
"HelpText": null, | ||
"DefaultValue": "", | ||
"DisplaySettings": { | ||
"Octopus.ControlType": "SingleLineText" | ||
} | ||
}, | ||
{ | ||
"Id": "2cf29ab4-61a1-4a80-942f-6f1dd035f634", | ||
"Name": "AWSBlueGreen.AWS.BlueTargetGroup", | ||
"Label": "Blue Target Group ARN", | ||
"HelpText": "The ARN of the blue target group. See https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-target-groups.html for more details.", | ||
"DefaultValue": "", | ||
"DisplaySettings": { | ||
"Octopus.ControlType": "SingleLineText" | ||
} | ||
}, | ||
{ | ||
"Id": "b7d105c6-1640-48c4-9f01-ad9ece8d3588", | ||
"Name": "AWSBlueGreen.AWS.GreenTargetGroup", | ||
"Label": "Green Target Group ARN", | ||
"HelpText": "The ARN of the green target group. See https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-target-groups.html for more details.", | ||
"DefaultValue": "", | ||
"DisplaySettings": { | ||
"Octopus.ControlType": "SingleLineText" | ||
} | ||
}, | ||
{ | ||
"Id": "ff055e9f-f223-453a-9a1f-a0238e6cdfd6", | ||
"Name": "AWSBlueGreen.AWS.RuleArn", | ||
"Label": "Rule ARN", | ||
"HelpText": "The ARN of the listener rule to update. See https://docs.aws.amazon.com/elasticloadbalancing/latest/application/listener-update-rules.html for more information.", | ||
"DefaultValue": "", | ||
"DisplaySettings": { | ||
"Octopus.ControlType": "SingleLineText" | ||
} | ||
} | ||
], | ||
"StepPackageId": "Octopus.AwsRunScript", | ||
"$Meta": { | ||
"ExportedAt": "2025-01-10T03:41:11.780Z", | ||
"OctopusVersion": "2025.1.5319", | ||
"Type": "ActionTemplate" | ||
}, | ||
"LastModifiedBy": "mcasperson", | ||
"Category": "aws" | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
{ | ||
"Id": "150c46d1-f33f-493b-a8c6-f5bd22f540f3", | ||
"Name": "AWS - Initiate Instance Refresh", | ||
"Description": "Initiates an instance refresh for an Auto Scaling group and waits for it to complete.", | ||
"ActionType": "Octopus.AwsRunScript", | ||
"Version": 1, | ||
"CommunityActionTemplateId": null, | ||
"Packages": [], | ||
"GitDependencies": [], | ||
"Properties": { | ||
"OctopusUseBundledTooling": "False", | ||
"Octopus.Action.Script.ScriptSource": "Inline", | ||
"Octopus.Action.Script.Syntax": "Bash", | ||
"Octopus.Action.Aws.AssumeRole": "False", | ||
"Octopus.Action.AwsAccount.UseInstanceRole": "False", | ||
"Octopus.Action.RunOnServer": "true", | ||
"Octopus.Action.AwsAccount.Variable": "#{AWSBlueGreen.AWS.Account}", | ||
"Octopus.Action.Aws.Region": "#{AWSBlueGreen.AWS.Region}", | ||
"Octopus.Action.Script.ScriptBody": "#!/bin/bash\n\nASG=${1:-'#{AWSBlueGreen.AWS.ASG | Trim}'}\n\nechoerror() { echo \"$@\" 1>&2; }\n\nif ! command -v \"aws\" &> /dev/null; then\n echoerror \"You must have the AWS CLI installed for this step. Consider using a Container Image - https://octopus.com/docs/projects/steps/execution-containers-for-workers#how-to-use-execution-containers-for-workers\"\n exit 1\nfi\n\nif ! command -v \"jq\" &> /dev/null; then\n echoerror \"You must have jq installed for this step. Consider using a Container Image - https://octopus.com/docs/projects/steps/execution-containers-for-workers#how-to-use-execution-containers-for-workers\"\n exit 1\nfi\n\nif [[ -z \"${ASG}\" ]]; then\n echoerror \"Please provide the name of the Auto Scaling group as the first argument\"\n exit 1\nfi\n\nfor i in {1..30}; do\n EXISTINGREFRESHES=$(aws autoscaling describe-instance-refreshes --auto-scaling-group-name \"${ASG}\")\n NOTSUCCESSFUL=$(jq '.InstanceRefreshes[] | select(.Status == \"Pending\" or .Status == \"InProgress\" or .Status == \"Cancelling\" or .Status == \"RollbackInProgress\" or .Status == \"Baking\")' <<< \"${EXISTINGREFRESHES}\")\n if [[ -z \"${NOTSUCCESSFUL}\" ]];\n then\n break\n fi\n echo \"Waiting for existing Auto Scaling group ${ASG} refresh to complete...\"\n sleep 12\ndone\n\nREFRESH=$(aws autoscaling start-instance-refresh --auto-scaling-group-name \"${ASG}\")\n\nif [[ $? -ne 0 ]];\nthen\n echoerror \"Failed to start instance refresh for Auto Scaling group ${ASG}\"\n exit 1\nfi\n\nREFRESHTOKEN=$(jq -r '.InstanceRefreshId' <<< \"${REFRESH}\")\n\necho \"Refreshing instances in Auto Scaling group ${ASG}...\"\n\nwrite_verbose \"${REFRESH}\"\n\n# Wait for all instances to be healthy\nfor i in {1..30}; do\n REFRESHSTATUS=$(aws autoscaling describe-instance-refreshes --auto-scaling-group-name \"${ASG}\" --instance-refresh-ids \"${REFRESHTOKEN}\")\n STATUS=$(jq -r '.InstanceRefreshes[0].Status' <<< \"${REFRESHSTATUS}\")\n PERCENTCOMPLETE=$(jq -r '.InstanceRefreshes[0].PercentageComplete' <<< \"${REFRESHSTATUS}\")\n\n # Treat a null percentage as 0\n if [[ \"${PERCENTCOMPLETE}\" == \"null\" ]]\n then\n PERCENTCOMPLETE=0\n fi\n\n write_verbose \"${REFRESHSTATUS}\"\n\n if [[ \"${STATUS}\" == \"Successful\" ]]\n then\n echo \"Instance refresh succeeded\"\n break\n elif [[ \"${STATUS}\" == \"Failed\" ]];\n then\n echo \"Instance refresh failed!\"\n exit 1\n fi\n echo \"Waiting for Auto Scaling group ${ASG} refresh to complete (${STATUS} ${PERCENTCOMPLETE}%)...\"\n sleep 12\ndone" | ||
}, | ||
"Parameters": [ | ||
{ | ||
"Id": "2fe001f5-39ee-40d9-b104-24817759ac6f", | ||
"Name": "AWSBlueGreen.AWS.Region", | ||
"Label": "AWS Region", | ||
"HelpText": "The AWS region. See https://aws.amazon.com/about-aws/global-infrastructure/regions_az/ for more information.", | ||
"DefaultValue": "", | ||
"DisplaySettings": { | ||
"Octopus.ControlType": "SingleLineText" | ||
} | ||
}, | ||
{ | ||
"Id": "f3630bb5-ab07-46b4-b764-19f1c3b2ec5f", | ||
"Name": "AWSBlueGreen.AWS.Account", | ||
"Label": "Account", | ||
"HelpText": null, | ||
"DefaultValue": "", | ||
"DisplaySettings": { | ||
"Octopus.ControlType": "AmazonWebServicesAccount" | ||
} | ||
}, | ||
{ | ||
"Id": "bdfdedee-fdeb-4292-96fd-e41c64b1e523", | ||
"Name": "AWSBlueGreen.AWS.ASG", | ||
"Label": "ASG Name", | ||
"HelpText": "The name of the auto scaler group to refresh. See https://docs.aws.amazon.com/autoscaling/ec2/userguide/auto-scaling-groups.html for more details.", | ||
"DefaultValue": "", | ||
"DisplaySettings": { | ||
"Octopus.ControlType": "SingleLineText" | ||
} | ||
} | ||
], | ||
"StepPackageId": "Octopus.AwsRunScript", | ||
"$Meta": { | ||
"ExportedAt": "2025-01-10T04:12:22.681Z", | ||
"OctopusVersion": "2025.1.5319", | ||
"Type": "ActionTemplate" | ||
}, | ||
"LastModifiedBy": "mcasperson", | ||
"Category": "aws" | ||
} |
Oops, something went wrong.