I'm running an application on elastic beanstalk.
How do I find my application name? in other words, how does the application runnning in elastic beanstalk find out information about itself.
or other information about the environment the that the current application is runnning in.
I wouldn't be surprised if some of this information is available via system properties.
UPDATE: something I forgot to mention (sorry). It's java app and I'd prefer to use the JAVA SDK to acquire this information
An alternative, and rather nasty have to find the name of the environment is to check the root folder of the Elastic Beanstalk instance. As of today, there is a file there named /<aws-env-name>_LaunchFile in the root folder of the EC2 instance (caveat emptor: this can change at any time).
For example, if you environment name is "mycoolapp-dev" then there will be a file called mycoolapp-dev_LaunchFile in the root directory of your Elastic Beanstalk Instance. For things like loggly and newrelic to work correctly, sometimes it's useful to give your host a proper hostname (both services still record the IP, which is the original EC2 IP).
The command snippet below can be pasted into your .ebextensions folder .config file to set the hostname to mycoolapp-dev for these services to work.
commands:
00_set_hostname:
command: "hostname `ls /*_LaunchFile | sed -e 's/\/\(.*\)_LaunchFile$/\1/'`"
Or a really nice solution is to use this link by Steel Pangolin - Jeremy Ehrhardt
You can query Metadata about the instance by navigating from the instance to this internal address:
http://169.254.169.254/latest/meta-data/
There are many different methods you can use to query and parse the results of this data for your purposes.
See more information about Instance Metadata and Userdata here.
Related
I'm trying to locate the staging directory as mentioned in the Elastic Beanstalk documentation.
The specified commands run as the root user, and are processed in alphabetical order by name. Container commands are run from the staging directory, where your source code is extracted prior to being deployed to the application server. Any changes you make to your source code in the staging directory with a container command will be included when the source is deployed to its final location.
For anyone else who ends up here, this worked for me:
/opt/elasticbeanstalk/bin/get-config platformconfig -k AppStagingDir
Amazon's documentation actually provides that exact command on this page (you have to expand the platformconfig – Constant configuration values section to see it).
The staging directory is in /var/app/ondeck. Or at least this is the case on their managed platform Puma with Ruby 2.5 running on 64bit Amazon Linux/2.11.0.
To check your own SSH into your Beanstalk instance and do:
/opt/elasticbeanstalk/lib/ruby/bin/get-config container -k app_staging_dir
You can also create a script in .ebextensions/ and issue a command that will be something like:
echo "We are here: $(pwd)"
You'll then be able to check eb-activity.log for that line.
We have some docker images we build with sbt-native-packager that need to interact with AWS services. When running them outside of AWS, we need to explicitly provide credentials.
I know we can explicitly pass environment variables containing the AWS credentials. Doing this complicates keeping our credentials secret. One option is to provide them via the command line, typically storing them into our shell history (yes I know this can be avoided by adding a space to the start of the command, but that is easy to forget) and putting them at higher risk of accidental copy/paste sharing. Alternatively, we can provide them via an env-file. But this exposes us to possibly checking them into version control or pushing them to another server unintentionally.
We've found that the ideal practice is to mount our local ~/.aws/ directory into the running user's home directory for the docker container. However, our attempts at getting this to work with the sbt-native-packager images have been unsuccessful.
One unique detail for sbt-native-packager images (compared to our others) is they are build using docker's ENTRYPOINT instead of CMD to start the application. I don't know if this has bearing on the problem.
So the question: Is it possible to provide AWS credentials to a docker container created by sbt-native-packager by mounting the AWS credentials folder via command line parameters at startup?
The problem I was running into was related to permissions. The .aws files have very restricted access on my machine, and the default user within the sbt-native-packager image is daemon. This user does not have access to read my files when mounted into the container.
I am able to obtain the behavior I desire by adding the following flags to my docker run command: -v ~/.aws/:/root/.aws/ --user=root
I was able to discover this by using the --entrypoint=ash flag when running to look at the HOME environment variable (location to mount the /.aws/ folder) and attempting to cat the contents of mounted folder.
Now I just need to understand what security vulnerabilities I'm opening myself up to by running docker containers in this way.
I'm not entirely sure why mounting ~/.aws would be a problem - typically it could be related to read permissions on that directory and the different UID between the host system and the container.
That said, I can suggest a couple of workarounds:
Use an environment variable file instead of explicitly specifying them in the command line. In docuer run, you can do this by specifying --env-file. To me this sounds like the most simple approach.
Mount a different credentials file and provide the AWS_CONFIG_FILE environment variable to specify it's location.
I am using .git to deploy eb (PHP), and in the root folder, I've created folder .ebextensions and a file options.config with content
config_options:
aws:elasticbeanstalk:container:php:phpini:
document_root: /laravel/public
However, in the /var/log/eb-activity.log and I find the document_root is never being set
++ export PHP_DOCUMENT_ROOT=
++ PHP_DOCUMENT_ROOT=
In the S3 package I find the .ebextensions is bundled, so what can I do to debug this?
The docs state using option_settings rather than config_options (node.js, python and ruby examples use it, however the PHP specific example is for config_options)
option_settings:
- namespace: 'aws:elasticbeanstalk:container:php:phpini':
option_name: document_root
value: /laravel/public
or shorthand YAML as you are using
option_settings:
aws:elasticbeanstalk:container:php:phpini:
document_root: /laravel/public
http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/ebextensions-optionsettings.html
Also a simple thing but is the .ebextensions folder in the source root and the options.config in the .ebextensions folder? http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/ebextensions.html
This is an old issue (the link) but as it is said in this link:
Having said that, we were concerned when a number of our customers
began reporting issues with setting the Document Root environment
configuration. Many of these environments were inexplicably "going
red" and failing to update correctly under certain conditions. After
some digging, we discovered that while the configuration settings were
being written correctly during a configuration update, they weren't
being written correctly when a new instance was launched (via Auto
Scaling, the AWS Toolkit for Eclipse, or otherwise).
I think your problem is not the configuration, but may be the AMI you are using, which AMI is it? The updated AMI version is:
Amazon Linux 2012.03
Could you please verify your AMI version? Maybe you are using an old custom one?
EDIT
Also in this link, it says there is a document root configuration in the AWS EB PHP console:
To access the configuration options for your PHP environment
1) Open the Elastic Beanstalk console.
2) Navigate to the management console for your environment.
3) Choose Configuration.
4) In the Software Configuration section, choose Edit.
PHP Settings
Document root – The folder that contains your site's default page. If
your welcome page is not at the root of your source bundle, specify
the folder that contains it relative to the root path. For example,
/public if the welcome page is in a folder named public.
Maybe you can configure it from the dashboard?
While trying to setup an elastic beanstalk worker application using the command line tools (eb tools), my configuration file (optionsettings.MyApp-env) gets overwritten when I start/update/stop the environment.
These are the steps to reproduce:
Using the CLI tools' command eb init I've created a new application in Elastic Beanstalk.
The config file in the .elasticbeanstalk folder had the following line:
OptionSettingFile=/Users/doron/projects/workers/my-worker/.elasticbeanstalk/optionsettings.MyWorkerName-dev
After running eb start for the first time, that file was created with some values.
I went ahead and changed its contents according to http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/command-options.html so it'll be configured as I want (environment parameters, autoscaling servers amount, etc...).
To apply the changes I've tried the following:
Update the existing environment with eb update.
Terminate the existing environment with eb stop and build it from scratch with eb start.
In both cases the optionsettings file get changed after running the command (update or start).
The new content of the file looks more like the vanilla version I got after calling the first eb start with all sorts of configuration parameters that I added - removed completely.
Is there another way of configuring the environment (not the software on the machine, but the configuration that exists in the console - instance type, regions, autoscaling, rotating updates, etc...) ?
I realise that this is an old thread but in case anyone comes across this, as I did, then check out this thread on the AWS forums for Elasticbeanstalk https://forums.aws.amazon.com/thread.jspa?messageID=395052#395052
It explains how settings set in the .elasticbeanstalk/optionsettings. file are set using the API in such a way that they can't be changed later, unlike those set in the .ebextensions/*.config files.
Also, in an incredibly annoying move, the optionsettings file will often set some settings in it which you want to set in the .config file however it automatically re-creates the optionsettings file when running eb start and there's very little that seems possible. This makes using the eb command line tools close to impossible to use if you want to change something like the WSGIPath.
I found fragmented instructions here and some other places about deploying Play2 app on amazon ec2. But did not find any neat way to deploy using Beanstalk.
Play is a nice framework and AWS beanstalk is one of the most popular services then why is there no official instruction to do this?
Has anyone found any better solution?
Deploying a Play2 app on elastic beanstalk is now easy with Docker Containers in combination with sbt's experimental docker feature.
In build.sbt specify the exposed docker ports:
dockerExposedPorts in Docker := Seq(9000)
You should automate the following steps, but you can try this out manually to test that it works:
Generate a Dockerfile for the project by running the command: sbt docker:stage.
Go to the ./target/docker/ directory.
Create an elastic beanstalk Dockerrun.aws.json file with the following contents:
{
"AWSEBDockerrunVersion": "1",
"Ports": [
{
"ContainerPort": "9000"
}
]
}
Zip up everything in that directory, let's say into a file called play2-test-docker.zip. The zip file should contain the files: Dockerfile, Dockerrun.aws.json, and files/* directory.
Go to aws beanstalk console and create a new application using the m3.medium or any instance type with enough memory for the jvm to run. Any instance with too little memory will result in a JVM error.
Select "Docker Container" in the Predefined Configuration dropdown.
In the application selection screen, select "Upload" and select the zip file you created earlier. Launch the app and then go brew some tea. This can take a very long time. Minutes. Subsequent deployments of the same app version should be slightly quicker.
Once the app is running and green in the aws console, click on the app's url and you should see the welcome screen of the application (or whatever your index file is).
Here's my solution that doesn't require any additional services/containers like Docker or Jenkins.
Create a dist folder in the root of your Play application's directory. Create a Procfile file containing the following contents and put it in the dist folder (EB requires port 5000):
web: ./bin/YOUR_APP_FILE_NAME -Dhttp.port=5000 -Dconfig.file=conf/application.conf
The YOUR_APP_FILE_NAME is the name of the executable in the bin directory, which is inside the .zip created by activator dist.
After running activator dist, you can just upload the created zip file into Elastic Beanstalk and it will automatically deploy the app. You also put whatever .ebextension folders and configuration files into the dist folder that you require for Elastic Beanstalk configuration. Ex. I have dist/.ebextensions/nginx/conf.d/proxy.conf for NGINX reverse proxy settings or dist/.ebextensions/env.config for environment variables.
Edit 2016: There's now a much better way to deploy your Playframework apps onto ElasticBeanstalk using the new Java SE containers.
Here's an article that walks you through deploying step by step using Jenkins to build and deploy your project:
https://www.davemaple.com/articles/deploy-playframework-elastic-beanstalk-jenkins/
You can use custom AMIs that I keep updated here:
https://github.com/davemaple/playframework-nginx-elastic-beanstalk
These run Nginx + Playframework and support standard zip files created using "activator dist".
We also saw this as being too much of a pain and have added native Play 2 support to Boxfuse to address this.
You can now simply do boxfuse run my-play-app-1.0.zip -env=prod and this will automatically:
create a minimal AMI tailor-made for your Play 2 app
create an elastic IP
create a security group with the correct permissions
launch an instance of your app
All future updates are performed as blue/green deployments with zero downtime.
This also works with Elastic Load Balancers and Auto-Scaling Groups and the Boxfuse free tier is designed to fit the AWS free tier.
You can read more about it here: https://boxfuse.com/blog/playframework-aws
Disclaimer: I'm the founder and CEO of Boxfuse
I had some problems with other solutions found here and there. I guess that the problem is that I'm developing on Play 2.4.
Anyway, I could deploy the app to Beanstalk using Typesafe Activator and Docker:
In build.sbt I added this lines:
import com.typesafe.sbt.packager.docker.{ExecCmd, Cmd}
// [...]
dockerCommands := Seq(
Cmd("FROM","java:openjdk-8-jre"),
Cmd("MAINTAINER","myname"),
Cmd("EXPOSE","9000"),
Cmd("ADD","stage /"),
Cmd("WORKDIR","/opt/docker"),
Cmd("RUN","[\"chown\", \"-R\", \"daemon\", \".\"]"),
Cmd("RUN","[\"chmod\", \"+x\", \"bin/myapp\"]"),
Cmd("USER","daemon"),
Cmd("ENTRYPOINT","[\"bin/myapp\", \"-J-Xms128m\", \"-J-Xmx512m\", \"-J-server\"]"),
ExecCmd("CMD")
)
I went to the project's directory and ran this command in the terminal
$ ./activator clean docker:stage
I opened the [project]/target/dockerdirectory and created the file Dockerrun.aws.json. This was its content:
{
"AWSEBDockerrunVersion": "1",
"Ports": [
{
"ContainerPort": "9000"
}
]
}
In the same target/docker directory, I tested the result, built, checked and ran the image:
$ docker build -t myapp .
$ docker images
$ docker run -p 9000:9000 myapp
As everything was ok, I zipped the content:
$ zip -r myapp.zip *
My zip file had Dockerfile, Dockerrun.aws.json and stage/* files
Finally, I created a new Beanstalk app and uploaded the zip created on the last step. I took care of select "Generic Docker" on "Predefined configuration", when I was creating the app.
Beanstalk only supports WAR deployment and Play doesn't officially support WAR deployment. If you want to use EC2 then you should instead just create an EC2 instance and follow the deployment instructions: http://www.playframework.com/documentation/2.2.x/ProductionDist
Deploying play 2.* apps in aws ec2 is very diffrent until you have found this much better way to do it. I mean ansible is promising a great solution to that. though it is still needed to work with new setup of ansible, and its playbook but that must be worthy.
I have found these reads very recently and yet to apply them in my project. I hope following reads will help you to learn more:
Ansible + play + aws ec2
Read it to know more about Ansible to deply play in aws
Thanks!
Hope this will help you to kick your start. Please do share more knowledge you gain during the procedure or if there is any simple way to solve this complicated deployment problem.