Skip to content

Commit

Permalink
Improve script logging and fix api trottling
Browse files Browse the repository at this point in the history
  • Loading branch information
caiovfernandes committed Jun 29, 2023
1 parent d700384 commit fe27360
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 82 deletions.
15 changes: 8 additions & 7 deletions src/aws_authentication.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import boto3
import os


def get_boto_client():
print("AUTH_METHOD: " + str(os.getenv('AUTH_METHOD')))
if os.getenv('AUTH_METHOD') == 'SSO':
boto3.setup_default_session(profile_name=os.getenv('SSO_PROFILE'))
print("SSO Authentication")
else:
print("AWS KEYS authentication")
return boto3
print("AUTH_METHOD: ")
if os.getenv('AUTH_METHOD') == 'SSO':
boto3.setup_default_session(profile_name=os.getenv('SSO_PROFILE'))
print("\t -> SSO Authentication\n")
else:
print("\t -> AWS KEYS authentication\n")
return boto3
14 changes: 13 additions & 1 deletion src/clone_blue_environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ def main(BLUE_ENV_NAME, GREEN_ENV_NAME, BEANSTALK_APP_NAME, S3_ARTIFACTS_BUCKET,

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

current_release_bucket, current_release_key = get_current_release_package(
beanstalkclient, BEANSTALK_APP_NAME)
return current_release_bucket, current_release_key


def create_config_template(beanstalkclient, AppName, blue_env_id, TempName):
'''Creates a ElasticBeanstalk deployment template and return the Template Name'''
Expand Down Expand Up @@ -101,7 +105,7 @@ def wait_green_be_ready(beanstalkclient, GREEN_ENV_NAME):
green_env_info = get_env_info(beanstalkclient, GREEN_ENV_NAME)
while green_env_info["Environments"][0]["Status"] != "Ready":
print("Waiting the blue environment be Ready!")
time.sleep(10)
time.sleep(60)
green_env_info = get_env_info(beanstalkclient, GREEN_ENV_NAME)


Expand All @@ -118,3 +122,11 @@ def rollback_created_env(boto_authenticated_client, environment_name):
EnvironmentId=green_env_info["Environments"][0]["EnvironmentId"]
)
return "Environment terminaated successfully!!"

def get_current_release_package(client, application_name):
response = client.describe_application_versions(
ApplicationName=application_name,
MaxRecords=1
)

return response['ApplicationVersions'][0]['SourceBundle']['S3Bucket'], response['ApplicationVersions'][0]['SourceBundle']['S3Key']
3 changes: 2 additions & 1 deletion src/deploy_release.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ def deploy_new_version(beanstalkclient, BEANSTALK_APP_NAME, BLUE_ENV_NAME, VERSI
return False

print("The new version was deployed successfully!")
print(f"New version environment URL: http://{response['EnvironmentName']}.elasticbeanstalk.com")
print(
f"New version environment URL: http://{response['EnvironmentName']}.elasticbeanstalk.com")
return True


Expand Down
113 changes: 76 additions & 37 deletions src/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,29 @@
import release_health_check
import terminate_green_env
import aws_authentication
import time


def main():
print("------------Initiating blue green deployment process------------\n\n\n")
starting_time = time.time()

BLUE_ENV_NAME = os.getenv("BLUE_ENV_NAME")
GREEN_ENV_NAME = os.getenv("GREEN_ENV_NAME")
BEANSTALK_APP_NAME = os.getenv("BEANSTALK_APP_NAME")
S3_ARTIFACTS_BUCKET = os.getenv("S3_ARTIFACTS_BUCKET")
S3_ARTIFACTS_OBJECT = os.getenv("S3_ARTIFACTS_OBJECT")

print("Environment variables: \n")
print(f"BLUE_ENV_NAME = {BLUE_ENV_NAME}\n")
print(f"GREEN_ENV_NAME = {GREEN_ENV_NAME}\n")
print(f"BEANSTALK_APP_NAME = {BEANSTALK_APP_NAME}\n")
print(f"S3_ARTIFACTS_BUCKET = {S3_ARTIFACTS_BUCKET}\n")
print(f"S3_ARTIFACTS_OBJECT {S3_ARTIFACTS_OBJECT}\n")

current_release_bucket=""
current_release_key=""

available_execution_types = ["deploy", "cutover", "full", "rollback"]
execution_type = str(sys.argv[1])

Expand All @@ -36,16 +44,22 @@ def main():
sys.exit(1)

boto_authenticated_client = aws_authentication.get_boto_client()
print("Execution Type: " + execution_type)
print(f"\n Execution Type: {execution_type}\n")
print("Initiating blue green deployment process")
print("\n\n\n ------------------ Initiating Step 1 --------------------- \n\n\n")
print("\n\n\n ------------------ Creating Green Env --------------------- \n\n\n")



if execution_type == "deploy" or execution_type == "full":
print("\n\n\n ------------------ Stating Deployment Step 1 --------------------- \n")
print("------------------ Creating Green Env --------------------- \n\n\n")
# Step 1: Cloning the blue env into green env.
try:
print("Clonning the blue environment")
clone_blue_environment.main(
print("Clonning the blue environment...")
start_1 = time.time()
previous_release_bucket, previous_release_key = clone_blue_environment.main(
BLUE_ENV_NAME, GREEN_ENV_NAME, BEANSTALK_APP_NAME, S3_ARTIFACTS_BUCKET, boto_authenticated_client)
print(f"Clonning the blue environment has finished successfully!\n\
\tIt took: {time.time() - start_1} seconds\n")
except Exception as err:
clone_blue_environment.rollback_created_env(
boto_authenticated_client, GREEN_ENV_NAME
Expand All @@ -56,13 +70,18 @@ def main():
print(str(e))
traceback.print_exc()
sys.exit(1)

boto_authenticated_client = aws_authentication.get_boto_client()
print("\n\n\n ------------------ Stating Step 2 ---------------------\n")
print("------------------ Swapping Domains --------------------- \n\n\n")
# Step 2: Swapping blue and green envs URL's.
try:
print("Swapping environment URL's")
print("Swapping environment Domains...")
start_2 = time.time()
swap_environment.main(BLUE_ENV_NAME, GREEN_ENV_NAME, S3_ARTIFACTS_BUCKET,
BEANSTALK_APP_NAME, boto_authenticated_client)
print("URL's swap task finished succesfully")
print(f"Swapping environment Domains has finished successfully!\n\
\tIt took: {time.time() - start_2} seconds\n")
except Exception as err:
print("Swap environment has failed.")
print(("Error: " + str(err)))
Expand All @@ -75,13 +94,18 @@ def main():
print(e)
traceback.print_exc()
sys.exit(1)

boto_authenticated_client = aws_authentication.get_boto_client()
print("\n\n\n ------------------ Stating Step 3 --------------------- \n")
print("----------------- New release Deployment --------------------- \n\n\n")
# ## Step 3: Deploying the new release into the blue env.
try:
print("New release deployment initiated.")
start_3 = time.time()
deploy_release.main(S3_ARTIFACTS_OBJECT, S3_ARTIFACTS_BUCKET,
BLUE_ENV_NAME, BEANSTALK_APP_NAME, boto_authenticated_client)
print("New release was deployed successfully.")
print(f"New release deployment has finished successfully!\n\
\tIt took: {time.time() - start_3} seconds\n")
except Exception as err:
print("New release deployment has failed.")
print(("Error: " + str(err)))
Expand All @@ -90,7 +114,6 @@ def main():
traceback.print_exc()
sys.exit(1)

boto_authenticated_client = aws_authentication.get_boto_client()
# Start cutover phase
if execution_type == "cutover" or execution_type == "full":
# Step 4: Health checking new release deployment.
Expand All @@ -107,26 +130,16 @@ def main():
sys.exit(1)

# Step 5: Re-swapping the URL's and terminating the green environment.
print("\n\n\n ------------------ Stating Cutover --------------------- \n")
print("------------------ Re-swapping the Domains && Killing the green environment --------------------- \n\n\n")
boto_authenticated_client = aws_authentication.get_boto_client()
try:
print("Re-swapping the URL's and terminating the green environment.")
time_4 = time.time()
terminate_green_env.main(
BLUE_ENV_NAME, GREEN_ENV_NAME, BEANSTALK_APP_NAME, boto_authenticated_client)
print("The green environment has terminated successfully.")
print("The URL's has reswapped successfully.")
except Exception as err:
print(
"Re-swapping the URL's and terminating the green environment has failed!")
print(("Error: " + str(err)))
e = sys.exc_info()[0]
print(e)
traceback.print_exc()
sys.exit(1)
if execution_type == "rollback":
try:
print("Re-swapping the URL's and terminating the green environment.")
swap_environment.re_swap_dns(
boto_authenticated_client, S3_ARTIFACTS_BUCKET, GREEN_ENV_NAME, BLUE_ENV_NAME)
print(f"Re-swapping the URL's and terminating the green environment has finished successfully!\n\
\tIt took: {time.time() - time_4} seconds\n")
except Exception as err:
print(
"Re-swapping the URL's and terminating the green environment has failed!")
Expand All @@ -135,19 +148,45 @@ def main():
print(e)
traceback.print_exc()
sys.exit(1)
try:
print("Rolling back the blue environment.")
clone_blue_environment.rollback_created_env(
boto_authenticated_client, GREEN_ENV_NAME
)
print("The blue environment has rolled back successfully.")
except Exception as err:
print("Rolling back the blue environment has failed!")
print(("Error: " + str(err)))
e = sys.exc_info()[0]
print(e)
traceback.print_exc()
sys.exit(1)
# if execution_type == "rollback":
# try:
# print("Rolling back the blue environment to the previous version.")
# deploy_release.main(previous_release_key, previous_release_bucket,
# BLUE_ENV_NAME, BEANSTALK_APP_NAME, boto_authenticated_client)
#
# except Exception as err:
# print("Rolling back the blue environment has failed!")
# print(("Error: " + str(err)))
# e = sys.exc_info()[0]
# print(e)
# traceback.print_exc()
# sys.exit(1)
# try:
# print("Re-swapping the URL's and terminating the green environment.")
# swap_environment.re_swap_dns(
# boto_authenticated_client, S3_ARTIFACTS_BUCKET, GREEN_ENV_NAME, BLUE_ENV_NAME)
# except Exception as err:
# print(
# "Re-swapping the URL's and terminating the green environment has failed!")
# print(("Error: " + str(err)))
# e = sys.exc_info()[0]
# print(e)
# traceback.print_exc()
# sys.exit(1)
# try:
# print("Rolling back the blue environment.")
# clone_blue_environment.rollback_created_env(
# boto_authenticated_client, GREEN_ENV_NAME
# )
# except Exception as err:
# print("Rolling back the blue environment has failed!")
# print(("Error: " + str(err)))
# e = sys.exc_info()[0]
# print(e)
# traceback.print_exc()
# sys.exit(1)




if __name__ == "__main__":
Expand Down
53 changes: 28 additions & 25 deletions src/release_health_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,37 +4,40 @@
import requests
import time


def main(BLUE_ENV_NAME, boto_authenticated_client):
beanstalkclient = boto_authenticated_client.client('elasticbeanstalk')
beanstalkclient = boto_authenticated_client.client('elasticbeanstalk')

wait_until_env_be_ready(beanstalkclient, BLUE_ENV_NAME)

wait_until_env_be_ready(beanstalkclient, BLUE_ENV_NAME)
if os.getenv("RELEASE_HEALTH_CHECKING_PATH"):
blue_env_cname = os.getenv("RELEASE_HEALTH_CHECKING_PATH")
else:
blue_env_info = get_env_info(beanstalkclient, BLUE_ENV_NAME)
blue_env_cname = "http://" + blue_env_info["Environments"][0]["CNAME"]

if os.getenv("RELEASE_HEALTH_CHECKING_PATH"):
blue_env_cname = os.getenv("RELEASE_HEALTH_CHECKING_PATH")
else:
blue_env_info = get_env_info(beanstalkclient, BLUE_ENV_NAME)
blue_env_cname = "http://" + blue_env_info["Environments"][0]["CNAME"]

print("blue_env_cname: " + blue_env_cname)
env_http_response = requests.get(blue_env_cname, verify=False)
env_reponse_status = env_http_response.status_code
print("blue_env_cname: " + blue_env_cname)
env_http_response = requests.get(blue_env_cname, verify=False)
env_reponse_status = env_http_response.status_code

if env_reponse_status == 200 or env_reponse_status == 301:
return "Ok"
else:
raise Exception("The environment isn't health")

if env_reponse_status == 200 or env_reponse_status == 301:
return "Ok"
else:
raise Exception("The environment isn't health")

def get_env_info(beanstalkclient, env_name):
response = beanstalkclient.describe_environments(
EnvironmentNames=[
env_name
])
return response
response = beanstalkclient.describe_environments(
EnvironmentNames=[
env_name
])
return response


def wait_until_env_be_ready(beanstalkclient, ENV_NAME):
env_info = get_env_info(beanstalkclient, ENV_NAME)
while env_info["Environments"][0]["Status"] != "Ready":
print("Waiting the blue environment be Ready!")
time.sleep(10)
env_info = get_env_info(beanstalkclient, ENV_NAME)
return "Env is ready"
while env_info["Environments"][0]["Status"] != "Ready":
print("Waiting the blue environment be Ready!")
time.sleep(10)
env_info = get_env_info(beanstalkclient, ENV_NAME)
return "Env is ready"
11 changes: 1 addition & 10 deletions src/swap_environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ def get_env_address(BLUE_CNAME_CONFIG_FILE, S3_ARTIFACTS_BUCKET, s3client):
def get_environment_information(beanstalkclient, EnvName):
''' Get informations about a beanstalk environment'''
env_count = 0
env_count_for_credentials = 0

while True:
response = beanstalkclient.describe_environments(
Expand All @@ -72,21 +71,13 @@ def get_environment_information(beanstalkclient, EnvName):
])
if response["Environments"][0]["Status"] == "Ready":
break
time.sleep(5)
time.sleep(60)

if env_count == 3:
print("Waiting the env be ready.")
env_count = 0
else:
env_count += 1
if env_count_for_credentials == 12:
print("Renewing security token...")
boto_client = aws_authentication.get_boto_client()
beanstalkclient = boto_client.client(
"elasticbeanstalk", region_name="us-east-1")
env_count_for_credentials = 0
else:
env_count_for_credentials += 1

return response, beanstalkclient

Expand Down
1 change: 0 additions & 1 deletion src/terminate_green_env.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,5 @@ def delete_green_environment(beanstalkclient, EnvName):
time.sleep(10)
if (GreenEnvStatus == 'Ready'):
response = beanstalkclient.terminate_environment(EnvironmentName=EnvName)
print(response)
print("Successfully Terminated Green Environment")
return

0 comments on commit fe27360

Please sign in to comment.