Skip to content

Commit

Permalink
👌 IMPROVE: Add environment validatin if a environment is already created
Browse files Browse the repository at this point in the history
  • Loading branch information
caiovfernandes committed Jun 13, 2022
1 parent 77aa674 commit 39f7614
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 54 deletions.
2 changes: 1 addition & 1 deletion _docs/assets/BlueGreen.drawio

Large diffs are not rendered by default.

43 changes: 21 additions & 22 deletions blue_green_assets/clone_blue_environment.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import json
import traceback
import sys
import logging
import os
import time
import aws_authentication

def main(BLUE_ENV_NAME, GREEN_ENV_NAME, BEANSTALK_APP_NAME, boto_authenticated_client):
def main(BLUE_ENV_NAME, GREEN_ENV_NAME, BEANSTALK_APP_NAME, S3_ARTIFACTS_BUCKET, boto_authenticated_client):
beanstalkclient = boto_authenticated_client.client('elasticbeanstalk',region_name='ap-southeast-2')
s3client = boto_authenticated_client.client('s3',region_name='ap-southeast-2')

blue_env_info=get_blue_env_info(beanstalkclient, BLUE_ENV_NAME)
blue_env_id=(blue_env_info['Environments'][0]['EnvironmentId'])
blue_version_label=(blue_env_info['Environments'][0]['VersionLabel'])
Expand All @@ -19,27 +17,26 @@ def main(BLUE_ENV_NAME, GREEN_ENV_NAME, BEANSTALK_APP_NAME, boto_authenticated_c
#raise Exception if the Config file does not exist
raise Exception("There were some issue while creating a Configuration Template from the Blue Environment")
else:
green_env_id=create_green_environment(beanstalkclient, env_name=(GREEN_ENV_NAME),config_template=ReturnedTempName,AppVersion=blue_version_label,AppName=(BEANSTALK_APP_NAME))
green_env_id, did_new_env_was_created = create_green_environment(beanstalkclient, GREEN_ENV_NAME, ReturnedTempName, blue_version_label, BEANSTALK_APP_NAME)

# wait_green_be_ready(beanstalkclient, GREEN_ENV_NAME)

print("Green environment ID: " + green_env_id)
if green_env_id:
if green_env_id and did_new_env_was_created:
#Create a CNAME Config file
BlueEnvCname=(blue_env_info['Environments'][0]['CNAME'])
BlueEnvCnameFile = {'BlueEnvUrl': BlueEnvCname}
file_name = "blue_cname.json"
with open(file_name, 'w') as fp:
json.dump(BlueEnvCnameFile, fp)
print ("Created a new CNAME file")
file_name = "blue_green_assets/blue_cname.json"
response = s3client.put_object(Bucket=S3_ARTIFACTS_BUCKET, Key=file_name, Body=json.dumps(BlueEnvCnameFile))

print("Created a new CNAME file at S3")

def create_config_template(beanstalkclient, AppName,blue_env_id,TempName):
def create_config_template(beanstalkclient, AppName, blue_env_id, TempName):
ListTemplates = beanstalkclient.describe_applications(ApplicationNames=[AppName])['Applications'][0]['ConfigurationTemplates']
count = 0
while count < len(ListTemplates):
print (ListTemplates[count])
if ListTemplates[count] == TempName:
print ("ConfigTempAlreadyExists")
print ("Configuration template already exists")
return TempName
count += 1
response = beanstalkclient.create_configuration_template(
Expand All @@ -56,21 +53,23 @@ def get_blue_env_info(beanstalkclient, env_name):
return response

def create_green_environment(beanstalkclient, env_name,config_template,AppVersion,AppName):
GetEnvData = (beanstalkclient.describe_environments(EnvironmentNames=[env_name]))
print(GetEnvData)
did_new_env_was_created = True
response = (beanstalkclient.describe_environments(EnvironmentNames=[env_name]))
InvalidStatus = ["Terminating","Terminated"]
if not(GetEnvData['Environments']==[]):
print("Environment Exists")
if not(GetEnvData['Environments'][0]['Status']) in InvalidStatus:
print("Existing Environment with the name %s not in Invalid Status" % env_name)
return (GetEnvData['Environments'][0]['EnvironmentId'])
GetEnvData = [item for item in response['Environments'] if item['Status'] not in InvalidStatus]
if not(GetEnvData==[]):
did_new_env_was_created = False
if not(GetEnvData[0]['Status']) in InvalidStatus:
print("Environment already exists")
print(f"Existing Environment - {env_name} - it is in a Valid Status: {GetEnvData[0]['Status']}")
return (GetEnvData[0]['EnvironmentId']), did_new_env_was_created
print ("Creating a new Environment")
response = beanstalkclient.create_environment(
ApplicationName=AppName,
EnvironmentName=env_name,
TemplateName=config_template,
VersionLabel=AppVersion)
return response['EnvironmentId']
return response['EnvironmentId'], did_new_env_was_created

def wait_green_be_ready(beanstalkclient, GREEN_ENV_NAME):
green_env_info = get_green_env_info(beanstalkclient, GREEN_ENV_NAME)
Expand Down
18 changes: 8 additions & 10 deletions blue_green_assets/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,6 @@
import aws_authentication

def main():
AWS_DEFAULT_REGION = os.getenv("AWS_DEFAULT_REGION")
AWS_ACCOUNT_ID = os.getenv("AWS_ACCOUNT_ID")
AWS_ROLE = os.getenv("AWS_ROLE")
BLUE_ENV_NAME = os.getenv("BLUE_ENV_NAME")
GREEN_ENV_NAME = os.getenv("GREEN_ENV_NAME")
BEANSTALK_APP_NAME = os.getenv("BEANSTALK_APP_NAME")
Expand All @@ -27,7 +24,7 @@ def main():
## Step 1: Cloning the blue env into green env.
try:
print(colored("Clonning the blue environment", "blue"))
clone_blue_environment.main(BLUE_ENV_NAME, GREEN_ENV_NAME, BEANSTALK_APP_NAME, boto_authenticated_client)
clone_blue_environment.main(BLUE_ENV_NAME, GREEN_ENV_NAME, BEANSTALK_APP_NAME, S3_ARTIFACTS_BUCKET, boto_authenticated_client)
except Exception as err:
print(colored("Clonning the blue environment environment has failed!", "red"))
print(colored( ("Error: " + str(err)), "red"))
Expand All @@ -39,8 +36,8 @@ def main():
## Step 2: Swapping blue and green envs URL's.
try:
print(colored("Swapping environment URL's", "blue"))
swap_environment.main(BLUE_ENV_NAME, GREEN_ENV_NAME, boto_authenticated_client)
print(colored("URL's swapped successfully", "green"))
swap_environment.main(BLUE_ENV_NAME, GREEN_ENV_NAME, S3_ARTIFACTS_BUCKET, boto_authenticated_client)
print(colored("URL's swap task finished succesfully", "green"))
except Exception as err:
print(colored("Swap environment has failed.", "red"))
print(colored(("Error: " + str(err)), "red"))
Expand All @@ -66,20 +63,20 @@ def main():
try:
print(colored("Health checking the new release.", "blue"))
release_health_check.main(BLUE_ENV_NAME, boto_authenticated_client)
print(colored("The environment is health.", "green"))
print(colored("Environment is healthy!", "green"))
except Exception as err:
print(colored("Environment health check has failed.", "red"))
print(colored("Environment health check has failed!", "red"))
print(colored(("Error: " + str(err)), "red"))
e = sys.exc_info()[0]
print(e)
traceback.print_exc()
sys.exit(1)

## Step 5: Re-swapping the URL's and terminating the green environment.
## Step 5: Re-swapping the URL's and terminating the green environment.
if str(sys.argv[1]) == 'cutover':
try:
print(colored("Re-swapping the URL's and terminating the green environment.", "blue"))
terminate_green_env.main()
terminate_green_env.main(BLUE_ENV_NAME, GREEN_ENV_NAME, BEANSTALK_APP_NAME, boto_authenticated_client)
print(colored("The blue environment has terminated successfully.", "green"))
print(colored("The URL's has reswapped successfully.", "green"))
except Exception as err:
Expand All @@ -91,6 +88,7 @@ def main():
sys.exit(1)



if __name__ == "__main__":
try:
if "AWS_DEFAULT_REGION" not in os.environ:
Expand Down
18 changes: 9 additions & 9 deletions blue_green_assets/swap_environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,17 @@



def main(BLUE_ENV_NAME, GREEN_ENV_NAME, boto_authenticated_client):
def main(BLUE_ENV_NAME, GREEN_ENV_NAME, S3_ARTIFACTS_BUCKET, boto_authenticated_client):
beanstalkclient = boto_authenticated_client.client("elasticbeanstalk",region_name="ap-southeast-2")
s3client = boto_authenticated_client.client('s3',region_name='ap-southeast-2')

BLUE_CNAME_CONFIG_FILE = "blue_cname.json"
BLUE_CNAME_CONFIG_FILE = "blue_green_assets/blue_cname.json"

blue_env_url = get_blue_env_address(BLUE_CNAME_CONFIG_FILE)
blue_env_url = get_blue_env_address(BLUE_CNAME_CONFIG_FILE, S3_ARTIFACTS_BUCKET, s3client)
print("Blue env URL: " + str(blue_env_url))


green_env_info = get_green_env_info(beanstalkclient, GREEN_ENV_NAME)
green_env_info = get_environment_information(beanstalkclient, GREEN_ENV_NAME)
green_env_cname = green_env_info["Environments"][0]["CNAME"]

print("Green env CNAME: " + str(green_env_cname))
Expand All @@ -27,7 +28,7 @@ def main(BLUE_ENV_NAME, GREEN_ENV_NAME, boto_authenticated_client):
else:
while green_env_info["Environments"][0]["Status"] != "Ready":
time.sleep(10)
green_env_info = get_green_env_info(beanstalkclient, GREEN_ENV_NAME)
green_env_info = get_environment_information(beanstalkclient, GREEN_ENV_NAME)
swap_response = swap_urls(beanstalkclient, BLUE_ENV_NAME, GREEN_ENV_NAME)
if swap_response == "Successful":
return "Ok"
Expand All @@ -37,15 +38,14 @@ def main(BLUE_ENV_NAME, GREEN_ENV_NAME, boto_authenticated_client):



def get_blue_env_address(BLUE_CNAME_CONFIG_FILE):
def get_blue_env_address(BLUE_CNAME_CONFIG_FILE, S3_ARTIFACTS_BUCKET, s3client):
# Opening JSON file
file_name = BLUE_CNAME_CONFIG_FILE
with open(file_name) as json_file:
data = json.load(json_file)
data = json.loads(s3client.get_object(Bucket=S3_ARTIFACTS_BUCKET, Key=file_name)['Body'].read())
blue_env_url = data["BlueEnvUrl"]
return blue_env_url

def get_green_env_info(beanstalkclient, EnvName):
def get_environment_information(beanstalkclient, EnvName):
count = 0
while True:
response = beanstalkclient.describe_environments(
Expand Down
16 changes: 4 additions & 12 deletions blue_green_assets/terminate_green_env.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,20 @@
import boto3
import json
import traceback
import time
import sys
import logging
import os

def main():
BLUE_ENV_NAME = os.getenv("BLUE_ENV_NAME")
GREEN_ENV_NAME = os.getenv("GREEN_ENV_NAME")
BEANSTALK_APP_NAME = os.getenv("BEANSTALK_APP_NAME")
def main(BLUE_ENV_NAME, GREEN_ENV_NAME, BEANSTALK_APP_NAME, boto_authenticated_client):
CREATE_CONFIG_TEMPLATE_NAME = "BlueEnvConfig"

beanstalkclient = boto3.client('elasticbeanstalk',region_name='ap-southeast-2')
beanstalkclient = boto_authenticated_client.client('elasticbeanstalk',region_name='ap-southeast-2')
s3client = boto_authenticated_client.client('s3',region_name='ap-southeast-2')
try:
print("Starting the job")
# Extract the Job Data
#Calling DeleteConfigTemplate API
DeleteConfigTemplate=DeleteConfigTemplateBlue(beanstalkclient, AppName=(BEANSTALK_APP_NAME),TempName=(CREATE_CONFIG_TEMPLATE_NAME))
print(DeleteConfigTemplate)
#re-swapping the urls
print("Swapping the URL's")
print("Swapping URL's")
reswap = SwapGreenandBlue(beanstalkclient, SourceEnv=(BLUE_ENV_NAME),DestEnv=(GREEN_ENV_NAME))
if reswap == "Failure":
print("Re-Swap did not happen")
Expand Down Expand Up @@ -51,7 +45,6 @@ def DeleteConfigTemplateBlue(beanstalkclient, AppName,TempName):

def SwapGreenandBlue(beanstalkclient, SourceEnv, DestEnv):
GetEnvData = (beanstalkclient.describe_environments(EnvironmentNames=[SourceEnv,DestEnv],IncludeDeleted=False))
print(GetEnvData)
if (((GetEnvData['Environments'][0]['Status']) == "Ready") and ((GetEnvData['Environments'][1]['Status']) == "Ready")):
response = beanstalkclient.swap_environment_cnames(SourceEnvironmentName=SourceEnv,DestinationEnvironmentName=DestEnv)
return ("Successful")
Expand All @@ -60,7 +53,6 @@ def SwapGreenandBlue(beanstalkclient, SourceEnv, DestEnv):

def DeleteGreenEnvironment(beanstalkclient, EnvName):
GetEnvData = (beanstalkclient.describe_environments(EnvironmentNames=[EnvName]))
print(GetEnvData)
InvalidStatus = ["Terminating","Terminated"]
if not(GetEnvData['Environments']==[]):
if (GetEnvData['Environments'][0]['Status']) in InvalidStatus:
Expand Down

0 comments on commit 39f7614

Please sign in to comment.