How to deploy on AWS EC2¶
Amazon Web Services is a popular subsidiary of Amazon that provides on-demand cloud computing platforms on a metered pay-as-you-go basis. Access the AWS web console at console.aws.amazon.com.
Prerequisites¶
This guide assumes you have:
A physical or virtual machine running Ubuntu 22.04+
Juju 3 (
3.6+
is recommended)See: How to install Juju
Install AWS tooling¶
Follow the installation guide for the Amazon Web Services CLI.
To check it is correctly installed, you can run the commands demonstrated below with sample outputs:
~$ aws --version
aws-cli/2.13.25 Python/3.11.5 Linux/6.2.0-33-generic exe/x86_64.ubuntu.23 prompt/off
Authenticate¶
Create an IAM account (or use legacy access keys) to operate AWS EC2:
mkdir -p ~/.aws && cat <<- EOF > ~/.aws/credentials.yaml
credentials:
aws:
NAME_OF_YOUR_CREDENTIAL:
auth-type: access-key
access-key: SECRET_ACCESS_KEY_ID
secret-key: SECRET_ACCESS_KEY_VALUE
EOF
Bootstrap Juju controller on AWS EC2¶
Add AWS credentials to Juju:
juju add-credential aws -f ~/.aws/credentials.yaml
Bootstrap Juju controller (check all supported configuration options):
juju bootstrap aws
Output example
> juju bootstrap aws
Creating Juju controller "aws-us-east-1" on aws/us-east-1
Looking for packaged Juju agent version 3.5.4 for amd64
Located Juju agent version 3.5.4-ubuntu-amd64 at https://juju-dist-aws.s3.amazonaws.com/agents/agent/3.5.4/juju-3.5.4-linux-amd64.tgz
Launching controller instance(s) on aws/us-east-1...
- i-0f4615983d113166d (arch=amd64 mem=8G cores=2)
Installing Juju agent on bootstrap instance
Waiting for address
Attempting to connect to 54.226.221.6:22
Attempting to connect to 172.31.20.34:22
Connected to 54.226.221.6
Running machine configuration script...
Bootstrap agent now started
Contacting Juju controller at 54.226.221.6 to verify accessibility...
Bootstrap complete, controller "aws-us-east-1" is now available
Controller machines are in the "controller" model
Now you can run
juju add-model <model-name>
to create a new model to deploy workloads.
You can check the AWS EC2 instance availability (ensure the right AWS region chosen!):
Create a new Juju model:
juju add-model welcome
Optionally increase the debug level if you are troubleshooting charms:
juju model-config logging-config='<root>=INFO;unit=DEBUG'
Deploy charms¶
The following command deploys PostgreSQL and Data-Integrator (the charm to request a test DB):
juju deploy postgresql --channel 14/stable
juju deploy data-integrator --config database-name=test123
juju relate postgresql data-integrator
Check the status:
> juju status --relations
Model Controller Cloud/Region Version SLA Timestamp
welcome aws-us-east-1 aws/us-east-1 3.5.4 unsupported 13:33:05+02:00
App Version Status Scale Charm Channel Rev Exposed Message
data-integrator active 1 data-integrator latest/stable 41 no
postgresql 14.12 active 1 postgresql 14/stable 468 no
Unit Workload Agent Machine Public address Ports Message
data-integrator/0* active idle 1 50.19.16.57
postgresql/0* active idle 0 54.224.41.249 5432/tcp Primary
Machine State Address Inst id Base AZ Message
0 started 54.224.41.249 i-0f374435695ffc54c [email protected] us-east-1b running
1 started 50.19.16.57 i-061e0d10d36c8cffe [email protected] us-east-1a running
Integration provider Requirer Interface Type Message
data-integrator:data-integrator-peers data-integrator:data-integrator-peers data-integrator-peers peer
postgresql:database data-integrator:postgresql postgresql_client regular
postgresql:database-peers postgresql:database-peers postgresql_peers peer
postgresql:restart postgresql:restart rolling_op peer
postgresql:upgrade postgresql:upgrade upgrade peer
Once deployed, request the credentials for your newly bootstrapped PostgreSQL database.
For Juju 2.9 use:
juju run-action --wait data-integrator/leader get-credentials
and for newer Juju 3+ use:
juju run data-integrator/leader get-credentials
The output example:
postgresql:
data: '{"database": "test123", "external-node-connectivity": "true", "requested-secrets":
"[\"username\", \"password\", \"tls\", \"tls-ca\", \"uris\"]"}'
database: test123
endpoints: 172.31.40.178:5432
password: rmnk0AO4jICAixCL
uris: postgresql://relation-4:[email protected]:5432/test123
username: relation-4
version: "14.12"
At this point, you can access your DB inside AWS using the internal IP address. All further Juju applications will use the database through the internal network:
> psql postgresql://relation-4:[email protected]:5432/test123
psql (15.6 (Ubuntu 15.6-0ubuntu0.23.10.1), server 14.12 (Ubuntu 14.12-0ubuntu0.22.04.1))
Type "help" for help.
test123=>
From here you can use/scale/backup/restore/refresh your newly deployed Charmed PostgreSQL.
Expose database (optional)¶
If necessary to access DB from outside of AWS (warning: opening ports to public is risky) open the AWS firewall using the simple juju expose functionality:
juju expose postgresql
Once exposed, you can connect your database using the same credentials as above (Important: this time use the EC2 Public IP assigned to the PostgreSQL instance):
> juju status postgresql
...
Unit Workload Agent Machine Public address Ports Message
postgresql/0* active idle 0 54.224.41.249 5432/tcp Primary
...
> psql postgresql://relation-4:[email protected]:5432/test123
psql (15.6 (Ubuntu 15.6-0ubuntu0.23.10.1), server 14.12 (Ubuntu 14.12-0ubuntu0.22.04.1))
Type "help" for help.
test123=>
To close the public access run:
juju unexpose postgresql
Clean up¶
Caution
Always clean AWS resources that are no longer necessary - they could be costly!
To destroy the Juju controller and remove AWS instance (warning: all your data will be permanently removed):
> juju controllers
Controller Model User Access Cloud/Region Models Nodes HA Version
aws-us-east-1* - admin superuser aws/us-east-1 1 1 none 3.5.4
> juju destroy-controller aws-us-east-1 --destroy-all-models --destroy-storage --force
Next, check and manually delete all unnecessary AWS EC2 instances, to show the list of all your EC2 instances run the following command (make sure the correct region used!):
aws ec2 describe-instances --region us-east-1 --query "Reservations[].Instances[*].{InstanceType: InstanceType, InstanceId: InstanceId, State: State.Name}" --output table
Output example
-------------------------------------------------------
| DescribeInstances |
+---------------------+----------------+--------------+
| InstanceId | InstanceType | State |
+---------------------+----------------+--------------+
| i-0f374435695ffc54c| m7i.large | terminated |
| i-0e1e8279f6b2a08e0| m7i.large | terminated |
| i-061e0d10d36c8cffe| m7i.large | terminated |
| i-0f4615983d113166d| m7i.large | terminated |
+---------------------+----------------+--------------+
List your Juju credentials:
> juju credentials
...
Client Credentials:
Cloud Credentials
aws NAME_OF_YOUR_CREDENTIAL
...
Remove AWS EC2 CLI credentials from Juju:
> juju remove-credential aws NAME_OF_YOUR_CREDENTIAL
Finally, remove AWS CLI user credentials (to avoid forgetting and leaking):
rm -f ~/.aws/credentials.yaml
Note
If you expect having several concurrent connections frequently, it is highly recommended to deploy PgBouncer alongside PostgreSQL. For more information, read our explanation about Connection pooling.