Deploying a Django app on AWS: Difference between revisions

From Littledamien Wiki
Jump to navigation Jump to search
 
(26 intermediate revisions by the same user not shown)
Line 7: Line 7:


<p class="alert alert-warning">I didn't realize this at first, but these prerequisites are all '''local'''. The first time I tried this out, I thought I had to get on a remote server to install Python, Django, awsebcli, etc. All of these things are installed on the local workstation and `eb deploy` handles moving them over and replicating the app environment.</p>
<p class="alert alert-warning">I didn't realize this at first, but these prerequisites are all '''local'''. The first time I tried this out, I thought I had to get on a remote server to install Python, Django, awsebcli, etc. All of these things are installed on the local workstation and `eb deploy` handles moving them over and replicating the app environment.</p>
* EB CLI <ref>[https://docs.amazonaws.cn/en_us/elasticbeanstalk/latest/dg/eb-cli3-install-osx.html Install the EB CLI on Mac OS] - AWS Elastic Beanstalk docs</ref>
<syntaxhighlight lang="sh">
$ brew install awsebcli
</syntaxhighlight>


* See [[Amazon_Web_Services_Website_Hosting_Fundamentals#AWS_services|AWS Services]]
* See [[Amazon_Web_Services_Website_Hosting_Fundamentals#AWS_services|AWS Services]]
Line 15: Line 21:
Existing Elastic Beanstalk applications and environments can be found in the [https://us-west-2.console.aws.amazon.com/elasticbeanstalk/home AWS Elastic Beanstalk management console].  
Existing Elastic Beanstalk applications and environments can be found in the [https://us-west-2.console.aws.amazon.com/elasticbeanstalk/home AWS Elastic Beanstalk management console].  


Create a ne Elastic Beanstalk application from the command line one a local workstation,
Create a new Elastic Beanstalk application from the command line on a local workstation:


<syntaxhighlight lang="bash">
<syntaxhighlight lang="sh">
$ eb init
$ eb init
</syntaxhighlight>
</syntaxhighlight>
Line 25: Line 31:
These properties are stored in `.elasticbeanstalk/config.yml` which should '''not''' be added to Git.  
These properties are stored in `.elasticbeanstalk/config.yml` which should '''not''' be added to Git.  


Create a new Elastic Beanstalk environment from the command line on a local workstation.  
Create a new Elastic Beanstalk environment from the command line on a local workstation. Assuming that the instance is using an independent RDS.
 
<syntaxhighlight lang="sh">
$ eb create
</syntaxhighlight>
 
If instead the Elastic Beanstalk environment is creating its own database, it's necessary to specify that option with the `create` command:


<syntaxhighlight lang="bash">
<syntaxhighlight lang="sh">
$ eb create --database.engine postgres
$ eb create --database.engine postgres
</syntaxhighlight>
</syntaxhighlight>


This will prompt for the environment name, its URL prefix, and a database username and password.  
This will prompt for the environment name, its URL prefix, and a database username and password.


The `--database.engine` argument is optional. I was running into the problem of the RDS instance not being created when the environment was created. This option fixed that issue, but since getting a working version of the site I have not confirmed that the `--database.engine` option is essential to creating the RDS instance.
== Saving and applying Elastic Beanstalk environment configuration ==
 
Elastic Beanstalk environment configuration is controlled through the '''Configuration''' panel of the AWS Elastic Beanstalk console.
 
For example, it's necessary to configure Security Groups and  Environment Variables to support [[Using_Elastic_Beanstalk_With_Amazon_RDS#Grant_RDS_access_for_the_Elastic_Beanstalk_environment|connecting to independent RDS instances]].
 
To save an environment's configuration to apply again later if an environment is created from scratch, save the environment configuration.
 
From the AWS EB console: ''select application'' > ''select environment'' > '''Actions''' button at the upper right > '''Save Configuration'''
 
From the eb cli: `eb save environment-name`. This will save the configuration under `.elasticbeanstalk/saved_configs/env-name-version.cfg.yml`
 
To apply a saved configuration to an Elastic Beanstalk environment:
 
'''AWS EB console''' > ''select application'' > ''select environment'' > '''Actions''' button at the upper right > '''Load Configuration'''


== Deploying a Django app ==
== Deploying a Django app ==
Line 75: Line 101:


See [[Defining Django App Dependencies]]
See [[Defining Django App Dependencies]]
See also [[Customizing AWS Software With .ebextensions]]


== Production environment project settings ==
== Production environment project settings ==
Line 120: Line 148:
See [[Using Elastic Beanstalk With Amazon RDS]]
See [[Using Elastic Beanstalk With Amazon RDS]]


# In the [https://us-west-2.console.aws.amazon.com/rds/home Amazon RDS Management Console], create a new RDS instance. <ref>[http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/AWSHowTo.RDS.html#rds-external-defaultvpc Launching and Connecting to an External RDS] - AWS Elastic Beanstalk Developers Guide</ref>
Run `makemigration` ''locally''. This prevents potential data loss on the production server. <br />`eb deploy` will move the migrations file to the EC2 instance and have them ready to run a `migrate`.
# Modify DB instance's security group to allow inbound traffic.
 
# Add the DB instance's security group to the Elastic Beanstalk environment.
<syntaxhighlight lang="bash">
# Save RDS connection information in Elastic Beanstalk environment.
$ python manage.py makemigrations
# Restart the Elastic Beanstalk environment.
</syntaxhighlight>
 
* Add a `.config` command to run the migration; it will run as part of the `eb deploy` process.
* Deploy the project using `eb create` or `eb deploy`.
 
== Creating an admin account ==
 
See [[Creating a Django Admin Account on Elastic Beanstalk]]


== Serving static files using Amazon S3 ==
== Serving static files using Amazon S3 ==
=== Configuration ===
See [[Configuring Django to Serve Media Files Via S3]]
=== Deployment ===
Once configured to use S3 for storage, Django's `collectstatic` command will upload static files to the S3 bucket. Both the AWS servers and local development will reference the files on S3.
This means that if a stylesheet is compiled, the `collectstatic` command must be run before the changes are available anywhere.
<syntaxhighlight lang="sh">
python manage.py collectstatic --noinput
</syntaxhighlight>
The `--noinput` flag simply bypasses any confirmation messages.
The `static` template tag will correctly reference static resources in the Amazon S3 bucket.
Timestamps don't always correspond between S3 and the local filesystem. In some cases a newly edited file won't register as changed based on its timestamp. In these cases log into the AWS Management Console, navigate to the bucket under S3 and manually delete the file before executing `manage.py`.
== Managing domain names ==
The documentation at [http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/customdomains.html Your Elastic Beanstalk Environment's Domain Name] (AWS Elastic Beanstalk Developer Guide) is straight forward and easy to follow.
See [[Managing Elastic Beanstalk Domain Names]]
== Security Certificates ==
See [[EC2 Security Certificates]] for how to install and manage security certificates for Elastic Beanstalk hosted sites.


== Notes ==
== Notes ==

Latest revision as of 21:13, 19 March 2020

Overview[edit]

All of these steps are performed locally.

Prerequisites[edit]

I didn't realize this at first, but these prerequisites are all local. The first time I tried this out, I thought I had to get on a remote server to install Python, Django, awsebcli, etc. All of these things are installed on the local workstation and eb deploy handles moving them over and replicating the app environment.

$ brew install awsebcli

AWS Elastic Beanstalk[edit]

Existing Elastic Beanstalk applications and environments can be found in the AWS Elastic Beanstalk management console.

Create a new Elastic Beanstalk application from the command line on a local workstation:

$ eb init

This will prompt for region, credentials, application name, python version, ssh availability, etc.

These properties are stored in .elasticbeanstalk/config.yml which should not be added to Git.

Create a new Elastic Beanstalk environment from the command line on a local workstation. Assuming that the instance is using an independent RDS.

$ eb create

If instead the Elastic Beanstalk environment is creating its own database, it's necessary to specify that option with the create command:

$ eb create --database.engine postgres

This will prompt for the environment name, its URL prefix, and a database username and password.

Saving and applying Elastic Beanstalk environment configuration[edit]

Elastic Beanstalk environment configuration is controlled through the Configuration panel of the AWS Elastic Beanstalk console.

For example, it's necessary to configure Security Groups and Environment Variables to support connecting to independent RDS instances.

To save an environment's configuration to apply again later if an environment is created from scratch, save the environment configuration.

From the AWS EB console: select application > select environment > Actions button at the upper right > Save Configuration

From the eb cli: eb save environment-name. This will save the configuration under .elasticbeanstalk/saved_configs/env-name-version.cfg.yml

To apply a saved configuration to an Elastic Beanstalk environment:

AWS EB console > select application > select environment > Actions button at the upper right > Load Configuration

Deploying a Django app[edit]

Updates to the app are deployed with eb deploy.

This looks at .elasticbeanstalk/config.yml for the target application and environment.

branch-defaults:
  master:
    environment: nrose-env
global:
  application_name: north-rose
  default_ec2_keyname: nrosedevs-aws
  default_platform: 64bit Amazon Linux 2015.09 v2.0.6 running Python 3.4
  default_region: us-west-2
  profile: eb-cli
  sc: git

With the master Git branch checked out, and the config.yml above, eb deploy will package up the project file and upload them to the EC2 instance corresponding with the nrose-env environment of the north-rose app.

To update a staging environment, edit config.yml with the following:

branch-defaults:
  master:
    environment: nrose-env
  staging:
    environment: nrose-staging
  staging-nodebug:
    environment: nrose-staging

With the staging Git branch checked out, eb deploy will now update the nrose-staging environment.

Alternatively, use eb deploy alternate-env to target a non-default EB environment named alternate-env.

Installing Django app dependencies[edit]

See Defining Django App Dependencies

See also Customizing AWS Software With .ebextensions

Production environment project settings[edit]

Set DEBUG to False:

# myapp/settings.py
# ...
DEBUG = False

With DEBUG = False, ALLOWED_HOSTS is required. [2]

Add localhost, the domain of the site, Elastic Beanstalk, and AWS's Elastic Load Balancer to ALLOWED_HOSTS:

# myapp/settings.py
# ...
DEBUG = False

ALLOWED_HOSTS = [
    "localhost",
    "mydomain.com",
    ".us-west-2.elasticbeanstalk.com",
    ".compute-1.amazonaws.com" # allow viewing of instances directly
]

# Grant access to AWS's Elastic Load Balancer
import requests
EC2_PRIVATE_IP = None
try:
    EC2_PRIVATE_IP = requests.get('http://169.254.169.254/latest/meta-data/local-ipv4', timeout=0.01).text
except requests.exceptions.RequestException:
    pass

if EC2_PRIVATE_IP:
    ALLOWED_HOSTS.append(EC2_PRIVATE_IP)

It's necessary to install python-requests for the above code. (pip install requests).

Configuring an independent RDS instance[edit]

See Using Elastic Beanstalk With Amazon RDS

Run makemigration locally. This prevents potential data loss on the production server.
eb deploy will move the migrations file to the EC2 instance and have them ready to run a migrate.

$ python manage.py makemigrations
  • Add a .config command to run the migration; it will run as part of the eb deploy process.
  • Deploy the project using eb create or eb deploy.

Creating an admin account[edit]

See Creating a Django Admin Account on Elastic Beanstalk

Serving static files using Amazon S3[edit]

Configuration[edit]

See Configuring Django to Serve Media Files Via S3

Deployment[edit]

Once configured to use S3 for storage, Django's collectstatic command will upload static files to the S3 bucket. Both the AWS servers and local development will reference the files on S3.

This means that if a stylesheet is compiled, the collectstatic command must be run before the changes are available anywhere.

python manage.py collectstatic --noinput

The --noinput flag simply bypasses any confirmation messages.

The static template tag will correctly reference static resources in the Amazon S3 bucket.

Timestamps don't always correspond between S3 and the local filesystem. In some cases a newly edited file won't register as changed based on its timestamp. In these cases log into the AWS Management Console, navigate to the bucket under S3 and manually delete the file before executing manage.py.

Managing domain names[edit]

The documentation at Your Elastic Beanstalk Environment's Domain Name (AWS Elastic Beanstalk Developer Guide) is straight forward and easy to follow.

See Managing Elastic Beanstalk Domain Names

Security Certificates[edit]

See EC2 Security Certificates for how to install and manage security certificates for Elastic Beanstalk hosted sites.

Notes[edit]

See also[edit]

References[edit]

  1. Install the EB CLI on Mac OS - AWS Elastic Beanstalk docs
  2. ALLOWED_HOSTS - Django documentation