Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

challenge 3 #3

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions challenge_3/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Challenge 1

## Instructions

A Web application has been reported by a customer as broken and this has been escalated to the team. You're job is to investigate, troubleshoot and resolve the problem, returning the web app to normal service.

You will be provided with an individual url for the site.

[source code](./trubble/trubble.js), [documentation](./trubble/README.md) and [deployment code](./trubble/ansible/deploy.yml) is in the [trubble directory](./trubble/)

1. in advance, please generate a new, unique SSH keypair and send us the **public** key. You may follow [these](https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent#generating-a-new-ssh-key) instructions.

2. You will recieve a url from us.

3. Using SSH log in to the instance the web app is hosted on (the address is the same as the url the username is `ubuntu`).

4. Document your troubleshooting process while you restore normal operation.

5. Provide a permanent solution or work-around to the issue.

## Solution Submission

Please host your solution as a **private** repository and invite your interviewer as a collaborator.
170 changes: 170 additions & 0 deletions challenge_3/trubble/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
.pnpm-debug.log*

# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage
*.lcov

# nyc test coverage
.nyc_output

# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# Snowpack dependency directory (https://snowpack.dev/)
web_modules/

# TypeScript cache
*.tsbuildinfo

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Optional stylelint cache
.stylelintcache

# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variable files
.env
.env.development.local
.env.test.local
.env.production.local
.env.local

# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache

# Next.js build output
.next
out

# Nuxt.js build / generate output
.nuxt
dist

# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public

# vuepress build output
.vuepress/dist

# vuepress v2.x temp and cache directory
.temp
.cache

# Docusaurus cache and generated files
.docusaurus

# Serverless directories
.serverless/

# FuseBox cache
.fusebox/

# DynamoDB Local files
.dynamodb/

# TernJS port file
.tern-port

# Stores VSCode versions used for testing VSCode extensions
.vscode-test

# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*

# Local .terraform directories
**/.terraform/*

# .tfstate files
*.tfstate
*.tfstate.*

# Crash log files
crash.log
crash.*.log

# Exclude all .tfvars files, which are likely to contain sensitive data, such as
# password, private keys, and other secrets. These should not be part of version
# control as they are data points which are potentially sensitive and subject
# to change depending on the environment.
*.tfvars
*.tfvars.json

# Ignore override files as they are usually used to override resources locally and so
# are not checked in
override.tf
override.tf.json
*_override.tf
*_override.tf.json

# Include override files you do wish to add to version control using negated pattern
# !example_override.tf

# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan
# example: *tfplan*

# Ignore CLI configuration files
.terraformrc
terraform.rc

# Ansible retry files
*.retry

dist
1 change: 1 addition & 0 deletions challenge_3/trubble/.node-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
14.17.6
88 changes: 88 additions & 0 deletions challenge_3/trubble/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# Trubble

A web application built using Node.js and Express. It serves a simple web page at the root URL. There is only a single route `/` which searches for a random entity from [pokeapi](https://pokeapi.co/) and presents the encounter as plain text.

## Prerequisites

Before running the app, make sure you have the following installed:

- Node.js version 14 (https://nodejs.org/en/download)
- NPM (Node Package Manager)

## Configuration

The web app can be configured using environment variables. Create a `.env` file in the root directory of the project with the following variables:
- `NODE_ENV` (optional): The environment the app will run in.
- `PORT` (optional): The port number the app will listen on. Defaults to `3000`.
- `IMPORTANT_VALUE` (required): A boolean value that must be set to `true` for the app to run. If this value is not set or is set to anything other than `true`, the app will log an error message and exit.

## Logging

The application will log to an `app.log` file in `logs` directory.
In production logging will also be handled by systemd and will log to `/var/logs/syslog`. check the below systemd file for details.

## Running the App in Development

To run the app, follow these steps:

1. Install dependencies by running `npm install`.
2. Start the app by running `npm start`.
3. Access the app by navigating to `http://localhost:3000` (or whichever port you specified in the `PORT` environment variable).

## Testing

Open a web browser and navigate to `http://localhost:3000/`.

## Building the app for production

1. Install dependencies by running `npm install`.
2. Build the application with `npm run build`

## Installing the app in Production

Creation of the instance, install and managment of the application is by ansible. the playbook is in the [ansible directory](./ansible/deploy.yml).
Instructions on how to use the ansible playbook can be found in the [ansible directory](./ansible/README.md).
Ansible should be used to ensure the application is installed and configured correctly.

The [playbook](./ansible/deploy.yml) reads as the documentation however the install steps can be summarised as:

1. Ensure the App is built in the `dist` directory.
1. Create a new Linux instance.
2. Ensure nodejs is installed on the system.
3. Ensure nginx is installed and configured correctly.
4. Copy the contents of the local `dist` directory to the remote machine at the `/opt/` directory
5. Use systemd (example below) to keep the app running


## Systemd Unit File

To run the app as a systemd service on Linux, create a file as a root user `/etc/systemd/system/trubble.service` with the following content:

```
[Unit]
Description=trubble
After=network.target

[Service]
Environment="NODE_ENV=production"
User=root
WorkingDirectory=/opt
ExecStart=/usr/bin/node index.js
Restart=always
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=trubble

[Install]
WantedBy=multi-user.target
```

Then run the following commands:

```
sudo systemctl daemon-reload
sudo systemctl enable trubble
sudo systemctl start trubble
```

The app will now start automatically on boot and can be managed using the `systemctl` command.
38 changes: 38 additions & 0 deletions challenge_3/trubble/ansible/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Deploy Trubble

A playbook to create an AWS EC2 instance and install The trubble nodejs application.

## Prerequisites

- python 3.9+
- python pip

## Setup

Install dependencies

```
python3 -m pip install -r requirements.txt
ansible-galaxy install -f -r requirements.yml
ansible-galaxy collection install -f -r requirements.yml
```

Setup AWS credentials

```
export AWS_ACCESS_KEY_ID="xxxxx"
export AWS_SECRET_ACCESS_KEY="xxxxx"
export AWS_SESSION_TOKEN="xxxxx"
```

To only manage existing running application instances run:

ansible-playbook deploy.yml --extra-vars='\{"users": \[user1,user2,user3\]\}' --skip-tags='create'

where `users` var is an array of users to create instances for.

Run the full playbook and create a new instance:

```
ansible-playbook deploy.yml --extra-vars='\{"users": \[user1,user2,user3\]\}'
```
7 changes: 7 additions & 0 deletions challenge_3/trubble/ansible/ansible.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

[defaults]
ansible_python_interpreter=/usr/bin/python3
inventory=aws_ec2.yaml

[inventory]
enable_plugins = aws_ec2
9 changes: 9 additions & 0 deletions challenge_3/trubble/ansible/aws_ec2.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
plugin: aws_ec2
filters:
tag:Env: dev
keyed_groups:
- key: tags
prefix: tag
regions:
- us-east-1
Loading