Elastic BeanStalk app deploy post hook not executing my command - amazon-web-services

I recently was able to get my Laravel app deployed using codepipeline on Elastic Beanstalk but ran into a problem. I noticed that my routes where failing because of php.conf Nginx configuration. I had to add a few lines of code to EB's nginx php.conf file to get it to work.
My problem now was that after every deployment, the instance of the application I modified the php.conf file was destroyed and recreated fresh. I wanted a way to dynamically update the file after every successful deployment. I had a version of the file I wanted versioned with my application and so wanted to create a symlink to that file after deployment.
After loads of research, I stumbled on appDeploy Hooks on Elastic Beanstalk that runs post scripts after deployment so did this
files:
"/opt/elasticbeanstalk/hooks/appdeploy/post/91_post_deploy_script.sh":
mode: "000755"
owner: root
group: root
content: |
#!/usr/bin/env bash
sudo mkdir /var/testing1
sudo ln -sfn /var/www/html/php.conf.example /etc/nginx/conf.d/elasticbeanstalk/php.conf
sudo mkdir /var/testing
sudo nginx -s reload
And this for some reason does not work. The symlink is not created so my routes are still not working..
I even added some mkdir so am sure the commands in that script runs, none of those commands ran because none of those directories where created.
Please note that if I ssh into the ec2 instance and run the commands there it works. That bash script also exists in the post directory and if I manually run in on the server it works too.
Any pointers to how I could fix this would be helpful. Maybe I am doing something wrong too.
Now I have gotten my scripts to run by following this. However, the script is not running. I am getting an error
2020/06/28 08:22:13.653339 [INFO] Following platform hooks will be executed in order: [01_myconf.config]
2020/06/28 08:22:13.653344 [INFO] Running platform hook: .platform/hooks/postdeploy/01_myconf.config
2020/06/28 08:22:13.653516 [ERROR] An error occurred during execution of command [app-deploy] - [RunPostDeployHooks]. Stop running the command. Error: Command .platform/hooks/postdeploy/01_myconf.config failed with error fork/exec .platform/hooks/postdeploy/01_myconf.config: permission denied
I tried to follow this forum post here to make my file executable by adding to my container command a new command like so:
01_chmod1:
command: "chmod +x .platform/hooks/postdeploy/91_post_deploy_script.sh"
I am still running into the same issue. Permission denied

Sadly, the hooks you are describing (i.e. /opt/elasticbeanstalk/hooks/appdeploy) are for Amazon Linux 1.
Since you are using Amazon Linux 2, as clarified in the comments, the hooks you are trying to use do not apply. Thus they are not being executed.
In Amazon Linux 2, there are new hooks as described here and they are:
prebuild – Files here run after the Elastic Beanstalk platform engine downloads and extracts the application source bundle, and before it sets up and configures the application and web server.
predeploy – Files here run after the Elastic Beanstalk platform engine sets up and configures the application and web server, and before it deploys them to their final runtime location.
postdeploy – Files here run after the Elastic Beanstalk platform engine deploys the application and proxy server.
The use of these new hooks is different than in Amazon Linux 1. Thus you have to either move back to Amazon Linux 1 or migrate your application to Amazon Linux 2.
General migration steps from Amazon Linux 1 to Amazon Linux 2 in EB are described here

Create a folder called .platform in your project root folder and create a file with name 00_myconf.config inside the .platform folder.
.platform/
00_myconf.config
Open 00_myconf.config and add the scripts
files:
"/opt/elasticbeanstalk/hooks/appdeploy/post/91_post_deploy_script.sh":
mode: "000755"
owner: root
group: root
content: |
#!/usr/bin/env bash
sudo mkdir /var/testing1
sudo ln -sfn /var/www/html/php.conf.example /etc/nginx/conf.d/elasticbeanstalk/php.conf
sudo mkdir /var/testing
sudo nginx -s reload
Commit your changes or reupload the project. This .platform folder will be considered in each new instance creation and your application will deploy properly in all the new instances Amazon Elastic beanstalk creates.

If you access the documentation here and scroll to the section with the title "Application example with extensions" you can see an example of the folder structure of your .platform folder so it adds your custom configuration to NGINX conf on every deploy.
You can either replace the entire nginx.conf file with your file or add additional configuration files to the conf.d directory
Replace conf file with your file on app deploy:
.platform/nginx/nginx.conf
Add configuration files to nginx.conf:
.platform/nginx/conf.d/custom.conf

Related

AWS Elastic Beanstalk doesn't find .platform/hooks/postdeploy directory

I am deploying a spring boot war to a single instance AWS Elastic Beanstalk environment and trying to run a postdeploy script.
I have successfully had .ebextension scripts executed and attempted to follow the same pattern for the .platform/hooks/postdeploy directory but unfortunately EB isn't able to find the directory.
I get the following in the eb-engine.log:
[INFO] Executing platform hooks in .platform/hooks/postdeploy/
[INFO] The dir .platform/hooks/postdeploy/ does not exist
[INFO] Finished running scripts in /var/app/current/.platform/hooks/postdeploy
[INFO] Executing cleanup logic
I have verified the directory and script are placed inside the WAR file under /WEB-INF/classes:
Directory structure under .platform is .platform/hooks/postdeploy/myscript.sh
The EB environment is an Amazon Linux 2.
Any ideas why EB can't find the .platform/hooks/postdeploy directory? When I cd in /var/app I see a jar file and a Procfile.
In my case, I spent one entire week wondering why my configs are not correctly detected..
As mentioned here the .platform correct path is {project_root_directory}/.platform/ and thought I was doing everything fine.
But it need to look like this into your archive ! The root of the zip must have the .platform into
In my case it was : foobar.zip/{project_root_directory}/.platform/
But it must be :foobar.zip/.platform/

AWS Beanstalk couldn't create nginx config file at the deployment automatically

I have created a Django API application that is deployed on AWS Beanstalk Amazon Linux 2 (Python 3.8). In a part of my application, the user should be able to upload a file through API.
Nginx, on default, is returning CORS error to the user when the uploaded file is bigger than 3 MB and logging 'user tries to upload huge file' in the Nginx log.
The only solution which works for me is creating the bellow configuration file and reloading the Nginx:
/etc/nginx/conf.d/proxy.conf:
client_max_body_size 50M;
and then:
sudo service nginx reload
I have done this procedure manually by connecting to the EC2 which is the host of my beanstalk application via SSH. I want to automate this procedure to be done at every deployment and every instance.
I have created a file called nginx_max_upload.config file in .ebextensions folder which is located in the root of my project:
nginx_max_upload.config:
files:
/etc/nginx/conf.d/proxy.conf:
mode: "000755"
owner: root
group: root
content: |
client_max_body_size 50M
commands:
reload_nginx:
command: "sudo service nginx reload"
ignoreErrors: true
My problem is, the above code didn't create the file I want in the specified directory. When I changed the directory to another directory like /usr/local/bin/proxy.conf, the file would be successfully created but it can't create the config file in the Nginx configuration folder.
I guess the problem might be from the permissions but I don't know how to grant the needed permission to the deployment agent.
Also, I have tried these two solutions but none of them works:
I have tried to create the config file in another folder and then, move it via mv command to the right directory but it didn't work.
Also, I have tried to put the creation code in the predeply hook and put manual echo commands in my code. I saw all of my echo commands output in the beanstalk logs but it didn't do anything (nor creating the file in the nginx configuration neither moving it from somewhere else to the configuration folder).
Since you are using Amazon Linux 2 (AL2), your configuration files are incorrect. They used to work in AL1, but for AL2, they are in different place and have different format as shown in the docs.
Thus could have the following .platform/nginx/conf.d/myconfig.conf (not in .ebextensions) with content:
client_max_body_size 50M;

Elastic Beanstalk - .ebextensions not running on deploy

I have a dotnet core application. And I'm packed it for docker.
My aim is deploying this application to EB but I need to run some commands after deploy.
Thats why I have created a Dockerfile
# https://hub.docker.com/_/microsoft-dotnet-core
FROM mcr.microsoft.com/dotnet/core/sdk:2.2
WORKDIR /
# copy csproj and restore as distinct layers
COPY . ./App/
WORKDIR /App/WebApi
RUN dotnet restore
RUN dotnet publish -c release -o /build --no-restore
WORKDIR /build
ENV ASPNETCORE_URLS=http://+:8080
EXPOSE 8080
ENTRYPOINT ["dotnet", "WebApi.dll"]
And I have a Dockerrun.aws.json
{
"AWSEBDockerrunVersion": "1"
}
And finally this is my .ebextensions/01_nginx.conf
commands:
test_command:
command: "touch /tmp/x.f"
Then I'm creating an EB application
$ eb init
and creating an enviorment
$eb create
It is deploying my application successfully.
What is expected?
When I login to my EC2 container with ssh I want to see the /tmp/x.f file.
What is the problem?
I have tried several ways, I'm sure that .ebextensions/01_nginx.conf not running any way, because /tmp/x.f file not exists.
Notes :
I'm sure that the zip file which is deployed has .ebextensions/01_nginx.conf file
I'm sure that it is not about git. Because I'm including .ebignore in my root directory.
I can react the end point without any problem, my application is deploying successfully.
What is my mistake?
A probable reason is wrong extension of your files in .ebextensions. It should be .config, not .conf:
Configuration files are YAML- or JSON-formatted documents with a .config file extension that you place in a folder named .ebextensions and deploy in your application source bundle.

How to create folder on Elastic Beanstalk server to install LetsEncrypt SSL certificate with AcmePHP

I have a site running on an Elastic Beanstalk single instance server and want to add automated SSL certificate generation from LetsEncrypt using the AcmePHP library.
The library tries to store the certificates in ~/.acmephp, which the server responds to with an error
Failed to create "/home/webapp/.acmephp": mkdir(): Permission denied.
The acmephp library doesn't have an option to change the path built in, and rather than fork and recompile the script, I'd like to be able to store the files in the default directory.
Does anyone know how I can give the app permission to create this directory, outside of the web root, or how I can make the server create it automatically and have it be available to the app?
It looks like since it's being ran by the webapp user, when acmePHP is trying to store the certificate under that user's home directory it fails because that directory doesn't exist (afaik the webapp user only runs httpd and it definitely doesn't have a home directory).
A very dirty workaround could be manually creating that file and folder in the . ebextensions folder in your project.The file would be .ebextensions/create_home.config and it would contain something like this:
files:
"/tmp/create-home.sh" :
mode: "000755"
content: |
#!/usr/bin/env bash
mkdir -p /home/webapp
chown webapp:webapp -R /home/webapp
commands:
01_create:
command: "/tmp/create-home.sh"
That script is ran by the root user, and afterwards it changes ownership of the /home/webapp folder to the webapp user and group respectively. Hope it helps

Elastic Beanstalk Procfile for go

I'm trying to deploy my go restful server program to EC2 Linux using Elastic Beanstalk. The document says that I need to create a Procfile at the root. So I did. Here are the steps:
Build my go program myapp.go to using
$ go build -o myapp -i myapp.go
Create a Procfile with exact name at the root with
web: myapp
Zip up the Procfile and the myapp image to a myapp.zip file.
Upload to the server via Elastic Beanstalk console. But I keep getting Degraded health and warning with
WARN Process termination taking longer than 10 seconds.
Any suggestions. By the way, I tried to use the same procfile procedure on the simple application.go zip file came from the Elastic Beanstalk example library. It didn't work either.
I was finally able to get a Go application to deploy with Elastic Beanstalk using the eb client. There are a few things that EB requires:
The name of your main file should be application.go.
Make sure your app is listening on port 5000.
You'll need a Procfile in the main root with
web: bin/application
You'll need a Buildfile with
make: ./build.sh
And finally you'll need a build.sh file with
#!/usr/bin/env bash
# Stops the process if something fails
set -xe
# All of the dependencies needed/fetched for your project.
# FOR EXAMPLE:
go get "github.com/gin-gonic/gin"
# create the application binary that eb uses
GOOS=linux GOARCH=amd64 go build -o bin/application -ldflags="-s -w"
Then if you run eb deploy (after creating your initial eb repository), it should work. I wrote a whole tutorial for deploying a Gin application on EB here. The section specifically on deploying with Elastic Beanstalk is here.