Rolling With Additional Batch ignored during elastic beanstalk app update - amazon-elastic-beanstalk

We're using a bitbucket pipeline to deploy a NodeJS app to elastic beanstalk (eb).
We've configured the eb environment option "Rolling updates and deployments" to use "Rolling with additional batch" (RollingWithAdditionalBatch strategy).
This used to work fine up until about a year ago or so, since then (and updating the platform version to Node 14 then 16), the "rolling with additional batch" strategy is ignored on deployment. Eb seems to revert to a "rolling" strategy instead.
Bitbucket pipe version: atlassian/aws-elasticbeanstalk-deploy:1.0.2.
Eb config is as per attached screenshot.

Related

Using CodePipeline to Deploy ElasticBeanstalk application in another AWS account

We have a setup with different AWS accounts for each environment(dev, test, prod) and then a shared build account which has a AWS CodePipeline that deploys into each of these environment by assuming a role in dev, test, prod.
This works fine for our Serverless applications using a Codebuild script.
Can we do something similar for the Elastic Beanstalk application that uses the deploy action provider? Or what is the best approach for Elastic Beanstalk
We do this by using a CodeBuild job specified in each of the stage accounts (dev, test, prod) that uses the AWS CLI to deploy the CodePipeline artifact (available as CODEBUILD_SOURCE_VERSION in your build job's environment variables) to Elastic Beanstalk. We run this job as part of a CodePipeline in our shared build account.
These are the AWS CLI commands the CodeBuild deploy job runs:
aws elasticbeanstalk create-application-version --application-name ... --version-label ... --source-bundle S3Bucket="codepipeline-artifacts-us-east-1-123456789012",S3Key="application/deployable/XXXXXXX"
aws elasticbeanstalk update-environment --environment-name ... --version-label ...
You can specify a CodeBuild job from another account in CodePipeline using the strategy outlined here: https://docs.aws.amazon.com/codepipeline/latest/userguide/pipelines-create-cross-account.html. It involves setting up cross-account access to the role_arn used for the CodeBuild deploy job and a customer managed KMS key for the pipeline (with a cross-account access policy).
One deficiency with this approach is that the CodeBuild deploy job will complete as soon as the deployment starts and not wait until the ElasticBeanstalk deployment succeeds or fails, as the native CodePipeline EB deploy action does. You should be able to call aws elasticbeanstalk describe-environments in a loop from the job to replicate this behavior, but I have not yet attempted this. (Sample script here: https://blog.cyplo.net/posts/2018/04/wait-for-beanstalk/)
I have found the solution to cross account deployment of application to elastic beanstalk in another aws account using aws cdk.
As aws cdk do not have deploy to elastic beanstalk action feature yet so we have to implement it manually by implementing IAction interface
You can find complete working CDK app in my git repo
https://github.com/dhirajkhodade/CDKDotNetWebAppEbPipeline
We ended up solving it this way using CodeBuild:
version: 0.2
phases:
install:
runtime-versions:
python: 3.8
commands:
- pip install awsebcli --upgrade
pre_build:
commands:
- CRED=`aws sts assume-role --role-arn $assume_role --role-session-name codebuild-deployment-$environment`
- export AWS_ACCESS_KEY_ID=`node -pe 'JSON.parse(process.argv[1]).Credentials.AccessKeyId' "$CRED"`
- export AWS_SECRET_ACCESS_KEY=`node -pe 'JSON.parse(process.argv[1]).Credentials.SecretAccessKey' "$CRED"`
- export AWS_SESSION_TOKEN=`node -pe 'JSON.parse(process.argv[1]).Credentials.SessionToken' "$CRED"`
- export AWS_EXPIRATION=`node -pe 'JSON.parse(process.argv[1]).Credentials.Expiration' "$CRED"`
- echo $(aws sts get-caller-identity)
build:
commands:
- eb --version
- eb init <project-name> --platform "Node.js running on 64bit Amazon Linux" --region $AWS_DEFAULT_REGION
- eb deploy
Using the aws-cli to assume the role we needed and then using eb-cli to do the actual deployment. Not sure if this is the best way, but it works. We are considering moving to another CI/CD tool which is more flexi

Can I deploy automatically by AWS Elastic beanstalk and Code Commit?

I use Elastic Beanstalk. And it was connected with Code Commit.
I want that if I push to Code Commit repository, EB CLI or Code Commit automatically deploy this version to elasticbeanstalk
Can I do this?
You can create a script that periodically polls CodeCommit for new changes. When there is a new change, the script can trigger:
git clone <codecommit repository>
eb init -p <platform name>
eb create/eb deploy
of course, you probably don't need to clone every time, but this is basically how Jenkins works. In fact, you can just use Jenkins to poll CodeCommit. Any time there is a new commit detected, Jenkins will build it using the EBCLI.
CodePipeline
AWS CodePipeline is a continuous delivery service you can use to model, visualize, and automate the steps required to release your software. You can quickly model and configure the different stages of a software release process. AWS CodePipeline automates the steps required to release your software changes continuously.
https://docs.aws.amazon.com/codepipeline/latest/userguide/welcome.html
Configure a pipeline with CodePipeline. When GitHub or CodeCommit is configured as the source stage, every single commit will trigger your pipeline to execute. When Beanstalk is configured as a deploy stage, it will automatically deploy whatever new code is going through the pipeline.

Deploying Code and Managing configuration with Terraform

Just to give context:
I am planning to use Terraform to bring up new separate environments with ec2 machines, elb etc. and then maintaining configuration as well.
Doing that with terraform and using AWS provider sounds fairly simple.
Problem 1:
While launching those instances I want to install few packages etc. so that when Terraform launches the instances (servers) things/ apps should be up and running.
Assuming the above is up and running:
Problem 2:
How do I deploy new code on the servers in this environment launched by Terraform?
Should I use for eg. ansible playbooks/chef recipes/puppet manifests for that? or Terraform gives some other options/ways?
Brief answers:
Problem 1: While launching those instances I want to install few packages etc. so that when Terraform launches the instances (servers) things/ apps should be up and running.
A couple of options:
Create an AMI of your instance with the installed packages and specify that in the resource.
Use the user data script to install the packages that you need when the instance starts.
Use ansible playbooks/chef recipes/puppet to install packages once the instance is running (e.g. creating an opsworks stack with terraform)
Problem 2: How do I deploy new code on the servers in this environment
launched by Terraform? Should I use for eg. ansible playbooks/chef
recipes/puppet manifests for that? or Terraform gives some other
options/ways?
Not the intended use case for terraform, use other tools like jenkins or aws services like codepipeline or codedeploy. Ansible/chef/puppet can also help (e.g. with opsworks)

Elastic Beanstalk stops at EbExtensionPostBuild

I am having a problem deploying an EB instance with a custom .ebextensions file. This is the relevant part in that file:
container_commands:
01_migrate:
command: 'python db_migrate.py'
02_npm_build:
command: 'npm install && npm run prod'
As you can see, these commands are for migrating my PostgreSQL database (via a Flask backend) and building my React .jsx files.
If I leave these commands out, the deployment completes perfectly well. However, once I put them in, looking at the eb-activity.log it stalls at this part forever (as far as I can tell):
[2017-04-10T02:39:24.106Z] INFO [3023] - [Application deployment app-613e-170409_223418#1/StartupStage0/EbExtensionPostBuild] : Starting activity...
I also get this message on the Health overview in the console (this is after 1 day):
Performing application deployment (running for 1 day).
I have also tried to deploy it without those container_commands, and then including it back after the successful initial deployment. Then I get the same error message as before in eb-activity.log, and I also get this message on the Health overview:
Incorrect application version "app-2a3d-170409_214923" (deployment 1). Expected version "app-2a3d-170409_214923" (deployment 1).
Which is very strange because those two versions referenced are the same versions. I don't know what this means!
I found a solution.
Remove all you container_commands from .ebextensions/
Go ssh to instance, kill process with.
sudo killall python
Then Deploy new version without container_commands.
And start debuging all your container_commands, one by one on ssh..
Have fun.

How do I choose an artifact from Nexus in a Hudson / Jenkins job?

I have a job in Hudson server A which builds an artifact and deploys it to Nexus. I have another job in a completely separate Hudson server B which needs to download the artifact and deploy it. This job is normally run manually, and the person running it needs to indicate which version of the artifact to deploy - they may not always want to deploy the latest version (e.g. to roll back to a previous known good version).
Currently, I achieve this by using a parameterized build, and require the user to pass in the artifact version number; the job then uses the Execute shell build step to run wget on a URL constructed using the parameter. This is error prone.
Ideally I'd like a plugin that lets the user browse the artifact versions in the Nexus repository and pick and choose the one to deploy, but I'm open to other suggestions. A plugin that also handles the download would be nice, but I can live without it as long as I can still get a string that I can use in shell commands.
I've looked through the available Hudson & Jenkins plugins around Maven style artifact repositories, but they all seem more concerned with pushing artifacts into repos rather than getting them back down.
I'm using Hudson's "Copy Artifact" in other jobs, to get artifacts from other Hudson jobs on the same server, but this doesn't work across different Hudson servers, which is why I've turned to Nexus (which we're already using anyway).
Does anyone have any suggestions?
I recommend using rundeck to execute your deployments.
There is a rundeck plugin for Nexus that enables rundeck to display a pull down menu of available versions in Nexus.
There is a rundeck plugin for Jenkins that can be used to invoke deployments using rundeck and kick-off post deployment jobs (like integration testing) inn Jenkins.