├── .github ├── FUNDING.yml └── ISSUE_TEMPLATE │ ├── bug_report.md │ └── custom.md ├── README.md ├── appspec.yml ├── buildspec.yml ├── requirements.txt ├── scripts ├── mkdir.sh ├── start_flask.sh ├── stop_flask.py ├── stop_flask.sh └── stop_flask1.sh ├── templates ├── layout.html └── test.html ├── test_app.py └── web.py /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 13 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/custom.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Custom issue template 3 | about: Describe this issue template's purpose here. 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Python Backend App for AWS CI/CD 2 | 3 | This sample project is used for demonstrating Jenkins pipeline on AWS environment with AWS devops tools(CodeBuild, S3 Buckets, CodeDeploy) 4 | 5 | 6 | 7 | ## appspec.yml 8 | The application specification file (AppSpec file) is a YAML-formatted or JSON-formatted file used by CodeDeploy to manage a deployment. It must be placed in the root of the directory structure of an application's source code. 9 | It is used by CodeDeploy to determine: 10 | 11 | 12 | * What it should install onto instances from Amazon S3 or GitHub repositories. 13 | * Which lifecycle event hooks to run in response to deployment lifecycle events.(basically start and stop scripts of the application) 14 | 15 | 16 | ## buildspec.yml 17 | A build spec is a collection of build commands and related settings, in YAML format, that CodeBuild uses to run a build. Buildspec YAML file is included as part of the source code. Self explanatory file performs necessary installations by directly accesing the console of EC2 instance and copy listed artifacts to created directories before the CodeDeploy deployment phase. 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /appspec.yml: -------------------------------------------------------------------------------- 1 | version: 0.0 2 | os: linux 3 | files: 4 | - source: / 5 | destination: /web/ 6 | hooks: 7 | AfterInstall: 8 | - location: scripts/mkdir.sh 9 | timeout: 300 10 | runas: root 11 | ApplicationStart: 12 | - location: scripts/start_flask.sh 13 | timeout: 300 14 | runas: root 15 | ApplicationStop: 16 | - location: scripts/stop_flask1.sh 17 | timeout: 300 18 | runas: root 19 | 20 | 21 | -------------------------------------------------------------------------------- /buildspec.yml: -------------------------------------------------------------------------------- 1 | version: 0.2 2 | 3 | phases: 4 | install: 5 | commands: 6 | - python -m pip install Flask 7 | build: 8 | commands: 9 | - echo Build started on `date` 10 | - echo Compiling the Python code... 11 | - python test_app.py 12 | post_build: 13 | commands: 14 | - echo Build completed on `date` 15 | artifacts: 16 | files: 17 | - web.py 18 | - appspec.yml 19 | - templates/layout.html 20 | - templates/test.html 21 | - scripts/mkdir.sh 22 | - scripts/start_flask.sh 23 | - scripts/stop_flask1.sh 24 | - scripts/stop_flask.py 25 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | Flask 2 | -------------------------------------------------------------------------------- /scripts/mkdir.sh: -------------------------------------------------------------------------------- 1 | mkdir -p /web 2 | curl -O https://bootstrap.pypa.io/get-pip.py 3 | python get-pip.py --user 4 | python -m pip install Flask 5 | #sdssdsds 6 | -------------------------------------------------------------------------------- /scripts/start_flask.sh: -------------------------------------------------------------------------------- 1 | python /web/web.py > /dev/null 2>&1 & 2 | -------------------------------------------------------------------------------- /scripts/stop_flask.py: -------------------------------------------------------------------------------- 1 | import requests 2 | 3 | requests.post("http://127.0.0.1/shutdown") 4 | -------------------------------------------------------------------------------- /scripts/stop_flask.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | import requests 3 | 4 | requests.post("http://127.0.0.1/shutdown") 5 | 6 | 7 | -------------------------------------------------------------------------------- /scripts/stop_flask1.sh: -------------------------------------------------------------------------------- 1 | python /web/scripts/stop_flask.py -------------------------------------------------------------------------------- /templates/layout.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | AWS CodeBuild-Jenkins-CodeDeploy 5 | 17 | 18 | 19 | 20 | 21 | {% block body %}{% endblock %} 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /templates/test.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% block body %} 3 | 4 | 5 |
6 |

Congratulations!!

7 |

You have successfully deployed your web application using automated CI/CD.

8 |
9 |

Jenkins - AWS CodeBuild - AWS CodeDeploy

10 | 11 |   13 |
14 |

{% endblock %}

15 | -------------------------------------------------------------------------------- /test_app.py: -------------------------------------------------------------------------------- 1 | # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # SPDX-License-Identifier: MIT-0 3 | 4 | from web import myapp 5 | import unittest 6 | 7 | # python -m unittest test_app 8 | 9 | 10 | class TestMyApp(unittest.TestCase): 11 | 12 | def setUp(self): 13 | self.app = myapp.test_client() 14 | 15 | def test_main(self): 16 | rv = self.app.get('/') 17 | assert rv.status == '200 OK' 18 | assert b'Congratulations' in rv.data 19 | #assert False 20 | 21 | def test_404(self): 22 | rv = self.app.get('/other') 23 | self.assertEqual(rv.status, '404 NOT FOUND') 24 | 25 | 26 | if __name__ == '__main__': 27 | unittest.main() 28 | -------------------------------------------------------------------------------- /web.py: -------------------------------------------------------------------------------- 1 | # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # SPDX-License-Identifier: MIT-0 3 | 4 | from flask import Flask, flash, redirect, render_template, request, session, abort 5 | from random import randint 6 | 7 | def shutdown_server(): 8 | func = request.environ.get('werkzeug.server.shutdown') 9 | if func is None: 10 | raise RuntimeError('Not running with the Werkzeug Server') 11 | func() 12 | 13 | 14 | myapp = Flask(__name__) 15 | 16 | 17 | @myapp.route('/shutdown', methods=['POST']) 18 | def shutdown(): 19 | shutdown_server() 20 | return 'Server shutting down...' 21 | 22 | 23 | @myapp.route("/") 24 | def hello(): 25 | # return name 26 | return render_template( 27 | 'test.html', **locals()) 28 | 29 | 30 | if __name__ == "__main__": 31 | myapp.run(host='0.0.0.0', port=80) 32 | --------------------------------------------------------------------------------