Tuesday 4 May 2021

Continuous Delivery of Microservices on AWS using AWS Elastic Beanstalk

 

Continuous Delivery of Microservices on AWS using AWS Elastic Beanstalk

AWS Elastic Beanstalk service can be used to deploy and scale applications and services (from docker containers) developed with Java, .NET, PHP, Nodejs, Python, Ruby, Go etc on servers such as Apache, Tomcat, Nginx etc. Docker containers provide the flexibility of selecting one's runtime environment of choice including platform, programming language, app/services dependencies, and also, configuring the environment appropriately. All one is required to do is simply push the docker image to the image repository, and deploy the container. Elastic Beanstalk service, then, takes care of different aspects of deployment such as capacity provisioning, load balancing, auto-scaling, application/service health monitoring etc.

Docker platform for Elastic Beanstalk has two generic configurations such as following:

  • Single container Docker
  • Multicontainer Docker

We shall try and cover the use cases for both the configuration types.

Single Container Docker

Before getting into details of single container docker configurations for Elastic Beanstalk, lets quickly look into the solution architecture for deploying microservices on AWS using AWS Elastic Beanstalk.

Solution Architecture

Following represents the solution architecture of deploying microservices on AWS using AWS Elastic Beanstalk using single container docker configurations.

Solution Architecture - Microservices to AWS Elastic Beanstalk

In the above diagram, pay attention to some of the following:

  1. Code is checked into code repository such as Gitlab
  2. Webhook configured in GitLab triggers the Jenkins job
  3. Jenkins job starts executing which results in following steps:
    • Retrieve the microservice artifacts from Gitlab
    • Build the microservice
    • Run the tests such as unit and integration tests
    • Build the image if all of the above steps are successful
    • Push the image to image repository such as Dockerhub or AWS ECR
    • Deploy using AWS Elastic Beanstalk CLI command

Single Docker Container Configuration

Following steps need to be taken to get setup with Elastic Beanstalk to deploy application/services/microservices from docker containers based on single docker container configuration:

  1. Create a Beanstalk application using AWS console for creating new application. Pay attention to some of the following while creating the application.
    • Select environment as Web Server environment.
    • On environment type page, select configuration as "Docker" (and not Multi-container Docker) and environment type as "Load balancing, auto scaling"
    • Continue with choosing default in each step. In "Application version", you may choose to upload the Dockerfile or Dockerrun.aws.json. Later, the same Dockerfile or Dockerrun.aws.json can be uploaded using "eb deploy" command as part of Jenkins build post-steps.
  2. Install Elastic Beanstalk command line interface (EB CLI). EB CLI provides a set of commands for creating, updating and monitoring environments from a local repository.
  3. Go to the project folder consisting of Dockerrun.aws.json or Dockerfile (for single docker container configuration). Use "eb init" command to choose some of the following:
    • Region
    • Access key and secret key
    • Select an application (created earlier using EB console).
    • Select a keypair (one which was selected while creating the application using EB console)

With above steps followed, one should be all set to execute the following command from the project folder.

eb deploy

Make sure that project folder consists of either Dockerfile or Dockerrun.aws.json. In the code below, image is retrieved from Dockerhub. Note the AWSEBDockerrunVersion as "1". For multi-container configuration, the value becomes "2".

{
  "AWSEBDockerrunVersion": 1,
  "Image": {
    "Name": "xyz/springboot-web-app",
    "Update": "true"
  },
  "Ports": [
    {
      "ContainerPort": "8080"
    }
  ],
  "Logging": "/var/log"
}

Configure Jenkins Post-steps

Jenkins post-steps can be configured to achieve following:

Pushing images to Dockerhub; Deploy to Elastic Beanstalk

# Build the docker image
sudo docker build -t ImageName:tag /var/jenkins_home/workspace/SpringBootApp

# Login into Dockerhub; dockerhubLogin and dockerhubPassword is login and password respectively for dockerhub.com
sudo docker login -u="dockerhubLogin" -p="dockerhubPassword"

# Push docker image into Dockerhub
sudo docker push ImageName:tag

# EB Deploy; Go to the project folder and execute the command, "eb deploy"
cd /var/jenkins_home/workspace/awsebdemo
eb deploy

In above code samples, note some of the following:

  • ImageName:tag should be replaced with image such as xyz/springboot-web-app:latest.

Reference

Continuous Delivery of Microservices with AWS ECS

 

Continuous Delivery of Microservices with AWS ECS

AWS EC2 Container Service (ECS) is a highly scalable container management service which is used to start, stop and run microservices within Docker containers on a cluster of AWS EC2 instances. In this project, it is demonstrated as to how to deploy container-based microservices using CLI commands from within Jenkins. In order to achieve the same, following needs to be done:

  1. Setup ECS Service
    • Create a repository (EC2 Repository - ECR)
    • Create a task definition
    • Create an ECS cluster
    • Create a service
  2. Configure Jenkins build Post-steps

Note: For the demonstration purpose, both Gitlab and Jenkins are setup within Docker Containers. In real world scenario, Gitlab and Jenkins may get setup within different VMs.

Before getting into the setup details, let us try and understand the solution architecture related with achieving continuous delivery of microservices with AWS ECS.

Solution Architecture

Following represents the solution architecture of deploying micro-services using AWS ECS.

Solution Architecture - Microservices to AWS ECS

In above diagram, pay attention to some of the following:

  1. Code is checked into code repository such as Gitlab
  2. Web-hook configured in GitLab triggers the Jenkins job
  3. Jenkins job starts executing which results in following steps:
    • Retrieve the micro-service artifacts from Gitlab
    • Build the micro-service
    • Run the tests such as unit and integration tests
    • Build the image if all of the above steps are successful
    • Push the image to image repository such as Dockerhub or AWS ECR
    • Register task definition with AWS ECS
    • Update AWS ECS

Setup ECS Service

Before configuring steps into Jenkins, following needs to be setup using AWS ECS console.

Create an Image Repository with AWS ECR

First step is getting setup with AWS ECR. Following command needs to be executed in order to create an ECR repository.

# Login into ECR
aws configure
aws ecr get-login
docker built -t ImageName .
docker tag ImageName:tag AWS_ECR_URL/ImageName:tag
docker push AWS_ECR_URL/ImageName:tag

Note some of the following with above command:

  • AWS_ECR_URL is of the format https://aws_account_id.dkr.ecr.region.amazonaws.com. One can get the value of Account id by logging into console and going to My Account page. Region information can be found from the region and availability zones page
  • aws configure command is used to setup AWS CLI installation. The command would require one to enter credentials and config information before one starts working with their AWS services. The command would require one to enter details for access key ID, secret access key, default region name and default output format. However, as we need to achieve this without entering details at the prompt, following needs to be done in order to achieve the promptless command such as aws configure --profile default
    • Create a folder, .aws in the home.
    • Create a file named as config within above folder, .aws, with following content. One could get access key id and secret access key information by logging into the AWS console and accessing "My Security Credentials".
[default]
aws_access_key_id=AKXXIXXYXX4X4XXXXJRY
aws_secret_access_key=DyxxxxxxeqQyxyyyyytXcwwthbbCxaaaa8Qi0y
region=us-west-2
output=json
  • aws ecr get-login command is used to get the login prompt which needs to be executed further to login (start authenticated session) into AWS ECR and thereafter, push the image.
  • Other commands are usual commands to push the docker image to the AWS ECR image repository.

Executing above commands leads to user entering the details at the prompt. If one wants to achieve the same without prompt, from within Jenkins, the same could be achieved using following command which is a combination of commands to achieve promptless execution.

yes "" | aws configure --profile default ; aws ecr get-login > awslogin.sh ; sudo sh awslogin.sh

One can observe that executing command such as "aws ecr get-login" leads to output of command such as following which needs to be executed for successfully logging in. The command below is sent to awslogin.sh file as shown in the command and then awslogin.sh is executed.

docker login -u AWS -p SomeRandomPasswordStringSentByAWS -e none https://**aws_account_id**.dkr.ecr.**region**.amazonaws.com

Create a Task Definition

Next step is to create a task definition. Command such as following could be used to create the task definition:

aws ecs register-task-definition --family TaskDefinitionFamily --container-definitions "[{\"name\":\"ContainerName\",\"image\":\"ImageName:tag\",\"memory\":300,\"portMappings\":[{\"hostPort\":0,\"containerPort\":8080,\"protocol\":\"tcp\"}]}]" 

In above command, note the following two aspects:

  • TaskDefinitionFamily is the name of family for a task definition, which allows you to track multiple versions of the same task definition. The family is used as a name for your task definition.
  • ContainerName which is the name of the container.
  • container-definitions which is used to provide information related with one or more containers which will be started as a result of executing task based on the task definition.

One may want to login and access the AWS console at Services/EC2 Container Service/Task Definitions and try and create task definition to understand different aspects of task definition creation. Further details in relation with register-task-definition can be found on this page, register-task-definition.

Create an ECS Cluster

As this is one time activity, one may want to use AWS console at Services/EC2 Container Service/Clusters to create the cluster. It is pretty straight forward and very easy to create the cluster.

Create/Update the Service

Once done with creating cluster, one will be required to update ECS service. update-service command is used to modify the task definition and deploy a new version of the service.

aws ecs update-service --cluster ClusterName --service ServiceName --task-definition TaskDefinitionName --desired-count 2

In above code snippet, note some of the following:

  • TaskDefinitionName is name of the task definition. The family and revision (family:revision ) or full Amazon Resource Name (ARN) of the task definition to run in your service. If a revision is not specified, the latest ACTIVE revision is used. If you modify the task definition with update-service , Amazon ECS spawns a task with the new version of the task definition and then stops an old task after the new version is running.
  • ClusterName is name of the ECS cluster
  • ServiceName is name of the service
  • desired-count is used to configure number of instantiations of the task to place and keep running in your service.

Further details in relation with update-service command can be found on this page, update-service.

Configure Jenkins Post-steps

Jenkins post-steps can be configured to achieve following:

Pushing images to Dockerhub; Register task definition; Update ECS

# Build the docker image
sudo docker build -t ImageName:tag /var/jenkins_home/workspace/SpringBootApp

# Login into Dockerhub; dockerhubLogin and dockerhubPassword is login and password respectively for dockerhub.com
sudo docker login -u="dockerhubLogin" -p="dockerhubPassword"

# Push docker image into Dockerhub
sudo docker push ImageName:tag

# Login using AWS CLI
yes "" | aws configure --profile default ; aws ecr get-login > awslogin.sh ; sudo sh awslogin.sh

# Register task definition`
aws ecs register-task-definition --family TaskDefinitionFamily --container-definitions "[{\"name\":\"ContainerName\",\"image\":\"ImageName:tag\",\"memory\":300,\"portMappings\":[{\"hostPort\":0,\"containerPort\":8080,\"protocol\":\"tcp\"}]}]" 

# Update service
aws ecs update-service --cluster ClusterName --service ServiceName --task-definition TaskDefinitionName --desired-count 2

In above code samples, note some of the following:

  • ImageName:tag is the image name. For example, ajitesh/springboot-web-app:latest.
  • TaskDefinitionFamily is the name of family for a task definition, which allows you to track multiple versions of the same task definition. The family is used as a name for your task definition.
  • ContainerName which is the name of the container.
  • ClusterName is the name of the ECS cluster
  • ServiceName is the name of the service

Pushing images to ECR; Register the task definition ; Update the ECS service

# Login into AWS
yes "" | aws configure --profile default ; aws ecr get-login > awslogin.sh ; sudo sh awslogin.sh

# Build the docker image
sudo docker build -t ImageName /var/jenkins_home/workspace/SpringBootApp

# Tag the image; Push docker image into AWS ECR
sudo docker tag ImageName:tag 153819127898.dkr.ecr.us-west-2.amazonaws.com/ImageName:tag
sudo docker push AWS_ECR_URL/ImageName:tag

# Register task definition`
aws ecs register-task-definition --family TaskDefinitionFamily --container-definitions "[{\"name\":\"ContainerName\",\"image\":\"ImageName:tag\",\"memory\":300,\"portMappings\":[{\"hostPort\":0,\"containerPort\":8080,\"protocol\":\"tcp\"}]}]" 

# Update service
aws ecs update-service --cluster ClusterName --service ServiceName --task-definition TaskDefinitionName --desired-count 2

Reference

Wednesday 28 April 2021

AWS Migration & Transfer

 

AWS Migration & Transfer

AWS Migration Hub

AWS Migration Hub provides a single location to track the progress of application migrations across multiple AWS and partner solutions.

AWS Migration Hub allows you to either import information about on-premises servers and applications, or to perform a deeper discovery using our AWS Discovery Agent or AWS Discovery Collector, an agentless approach for VMware environments.

AWS Migration Hub network visualization allows you to accelerate migration planning by quickly identifying servers and their dependencies, identifying the role of a server, and grouping servers into applications.

To use network visualization, first install AWS Discovery agents and start data collection from the Data Collectors page.

AWS Migration Hub provides all application details in a central location.

This allows you to track the status of all the moving parts across all migrations, making it easier to view overall migration progress and reducing the time spent determining current status and next steps.

AWS Migration Hub lets you track the status of your migrations into any AWS region supported by your migration tools.

Regardless of which regions you migrate into, the migration status will appear in Migration Hub when using an integrated tool

Application Discovery Service

AWS Application Discovery Service helps enterprise customers plan migration projects by gathering information about their on-premises data centers.

Planning data center migrations can involve thousands of workloads that are often deeply interdependent.

Server utilization data and dependency mapping are important early first steps in the migration process.

AWS Application Discovery Service collects and presents configuration, usage, and behavior data from your servers to help you better understand your workloads.

The collected data is retained in encrypted format in an AWS Application Discovery Service data store.

You can export this data as a CSV file and use it to estimate the Total Cost of Ownership (TCO) of running on AWS and to plan your migration to AWS.

In addition, this data is also available in AWS Migration Hub, where you can migrate the discovered servers and track their progress as they get migrated to AWS.

Database Migration Service

AWS Database Migration Service helps you migrate databases to AWS quickly and securely.

The source database remains fully operational during the migration, minimizing downtime to applications that rely on the database. The AWS Database Migration Service can migrate your data to and from most widely used commercial and open-source databases.

AWS Database Migration Service supports homogeneous migrations such as Oracle to Oracle, as well as heterogeneous migrations between different database platforms, such as Oracle or Microsoft SQL Server to Amazon Aurora.

With AWS Database Migration Service, you can continuously replicate your data with high availability and consolidate databases into a petabyte-scale data warehouse by streaming data to Amazon Redshift and Amazon S3.

Server Migration Service

AWS Server Migration Service (SMS) is an agentless service which makes it easier and faster for you to migrate thousands of on-premises workloads to AWS.

AWS SMS allows you to automate, schedule, and track incremental replications of live server volumes, making it easier for you to coordinate large-scale server migrations.

AWS Transfer Family

The AWS Transfer Family provides fully managed support for file transfers directly into and out of Amazon S3 or Amazon EFS.

With support for Secure File Transfer Protocol (SFTP), File Transfer Protocol over SSL (FTPS), and File Transfer Protocol (FTP), the AWS Transfer Family helps you seamlessly migrate your file transfer workflows to AWS by integrating with existing authentication systems, and providing DNS routing with Amazon Route 53 so nothing changes for your customers and partners, or their applications.

With your data in Amazon S3 or Amazon EFS, you can use it with AWS services for processing, analytics, machine learning, archiving, as well as home directories and developer tools.

AWS Snow Family

AWS provides edge infrastructure and software that moves data processing and analysis as close as necessary to where data is created in order to deliver intelligent, real-time responsiveness and streamline the amount of data transferred.

This includes deploying AWS managed hardware and software to locations outside AWS Regions and even beyond AWS Outposts.

The AWS Snow Family helps customers that need to run operations in austere, non-data center environments, and in locations where there’s lack of consistent network connectivity.

The Snow Family, comprised of AWS Snowcone, AWS Snowball, and AWS Snowmobile, offers a number of physical devices and capacity points, most with built-in computing capabilities.

These services help physically transport up to exabytes of data into and out of AWS.

Snow Family devices are owned and managed by AWS and integrate with AWS security, monitoring, storage management, and computing capabilities.

You can improve the transfer speed from your data source to a Snowball device in the following ways, ordered from largest to smallest positive impact on performance:

  1. Use the latest Mac or Linux Snowball client
  2. Batch small files together
  3. Perform multiple copy operations at one time
  4. Copy from multiple workstations
  5. Transfer directories, not files

AWS DataSync

AWS DataSync is an online data transfer service that simplifies, automates, and accelerates moving data between on-premises storage systems and AWS Storage services, as well as between AWS Storage services.

You can use DataSync to migrate active datasets to AWS, archive data to free up on-premises storage capacity, replicate data to AWS for business continuity, or transfer data to the cloud for analysis and processing.

DataSync provides built-in security capabilities such as encryption of data in-transit, and data integrity verification in-transit and at-rest.

It optimizes use of network bandwidth, and automatically recovers from network connectivity failures.

In addition, DataSync provides control and monitoring capabilities such as data transfer scheduling and granular visibility into the transfer process through Amazon CloudWatch metrics, logs, and events.

DataSync can copy data between Network File System (NFS) shares, Server Message Block (SMB) shares, self-managed object storage, AWS Snowcone, Amazon Simple Storage Service (Amazon S3) buckets, Amazon Elastic File System (Amazon EFS) file systems, and Amazon FSx for Windows File Server file systems.

AWS Lambda

 

AWS Lambda

Concurrency

Your functions’ concurrency is the number of instances that serve requests at a given time

For an initial burst of traffic, your functions’ cumulative concurrency in a Region can reach an initial level of between 500 and 3000, which varies per Region.

Burst concurrency quotas:

  • 3000 – US West (Oregon), US East (N. Virginia), Europe (Ireland)
  • 1000 – Asia Pacific (Tokyo), Europe (Frankfurt), US East (Ohio)
  • 500 – Other Regions

When requests come in faster than your function can scale, or when your function is at maximum concurrency, additional requests fail with a throttling error (429 status code).

Throttling can result in the error: “Rate exceeded” and 429 “TooManyRequestsException”

If the above error occurs, verify if you see throttling messages in Amazon CloudWatch Logs but no corresponding data points in the Lambda Throttles metrics.

If there are no Lambda Throttles metrics, the throttling is happening on API calls in your Lambda function code.

Methods to resolve throttling include:

  • Configure reserved concurrency.
  • Use exponential backoff in your application code.

Concurrency metrics:

  • ConcurrentExecutions
  • UnreservedConcurrentExecutions
  • ProvisionedConcurrentExecutions
  • ProvisionedConcurrencyInvocations
  • ProvisionedConcurrencySpilloverInvocations
  • ProvisionedConcurrencyUtilization

Invocations

Synchronous:

  • CLI, SDK, API Gateway.
  • Result returned immediately.
  • Error handling happens client side (retries, exponential backoff etc.).

Asynchronous:

  • S3, SNS, CloudWatch Events etc.
  • Lambda retries up to 3 times.
  • Processing must be idempotent (due to retries).

Event source mapping:

  • SQS, Kinesis Data Streams, DynamoDB Streams.
  • Lambda does the polling (polls the source).
  • Records are processed in order (except for SQS standard).

Traffic Shifting

With the introduction of alias traffic shifting, it is now possible to trivially implement canary deployments of Lambda functions. By updating additional version weights on an alias, invocation traffic is routed to the new function versions based on the weight specified.

Detailed CloudWatch metrics for the alias and version can be analyzed during the deployment, or other health checks performed, to ensure that the new version is healthy before proceeding.

The following example AWS CLI command points an alias to a new version, weighted at 5% (original version at 95% of traffic):

aws lambda update-alias --function-name myfunction --name myalias --routing-config '{"AdditionalVersionWeights" : {"2" : 0.05} }'

AWS Batch

Batch jobs run as Docker images.

Dynamically provisions EC2 instances in a VPC.

Deployment Options:

  • Managed for you entirely (serverless).
  • Manage yourself.

For managed deployments:

  • Choose your pricing model: On-demand or Spot.
  • Choose instance types.
  • Configure VPC/subnets.

Pay for underlying EC2 instances.

Schedule using CloudWatch Events.

Orchestrate with Step Functions.

Can use on-demand or Spot instances.

Multi Node can be used for HPC use cases.

Comparison with Lambda:

  • No execution time limit (Lambda is 15 minutes)
  • Any runtime (Lambda has limited runtimes)
  • Uses EBS for storage (Lambda has limited scratch space; can use EFS if in VPC)
  • Batch using EC2 it is not serverless
  • Can use Fargate with Batch for serverless architecture
  • Lambda is serverless + you pay only for execution time
  • Can be more expensive.

Amazon EC2

Placement Groups

Cluster Placement Groups:

  • A cluster placement group is a logical grouping of instances within a single Availability Zone.
  • A cluster placement group can span peered VPCs in the same Region.
  • Instances in the same cluster placement group enjoy a higher per-flow throughput limit for TCP/IP traffic and are placed in the same high-bisection bandwidth segment of the network.
    Cluster placement groups are recommended for applications that benefit from low network latency, high network throughput, or both.
  • They are also recommended when the majority of the network traffic is between the instances in the group.

Network Adapters

An Elastic Fabric Adapter (EFA) is a network device that you can attach to your Amazon EC2 instance to accelerate High Performance Computing (HPC) and machine learning applications.

EFA enables you to achieve the application performance of an on-premises HPC cluster, with the scalability, flexibility, and elasticity provided by the AWS Cloud.

AWS Elastic Beanstalk

With AWS Elastic Beanstalk you can perform a blue/green deployment, where you deploy the new version to a separate environment, and then swap CNAMEs of the two environments to redirect traffic to the new version instantly.

Tuesday 23 March 2021

AWS vs GCP – Which one is the best?

There are several cloud providers around the world that we can choose the best one based an our application needs, It could be price,demand, traffic, technologies and our desire to always improve makes us select the best ones in the market. 

But who are they (AWS vs GCP vs Azure)? What are their benefits?

Well, based on Gartner’s Magic Quadrant for Cloud Infrastructure as a Service Worldwide we can see Amazon Web Services, Microsoft Azure and Google are the top 3 cloud infrastructure providers. They obviously haven’t been in the market at the same time, Google is the latest competitor to join.

What do they have in common? and How can we benefit from choosing our applications with them?

Amazon Web Services

Amazon Web Services was officially launched in 2006. It currently offers online services for websites, applications or any infrastructure.
In 2013 Amazon became a business with revenues of more than $ 7B in resale services with a 23.5% margin of operation, making AWS a business of 10B USD run rate business. They grow their services over 40% every year.

Why is Amazon a Good choice for any business?

Whether you are an e-commerce, blog, media site, marketing site, real estate website, Amazon can be a real game changer for your business. Its wide variety of services will enable you to evolve and reach the next level to offer new great things to your customers.

The advantages that the cloud offers to any business are quite profitable compared to traditional hosting, such as:
  • Pay as you go model.
  • Minimize time to market.
  • Agility to launch servers.
  • Forget about storage costs.
  • Agility in apps development.
  • Services entirely managed. 


Google Compute Engine                   
IaaS service is providing virtual machines, similar to Amazon EC2.
Google App Engine
PaaS service for directly hosting applications, similar to AWS Elastic Beanstalk
BigTable
IaaS service providing MapReduce services, similar to Hadoop.