AWS ElasticBeanstalk: Tips and Tricks
AWS-ElasticBeanstalk — PaaS on the infrastructure of AWS. In my opinion a significant advantage of this service is the ability to directly access elements of the infrastructure (load balancers, instances, queues, etc.) In this article I decided to gather some tricks that solve common problems when using ElasticBeanstalk. Will complement as you acquire more. Questions and suggestions in the comments are welcome.

the
In my opinion an obvious disadvantage of the platform is vague storage engine configuration. So I used the following methods to add a configuration.
The most obvious and native to ElasticBeanstalk — set via environment variables. Inside these instance variables are not available as usual, but only in the environment of the application. For these settings the most convenient to use the command eb setenv from a batch awsebcli that is used to deploy the application (suitable for small projects) or AWS APIs.
the
The second option is when the config will injected inside created application version. For this we need to explain how to be deployed. Manually or by a script, create a zip archive containing application code is laid out on a special S3 bucket unique to each region ( elasticbeanstalk-<region_name>-<my_account_id> — do not attempt to use the other will not work — tested). You can create this package manually, or edit software. I prefer to use an alternative deployment option, when instead awsebcli used custom code to create the package version.

The third option — uploading configuration remotely to the deployment phase of the external database configuration. IMHO the most correct approach, but beyond the scope of this article. I use a scheme with the storage configuration on S3 and proxy requests to S3 through the API Gateway — this allows the most flexibility to manage configs. S3 also supports versioning.
the
ElasticBeanstalk supports the creation of jobs for the scheduler using cron.yaml. However, this config only works for worker environment — the configuration used to process a queue of tasks / periodic tasks. For this task, surrounded by a WebServer added to the project directory .ebextensions file with the following content:
the
the
Added to the config file to .ebextensions:
the
Similarly apply alembic migration; in order to avoid the use of migrations for each instance autoscaling group, you specify the parameter leader_only
the
Creating scripts in the directory /opt/elasticbeanstalk/hooks/, it is possible to add various control scripts, in particular, to modify the deployment process of the application. Scripts that are executed before deployment, are in the directory /opt/elasticbeanstalk/hooks/appdeploy/pre/*, while in /opt/elasticbeanstalk/hooks/appdeploy/enact/*, and /opt/elasticbeanstalk/hooks/appdeploy/post/*. Scripts are executed in alphabetical order so you can build the correct sequence of deployed applications.
the
the
By the way, I used an experimental option to take as the broker for Celery SQS and it is quite justified; however, flower does not yet have support for such schemes.
the
Here is a Supplement to the ElasticBeanstalk configuration inside Apache
the
the
Amazon provides an opportunity for registrants to use free SSL certificates, including wildcard, but only within the AWS. To use multiple domains with SSL on one environment get the certificate using the AWS Certificate Manager to add the ELB balancer and SSL configured on it. Can be used and obtained from another vendor's certificates.

UPDATE Below the comments dear darken99 gave a couple of useful chips will add them here with some explanations
turn Off environment schedule
In this case, depending on the specified time range the number of instances in the autoscaling group is reduced from 1 to 0.
the
Replacing Apache for Nginx
the doesn't work for Python
Article based on information from habrahabr.ru

the
adding application configuration
In my opinion an obvious disadvantage of the platform is vague storage engine configuration. So I used the following methods to add a configuration.
The most obvious and native to ElasticBeanstalk — set via environment variables. Inside these instance variables are not available as usual, but only in the environment of the application. For these settings the most convenient to use the command eb setenv from a batch awsebcli that is used to deploy the application (suitable for small projects) or AWS APIs.
the
eb setenv RDS_PORT=5432 PYTHONPATH=/opt/python/current/app/myapp:$PYTHONPATH RDS_PASSWORD=12345 DJANGO_SETTINGS_MODULE=myapp.settings RDS_USERNAME=dbuser RDS_DB_NAME=appdb RDS_HOSTNAME=dbcluster.us-east-1.rds.amazonaws.com
The second option is when the config will injected inside created application version. For this we need to explain how to be deployed. Manually or by a script, create a zip archive containing application code is laid out on a special S3 bucket unique to each region ( elasticbeanstalk-<region_name>-<my_account_id> — do not attempt to use the other will not work — tested). You can create this package manually, or edit software. I prefer to use an alternative deployment option, when instead awsebcli used custom code to create the package version.

The third option — uploading configuration remotely to the deployment phase of the external database configuration. IMHO the most correct approach, but beyond the scope of this article. I use a scheme with the storage configuration on S3 and proxy requests to S3 through the API Gateway — this allows the most flexibility to manage configs. S3 also supports versioning.
the
Included tasks in crontab
ElasticBeanstalk supports the creation of jobs for the scheduler using cron.yaml. However, this config only works for worker environment — the configuration used to process a queue of tasks / periodic tasks. For this task, surrounded by a WebServer added to the project directory .ebextensions file with the following content:
the
files:
"/etc/cron.d/cron_job":
mode: "000644"
owner: root
group: root
content: |
#Add comands below
15 10 * * * root curl www.google.com >/dev/null 2>&1<code>
"/usr/local/bin/cron_job.sh":
mode: "000755"
owner: root
group: root
content: |
#!/bin/bash
/usr/local/bin/test_cron.sh || exit
echo "running Cron at" `date` >> /tmp/cron_job.log
# Now do tasks that should only run on 1 instance ...
"/usr/local/bin/test_cron.sh":
mode: "000755"
owner: root
group: root
content: |
#!/bin/bash
METADATA=/opt/aws/bin/ec2-metadata
INSTANCE_ID=`$METADATA -i | awk '{print $2}"
REGION=`$METADATA-z | awk '{print substr($2, 0, length($2)-1)}"
# Find our Auto Scaling Group name.
ASG=`aws ec2 describe-tags --filters "Name=resource-id,Values=$INSTANCE_ID" \
--region $REGION --output text | awk '/aws:autoscaling:groupName/ {print $5}"
# Find the first instance in the Group
FIRST=`aws autoscaling describe-auto-scaling-groups --auto-scaling-group-names $ASG \
--region $REGION --output text | awk '/InService$/ {print $4}' | sort | head -1`
# Test if they're the same.
[ "$FIRST" = "$INSTANCE_ID" ]
commands:
rm_old_cron:
command: "rm *.bak"
cwd: "/etc/cron.d"
ignoreErrors: true
the
the Automatic application of migrations to Django and build of static when you deploy
Added to the config file to .ebextensions:
the
container_commands:
01_migrate:
command: "python manage.py migrate --noinput"
leader_only: true
02_collectstatic:
command: "./manage.py collectstatic --noinput"
Similarly apply alembic migration; in order to avoid the use of migrations for each instance autoscaling group, you specify the parameter leader_only
the
Using hooks when deploying applications
Creating scripts in the directory /opt/elasticbeanstalk/hooks/, it is possible to add various control scripts, in particular, to modify the deployment process of the application. Scripts that are executed before deployment, are in the directory /opt/elasticbeanstalk/hooks/appdeploy/pre/*, while in /opt/elasticbeanstalk/hooks/appdeploy/enact/*, and /opt/elasticbeanstalk/hooks/appdeploy/post/*. Scripts are executed in alphabetical order so you can build the correct sequence of deployed applications.
the
adding the Celery daemon in the existing config supervisor
the
files:
"/opt/elasticbeanstalk/hooks/appdeploy/post/run_supervised_celeryd.sh":
mode: "000755"
owner: root
group: root
content: |
#!/usr/bin/env bash
# Get the django environment variables
celeryenv=`cat /opt/python/current/env | tr '\n' ',' | sed 's/export //g' | sed 's/$PATH/%(ENV_PATH)s/g' | sed 's/$PYTHONPATH//g' | sed 's/$LD_LIBRARY_PATH//g"
celeryenv=${celeryenv%?}
# Create celery configuraiton script
celeryconf="[program:celeryd]
; Set full path to celery program if using virtualenv
command=/opt/python/run/venv/bin/celery worker -A yourapp -B --loglevel=INFO -s /tmp/celerybeat-schedule
directory=/opt/python/current/app
user=nobody
numprocs=1
stdout_logfile=/var/log/celery-worker.log
stderr_logfile=/var/log/celery-worker.log
autostart=true
autorestart=true
startsecs=10
; Need to wait for currently executing tasks to finish at shutdown.
; Increase this if you have very long running tasks.
stopwaitsecs = 600
; When resorting to send SIGKILL to the program to terminate it
; send SIGKILL to its whole process group instead,
; taking care of its children as well.
killasgroup=true
; if rabbitmq is supervised, set its priority higher
; so it starts first
priority=998
environment=$celeryenv"
# Create the celery supervisord conf script
echo "$celeryconf" | tee /opt/python/etc/celery.conf
# Add configuration script to supervisord conf (if not there already)
if ! grep -Fxq "[include]" /opt/python/etc/supervisord.conf
then
echo "[include]" | tee-a /opt/python/etc/supervisord.conf
echo "files: celery.conf" | tee-a /opt/python/etc/supervisord.conf
fi
# Reread the supervisord config
supervisorctl -c /opt/python/etc/supervisord.conf reread
# Update cache in supervisord without restarting all services
supervisorctl -c /opt/python/etc/supervisord.conf update
# Start/Restart celeryd through supervisord
supervisorctl -c /opt/python/etc/supervisord.conf restart celeryd
By the way, I used an experimental option to take as the broker for Celery SQS and it is quite justified; however, flower does not yet have support for such schemes.
the
Automatically redirect HTTP to HTTPS
Here is a Supplement to the ElasticBeanstalk configuration inside Apache
the
files:
"/etc/httpd/conf.d/ssl_rewrite.conf":
mode: "000644"
owner: root
group: root
content: |
RewriteEngine On
<If "-n '%{HTTP:X-Forwarded-Proto}' && %{HTTP:X-Forwarded-Proto} != 'https'">
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
</If>
the
Use of multiple SSL domains
Amazon provides an opportunity for registrants to use free SSL certificates, including wildcard, but only within the AWS. To use multiple domains with SSL on one environment get the certificate using the AWS Certificate Manager to add the ELB balancer and SSL configured on it. Can be used and obtained from another vendor's certificates.

UPDATE Below the comments dear darken99 gave a couple of useful chips will add them here with some explanations
turn Off environment schedule
In this case, depending on the specified time range the number of instances in the autoscaling group is reduced from 1 to 0.
the
option_settings:
- namespace: aws:autoscaling:scheduledaction
resource_name: Start
option_name: MinSize
value: 1
- namespace: aws:autoscaling:scheduledaction
resource_name: Start
option_name: MaxSize
value: 1
- namespace: aws:autoscaling:scheduledaction
resource_name: Start
option_name: DesiredCapacity
value: 1
- namespace: aws:autoscaling:scheduledaction
resource_name: Start
option_name: Recurrence
value: "0 9 * * 1-5"
- namespace: aws:autoscaling:scheduledaction
resource_name: Stop
option_name: MinSize
value: 0
- namespace: aws:autoscaling:scheduledaction
resource_name: Stop
option_name: MaxSize
value: 0
- namespace: aws:autoscaling:scheduledaction
resource_name: Stop
option_name: DesiredCapacity
value: 0
- namespace: aws:autoscaling:scheduledaction
resource_name: Stop
option_name: Recurrence
value: "0 18 * * 1-5"
the
option_settings:
aws:elasticbeanstalk:environment:proxy:
ProxyServer: nginx
Комментарии
Отправить комментарий