MOPS Speed Run
Published: 2023-12-21 21:52:13

## Create AWS Member Account

From Root Organization as Root User

1. From AWS Organizations.  Add an AWS account.

2.  From IAM Identity Center > Multi-account permissions > AWS Accounts.  Select new account from organizational structure and "Assign users or groups".

3.  From IAM Identity Center > Settings.  Navigate to Identity source and note the AWS access portal URL:  `https://############.awsapps.com/start`

## Start Code Repo

Get Templates 

```bash
git clone https://github.com/jrhicks/mops
mv mops prod
cd prod
rm -rf .git
```

Connect to Newly Created Github Repo

```bash
git init
git add .
git commit -m "first commit"
git branch -M main
git remote add origin https://github.com/YourCompany/prod.git
git push -u origin main
```

## Scaffold IaC

```bash
make hygen-cli
make config
code .mops.js
make mops
```

## Setup AWS CLI

The AWS Identity center allows a single user to access multiple accounts.  First we install the aws-cli then use it to configure a profile for the newly created account.

```bash
make aws-cli
make profile
make login
```

## Terraform Cluster

Terraform a VPC, EKS cluster, and a variety of resources useful for running web applications in EKS.

```bash
make tf-cli
make cluster
```

## Operationalize Cluster

Create a Personal Access Token in Github.

Bootstrap GitOps, Install k8s infrastructure, k8s add-ons, and k8s monitoring.

```bash
make kube-cli
make flux-cli
git add; git commit -m "k8s cluster"; git push
make flux
```

Check Results

```bash
make dashboard
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oovd27fa94nk1nwkt6tg.png)

## Delegate Name Server

Lookup the nameservers for the terraformed Hosted Zone and configure your DNS to use these Name Servers.

```bash
make nameservers
```

Copy output into DNS Provider's Management console.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9xn2zz1lsizjjg34hzgn.png)

## Scaffold App's Infrastructure (As Code)

* AWS Infrastructure (ECR, S3, ACM, SG)
* K8s Infrastructure (Namespace, Deployments, Service, PodMonitor, Dashboards, Secrets)
* Flux Infrastructure (Kustomization, Github Snippets, Automations)

```bash
make app
```

Link App into FluxCD by adding generated resources to Kustomizations (FluxCD's Custom Resource For Specifying GitOps Functionality)

* `k8s/apps/base/kustomization.yaml`

* `k8s/apps/namespaces/kustomization.yaml`

Deploy via GitOps

```bash
git add .
git commit -m "my-app infrastructure as code"
git push
```

Bypass Wait and Trigger Sync

```bash
make fsync
```

## Build CI/CD Pipeline

### Configure Github to Push to ECR

* Copy snippets from `./snippets/my-app/ci.yaml` to your ci.yaml for your app.

* Generate AWS Access Keys

```bash
make my-app-gh-keys
```

* Copy keys to Github.  Navigate to repository > Settings > Security > Secrets & Variables > Actions > Repository Secrets

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n7malv4ty32hyrh3209x.png)

* Trigger build

```bash
git add .
git commit -m "chore update ci/cd"
git push
```

### Configure Automations

#### Configure EKS to work with ECR

Deploy Secrets referenced by FluxCD Image Repository Resource

```bash
make ecr_credentials_renew
```

Deploy Secrets to share with Github
```bash
make flux-gh-deploy-keys
```

Paste into Github Repo > Settings > Security > Deploy Keys > Add Deploy Key

[x] Enable Write Access.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t4mxf5nh2t2yyq8ns0qr.png)

## Attach Database

Create an RDS database threw AWS Web Console, set VPC and Security Group.

Generate username and password input into web console, and note them to add to your Rails' encrypted credentials.

```bash
make rds-password
```

## Configure Rails

Get AWS Credentials.

```bash
make my-app-s3-keys
```

Load S3 & RDS credentials into Rails encrypted credentials.

```bash
cd ..; cd my-rails-app # Go over to App Repo
EDITOR="code --wait" bin/rails credentials:edit
```

```yaml
production:
  database:
    username: XXXXXXXX
    password: XXXXXXXXXXXXXXX
  aws:
    access_key_id: XXXXXXXXXXX
    secret_access_key: XXXXXXXXXXX/XXXX
```

Edit `config/storage_production.yaml`

```yaml
amazon_production:
  service: S3
  access_key_id: <%= Rails.application.credentials.production&.dig(:aws, :access_key_id) %>
  secret_access_key: <%= Rails.application.credentials.production&.dig(:aws, :secret_access_key) %>
  region: us-east-1
  bucket: platform-staging-booking-pro-bucket
```

Edit `config/database.yml`

```yaml
production:
  <<: *default
  adapter: postgresql
  encoding: unicode
  database: your_database_name
  username: <%= Rails.application.credentials.dig(:production, :database, :username) %>
  password: <%= Rails.application.credentials.dig(:production, :database, :password) %>
  host: [check aws web console]
  port: 5432
```

Grab the Rails Master Key from ENV or `config/credentials.yml.enc` (which is typically kept private via .gitignore) and add this single Rails Maser Key to K8s as a secret.

```bash
cd ..; cd prod # Go back to Infrastructure Repo
make my-app-rails-master-key-secret
```

Setup Rails to Work Behind a Terminating Load Balancer, edit `config/production.rb`

```rb
config.assume_ssl = true
```

## Configure Rails Metrics

Locate the generated snippets in `/snippets/your-app` and update the following files in your Rails app:

* `/config/initializers/yabeda_prometheus.rb`

* `config.ru`

* `Gemfile`

From your IaC Repo, link the Monitor and Dashboard's into

* `k8s/monitoring/configs/kustomization.yaml`

After you deploy the updates, you can view the new Rails Dashboards:

```bash
make dashboard
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p8mkf65x0yoqlnsa0azc.png)