Skip to content

Commit

Permalink
Add initial Terraform and Ansible configuration for Jenkins and appli…
Browse files Browse the repository at this point in the history
…cation deployment
  • Loading branch information
rishavnandi committed Nov 12, 2024
1 parent c7de843 commit 0c1a051
Show file tree
Hide file tree
Showing 14 changed files with 552 additions and 0 deletions.
76 changes: 76 additions & 0 deletions Jenkinsfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
pipeline {
agent any

environment {
DOCKER_CREDENTIALS = credentials('docker-hub-credentials')
DOCKER_IMAGE = "your-dockerhub-username/your-app-name"
DOCKER_TAG = "${env.GIT_COMMIT.take(7)}"
AWS_CREDENTIALS = credentials('aws-credentials')
}

stages {
stage('Checkout') {
steps {
checkout scm
}
}

stage('Build Docker Image') {
steps {
sh """
docker build -t ${DOCKER_IMAGE}:${DOCKER_TAG} .
docker tag ${DOCKER_IMAGE}:${DOCKER_TAG} ${DOCKER_IMAGE}:latest
"""
}
}

stage('Push Docker Image') {
steps {
sh """
echo ${DOCKER_CREDENTIALS_PSW} | docker login -u ${DOCKER_CREDENTIALS_USR} --password-stdin
docker push ${DOCKER_IMAGE}:${DOCKER_TAG}
docker push ${DOCKER_IMAGE}:latest
"""
}
}

stage('Update Application Version') {
steps {
sh """
sed -i 's|docker_image:.*|docker_image: ${DOCKER_IMAGE}:${DOCKER_TAG}|' main-server/ansible/vars.yml
"""
}
}

stage('Deploy Infrastructure') {
environment {
AWS_ACCESS_KEY_ID = "${AWS_CREDENTIALS_USR}"
AWS_SECRET_ACCESS_KEY = "${AWS_CREDENTIALS_PSW}"
}
steps {
dir('main-server/terraform') {
sh """
terraform init
terraform apply -auto-approve
"""
}
}
}

stage('Deploy Application') {
steps {
dir('main-server/ansible') {
sh """
ansible-playbook -i inventory.ini playbook.yml
"""
}
}
}
}

post {
always {
sh 'docker logout'
}
}
}
147 changes: 147 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
# Complete CI/CD Pipeline for a Flask Application

## Overview

This project is a web application that allows users to view stock price graphs and historical data for a given ticker symbol. It is built using Flask for the backend and uses yfinance to fetch stock data. The application is containerized using Docker and can be deployed on AWS using Terraform and Ansible.

This project was created for the purpose of learning and practicing CI/CD pipelines, infrastructure as code, and containerization.
So, it is not optimized for production use and is not recommended to be used in a production environment.

## Features

- Real-time stock price graphs using FinViz charts
- Historical price data in a tabular format
- Responsive web design with mobile support
- Automated CI/CD pipeline with Jenkins
- Infrastructure as Code using Terraform
- Automated deployment using Ansible
- Containerized application using Docker

## Prerequisites

- Docker
- Terraform
- Ansible
- Jenkins
- AWS account with appropriate permissions
- Python
- pip package manager

## Setup Instructions

### Local Development

1. **Clone the repository:**
```bash
git clone https://github.com/jenkins_pipeline.git
cd jenkins_pipeline
```

2. **Create and activate a virtual environment (recommended):**
```bash
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
```

3. **Install dependencies:**
```bash
pip install -r requirements.txt
```

4. **Run the application:**
```bash
flask run
```
The application will be available at `http://localhost:5000`

### Docker Deployment

1. **Build the Docker image:**
```bash
docker build -t flask-stock-app .
```

2. **Run the Docker container:**
```bash
docker run -p 5000:5000 flask-stock-app
```
Access the application at `http://localhost:5000`

### Production Deployment

#### 1. Infrastructure Setup

1. **Configure AWS credentials:**
```bash
export AWS_ACCESS_KEY_ID="your_access_key"
export AWS_SECRET_ACCESS_KEY="your_secret_key"
export AWS_DEFAULT_REGION="your_preferred_region"
```

#### 2. Jenkins CI/CD Setup

1. **Deploy Jenkins server:**
```bash
cd jenkins/terraform
terraform init
terraform apply
```

2. **Configure Jenkins:**
```bash
cd ../ansible
ansible-playbook playbook.yml
```

3. **Access Jenkins UI:**
- Navigate to `http://<jenkins-server-ip>:8080`
- Use the initial admin password displayed in the Ansible output
- Install suggested plugins
- Create admin user
- Configure the following credentials:
- Docker Hub credentials
- AWS credentials
- GitHub credentials

4. **Configure Jenkins Pipeline:**
- Create a new pipeline job
- Point it to your repository
- Use the provided Jenkinsfile

#### 3. Application Deployment

1. **Update variables:**
- Edit `main-server/ansible/vars.yml` with your Docker image details
- Edit `jenkins/ansible/vars.yml` with your GitHub repository

2. **Deploy application:**
```bash
cd main-server/ansible
ansible-playbook playbook.yml
```

## Project Structure

```
.
├── app.py # Flask application
├── Dockerfile # Docker configuration
├── requirements.txt # Python dependencies
├── static/ # Static assets
├── templates/ # HTML templates
├── main-server/ # Main application deployment
│ ├── ansible/ # Ansible playbooks
│ └── terraform/ # Infrastructure as code
└── jenkins/ # Jenkins CI/CD setup
├── ansible/ # Jenkins configuration
└── terraform/ # Jenkins infrastructure
```

## Acknowledgments

- yfinance for stock data API
- FinViz for stock charts
- Flask framework
- Jenkins community
- Terraform and Ansible communities
```
2 changes: 2 additions & 0 deletions jenkins/ansible/inventory.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[jenkins]
jenkins_server ansible_host=${jenkins_ip} ansible_user=ubuntu ansible_ssh_private_key_file=~/.ssh/your-key-pair.pem
136 changes: 136 additions & 0 deletions jenkins/ansible/playbook.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
---
- hosts: jenkins
become: yes
vars_files:
- vars.yml

tasks:
- name: Update apt cache
apt:
update_cache: yes

- name: Install Java
apt:
name: openjdk-11-jdk
state: present

- name: Add Jenkins repository key
apt_key:
url: https://pkg.jenkins.io/debian-stable/jenkins.io.key
state: present

- name: Add Jenkins repository
apt_repository:
repo: deb https://pkg.jenkins.io/debian-stable binary/
state: present

- name: Install Jenkins
apt:
name: jenkins
state: present

- name: Install Docker
apt:
name: docker.io
state: present

- name: Add jenkins user to docker group
user:
name: jenkins
groups: docker
append: yes

- name: Start Jenkins service
service:
name: jenkins
state: started
enabled: yes

- name: Get initial admin password
command: cat /var/lib/jenkins/secrets/initialAdminPassword
register: jenkins_password
changed_when: false

- name: Display Jenkins initial admin password
debug:
var: jenkins_password.stdout

- name: Install Jenkins plugins
jenkins_plugin:
name: "{{ item }}"
jenkins_home: "{{ jenkins_home }}"
with_items:
- git
- pipeline
- docker-pipeline
- ansible
- terraform

- name: Install required system packages
apt:
name:
- python3-pip
- git
state: present

- name: Install AWS CLI
pip:
name: awscli
state: present

- name: Install Terraform
unarchive:
src: https://releases.hashicorp.com/terraform/1.5.7/terraform_1.5.7_linux_amd64.zip
dest: /usr/local/bin
remote_src: yes
mode: 0755

- name: Create Jenkins job directory
file:
path: "{{ jenkins_home }}/jobs/main-pipeline"
state: directory
owner: jenkins
group: jenkins
mode: '0755'

- name: Configure Jenkins job
copy:
content: |
<?xml version='1.1' encoding='UTF-8'?>
<org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject plugin="workflow-multibranch">
<actions/>
<description>Main application pipeline</description>
<properties/>
<folderViews/>
<healthMetrics/>
<icon class="jenkins.branch.MetadataActionFolderIcon"/>
<orphanedItemStrategy class="com.cloudbees.hudson.plugins.folder.computed.DefaultOrphanedItemStrategy">
<pruneDeadBranches>true</pruneDeadBranches>
<daysToKeep>-1</daysToKeep>
<numToKeep>-1</numToKeep>
</orphanedItemStrategy>
<triggers/>
<sources class="jenkins.branch.MultiBranchProject$BranchSourceList">
<data>
<jenkins.branch.BranchSource>
<source class="jenkins.plugins.git.GitSCMSource">
<remote>{{ github_repo }}</remote>
<credentialsId>github-credentials</credentialsId>
<traits>
<jenkins.plugins.git.traits.BranchDiscoveryTrait/>
</traits>
</source>
</jenkins.branch.BranchSource>
</data>
</sources>
<factory class="org.jenkinsci.plugins.workflow.multibranch.WorkflowBranchProjectFactory"/>
</org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject>
dest: "{{ jenkins_home }}/jobs/main-pipeline/config.xml"
owner: jenkins
group: jenkins
mode: '0644'

- name: Restart Jenkins to apply changes
service:
name: jenkins
state: restarted
6 changes: 6 additions & 0 deletions jenkins/ansible/vars.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
jenkins_home: /var/lib/jenkins
jenkins_user: jenkins
jenkins_group: jenkins
github_repo: "your-repo-url"
github_branch: "main"
1 change: 1 addition & 0 deletions jenkins/jenkins-init.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

1 change: 1 addition & 0 deletions jenkins/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

1 change: 1 addition & 0 deletions jenkins/terraform.tfvars.example
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

Loading

0 comments on commit 0c1a051

Please sign in to comment.