generated from DNXLabs/docker-module-template
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
f424bc6
commit a3bb07c
Showing
4 changed files
with
631 additions
and
168 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,131 @@ | ||
import json | ||
import time | ||
import os | ||
|
||
# noqa: E502 | ||
|
||
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=os.environ['AWS_DEFAULT_REGION']) | ||
s3client = boto_authenticated_client.client( | ||
's3', region_name=os.environ['AWS_DEFAULT_REGION']) | ||
|
||
|
||
blue_env_info = get_env_info(beanstalkclient, BLUE_ENV_NAME) | ||
blue_env_id = blue_env_info['Environments'][0]['EnvironmentId'] | ||
blue_version_label = blue_env_info['Environments'][0]['VersionLabel'] | ||
|
||
# Calling CreateConfigTemplate API | ||
config_template = create_config_template(beanstalkclient, AppName=( | ||
BEANSTALK_APP_NAME), blue_env_id=blue_env_id, TempName="BlueEnvConfig") | ||
ReturnedTempName = config_template | ||
if not ReturnedTempName: | ||
# 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, did_new_env_was_created = create_green_environment( | ||
beanstalkclient, GREEN_ENV_NAME, | ||
ReturnedTempName, blue_version_label, | ||
BEANSTALK_APP_NAME | ||
) | ||
|
||
print("Green environment ID: " + green_env_id) | ||
if green_env_id and did_new_env_was_created: | ||
# Create a CNAME Config file | ||
blue_env_cname = blue_env_info['Environments'][0]['CNAME'] | ||
blue_env_cname_file = {'BlueEnvUrl': blue_env_cname} | ||
file_name = "blue_green_assets/blue_cname.json" | ||
response = s3client.put_object( | ||
Bucket=S3_ARTIFACTS_BUCKET, Key=file_name, Body=json.dumps(blue_env_cname_file)) | ||
|
||
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''' | ||
ListTemplates = beanstalkclient.describe_applications( | ||
ApplicationNames=[AppName])['Applications'][0]['ConfigurationTemplates'] | ||
count = 0 | ||
while count < len(ListTemplates): | ||
if ListTemplates[count] == TempName: | ||
print("Configuration template already exists") | ||
return TempName | ||
count += 1 | ||
response = beanstalkclient.create_configuration_template( | ||
ApplicationName=AppName, | ||
TemplateName=TempName, | ||
EnvironmentId=blue_env_id) | ||
return response['TemplateName'] | ||
|
||
|
||
def get_env_info(beanstalkclient, env_name): | ||
''' Get an beanstalk environment description by its name ''' | ||
response = beanstalkclient.describe_environments( | ||
EnvironmentNames=[ | ||
env_name | ||
]) | ||
return response | ||
|
||
|
||
def create_green_environment(beanstalkclient, env_name, config_template, app_version, app_name): | ||
''' Create a new elastic beansatalk environment based on a Environment Template''' | ||
did_new_env_was_created = True | ||
response = (beanstalkclient.describe_environments( | ||
EnvironmentNames=[env_name])) | ||
InvalidStatus = ["Terminating", "Terminated"] | ||
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 Green Environment") | ||
response = beanstalkclient.create_environment( | ||
ApplicationName=app_name, | ||
EnvironmentName=env_name, | ||
TemplateName=config_template, | ||
VersionLabel=app_version) | ||
return response['EnvironmentId'], did_new_env_was_created | ||
|
||
|
||
def wait_green_be_ready(beanstalkclient, GREEN_ENV_NAME): | ||
''' Stop code execution until an Beanstalk Environment gets in the Ready status''' | ||
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(60) | ||
green_env_info = get_env_info(beanstalkclient, GREEN_ENV_NAME) | ||
|
||
|
||
def rollback_created_env(boto_authenticated_client, environment_name): | ||
''' Terminate a beanstalk environment''' | ||
|
||
time.sleep(10) | ||
beanstalkclient = boto_authenticated_client.client( | ||
'elasticbeanstalk', region_name=os.environ['AWS_DEFAULT_REGION']) | ||
|
||
green_env_info = get_env_info(beanstalkclient, environment_name) | ||
if len(green_env_info["Environments"]) == 0: | ||
return "Environment terminated successfully!" | ||
beanstalkclient.terminate_environment( | ||
EnvironmentName=environment_name, | ||
EnvironmentId=green_env_info["Environments"][0]["EnvironmentId"] | ||
) | ||
return "{environment_name} terminated 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'] |
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,104 @@ | ||
from time import strftime, sleep | ||
from botocore.exceptions import ClientError | ||
import os | ||
import swap_environment | ||
|
||
def release_deployment(BLUE_ENV_NAME, BEANSTALK_APP_NAME, VERSION_LABEL, boto_authenticated_client): | ||
|
||
try: | ||
beanstalkclient = boto_authenticated_client.client('elasticbeanstalk') | ||
except ClientError as err: | ||
print("Failed to create boto3 beanstalk client.\n" + str(err)) | ||
return False | ||
|
||
# Wait for the new version to be consistent before deploying | ||
wait_until_env_be_ready(beanstalkclient, BLUE_ENV_NAME) | ||
|
||
if not deploy_new_version(beanstalkclient, BEANSTALK_APP_NAME, BLUE_ENV_NAME, VERSION_LABEL): | ||
raise Exception("Failed to deploy new version.") | ||
|
||
|
||
def create_new_version(beanstalkclient, VERSION_LABEL, BUCKET_KEY, S3_ARTIFACTS_BUCKET, BEANSTALK_APP_NAME): | ||
""" | ||
Creates a new application version in AWS Elastic Beanstalk | ||
""" | ||
|
||
try: | ||
response = beanstalkclient.create_application_version( | ||
ApplicationName=BEANSTALK_APP_NAME, | ||
VersionLabel=VERSION_LABEL, | ||
Description='New release azure devops', | ||
SourceBundle={ | ||
'S3Bucket': S3_ARTIFACTS_BUCKET, | ||
'S3Key': BUCKET_KEY | ||
}, | ||
Process=True | ||
) | ||
except ClientError as err: | ||
print("Failed to create application version.\n" + str(err)) | ||
return False | ||
|
||
try: | ||
if response['ResponseMetadata']['HTTPStatusCode'] == 200: | ||
return True | ||
else: | ||
print(response) | ||
return False | ||
except (KeyError, TypeError) as err: | ||
print(str(err)) | ||
return False | ||
|
||
|
||
def deploy_new_version(beanstalkclient, BEANSTALK_APP_NAME, BLUE_ENV_NAME, VERSION_LABEL): | ||
""" | ||
Deploy a new version to AWS Elastic Beanstalk | ||
""" | ||
try: | ||
response = beanstalkclient.update_environment( | ||
ApplicationName=BEANSTALK_APP_NAME, | ||
EnvironmentName=BLUE_ENV_NAME, | ||
VersionLabel=VERSION_LABEL, | ||
) | ||
except ClientError as err: | ||
print("Failed to update {BLUE_ENV_NAME} environment.\n" + str(err)) | ||
return False | ||
|
||
print("The new version {VERSION_LABEL} was deployed successfully on {BLUE_ENV_NAME}!") | ||
print( | ||
f"New version environment URL: http://{response['EnvironmentName']}.elasticbeanstalk.com") | ||
return True | ||
|
||
|
||
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!") | ||
sleep(50) | ||
env_info = get_env_info(beanstalkclient, ENV_NAME) | ||
return "Env is ready" | ||
|
||
|
||
def get_env_info(beanstalkclient, env_name): | ||
response = beanstalkclient.describe_environments( | ||
EnvironmentNames=[ | ||
env_name | ||
]) | ||
return response | ||
|
||
def rollback_release(client, application_name, environment_name, VERSION_LABEL): | ||
try: | ||
beanstalkclient = client.client('elasticbeanstalk') | ||
except ClientError as err: | ||
print("Failed to create boto3 beanstalk client.\n" + str(err)) | ||
return False | ||
|
||
environment_info, client = swap_environment.get_environment_information( | ||
beanstalkclient, environment_name) | ||
|
||
while environment_info["Environments"][0]["Status"] != "Ready": | ||
sleep(10) | ||
environment_info, client = swap_environment.get_environment_information( | ||
beanstalkclient, environment_name) | ||
|
||
if not deploy_new_version(beanstalkclient, application_name, environment_name, VERSION_LABEL): | ||
raise Exception("Failed to rollback to the version {VERSION_LABEL} on {environment_name}.") |
Oops, something went wrong.