This is a simple proof-of-concept for a cloud stack in AWS, that includes a containerized application running in a EC2 instance accessible through API Gateway and Network Load Balancer.
Additionally, a CI/CD script pushes changes to the backend when a change is pushed to the application repository.
This solution includes bootstrap, provision and deployment for a simple AWS infrastructure that allows a webserver to run while being accessible via HTTP from the internet.
Although the webserver has public internet access, it's not directly accessible via HTTP from the internet, instead it uses API Gateway along with a Network Load Balancer as a proxy to route the requests targeting the /hello resource.
The webserver itself is a docker container with nginx that responds with "world" to the resource /hello. The repository for that application is located in the hello-webserver directory.
This solution includes a simple script representing a CI/CD pipeline, that checks for new changes in the hello-webserver repository and pushes the new changes to the backend if any.
-
Install python and pip: https://www.python.org/downloads/
-
Install python libraries:
pip install -r requirements.txt -
Run
generate_ssh_key.pyscript to generate SSH key pair and processcloudformation/hello-webserver-stack.yml.j2template:python generate_ssh_key.py -
Copy AWS credentials template, rename to
aws_credentials.jsonand replace placeholders with actual secrets:cp ./.credentials/aws_credentials.json.template ./.credentials/aws_credentials.json
To bootstrap the AWS infrastructure, first add your credentials in the aws_credentials.json file located in the .credentials directory.
Saving keys in plain text is not the best practice, but as always, it's an inverse proportion relation between security and convenience. For this purpose, a plain-text json file will work fine.
Then, run the script aws_bootstrap.py:
python aws_bootstrap.py --template-path cloudformation/hello-webserver-stack.yml --stack-name hello-webserver-stack-testThis script will create the cloudformation stack in the selected region.
Refer to the script's documentation for other use cases.
Once the script finished successfully, add manually the created instance's public IP into the ansible hosts inventory file: hosts/test.ini.
Provision the EC2 instance:
ansible-playbook hello-webserver-provision.yml -i hosts/test.ini -vvThis playbook will install required dependencies on the host.
Deploy the docker container to the instance:
ansible-playbook hello-webserver-deploy.yml -i hosts/test.ini --extra-vars "hello_webserver_root=$(pwd)/hello-webserver" -vvThis playbook will update the image's dockerfile, re-build it and run it on the host.
To deploy automatically after any change is pushed to the image's repository, run the script hello_webserver_deploy_changes.py:
python hello_webserver_deploy_changes.py --git-repo-root $(pwd)/hello-webserver --environment testThis script will pull changes every 30 seconds and execute the hello-webserver-deploy.yml playbook if there are any new changes.
The best setup for this script is on a service that executes it on startup on a command-and-control machine.