Skip to content

Instantly share code, notes, and snippets.

@justisGipson
Last active June 27, 2024 12:46
Show Gist options
  • Select an option

  • Save justisGipson/26f576281a1371d4c9613bda3ec44d9a to your computer and use it in GitHub Desktop.

Select an option

Save justisGipson/26f576281a1371d4c9613bda3ec44d9a to your computer and use it in GitHub Desktop.
beanstalk dummy files

Allows for the inclusion of custom conf files overrides some of the default nginx settings for beanstalk


# Elastic Beanstalk Nginx Configuration File - UPDATED 2023-12-04

user                    nginx;
error_log               /var/log/nginx/error.log warn;
pid                     /var/run/nginx.pid;
worker_processes        auto;
worker_rlimit_nofile    31485;

events {
    worker_connections  1024;
}

http {
    server_tokens off;

    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    include       conf.d/*.conf;

    map $http_upgrade $connection_upgrade {
        default     "upgrade";
    }

    proxy_buffer_size          128k;
    proxy_buffers              4 256k;
    proxy_busy_buffers_size    256k;
    large_client_header_buffers 4 16k;

    server {
        listen        80 default_server;
        access_log    /var/log/nginx/access.log main;

        client_header_timeout 60;
        client_body_timeout   60;
        keepalive_timeout     60;
        # gzip not on by default
        gzip                  on;
        gzip_comp_level       4;
        gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;

        # Include the Elastic Beanstalk generated locations
        include conf.d/elasticbeanstalk/*.conf;
    }
}
---
###################################
###################################
#                                 #
#    EBS DEPLOY GITHUB ACTION     #
#        DEV AND PROD ENVS        #
#              AND                #
#        CONTAINER REGISTRY       #
#          IMAGE PUBLISH          #
#                                 #
###################################
###################################

name: Elastic Beanstalk API Deploys

# Documentation:
# https://help.github.com/en/articles/workflow-syntax-for-github-actions
# https://docs.github.com/en/actions/learn-github-actions/contexts#github-context
#
# Actions:
# https://github.com/actions/checkout
# https://github.com/rtCamp/action-slack-notify
# https://github.com/actions/setup-node
# https://github.com/gerred/current-time
# https://github.com/frabert/replace-string-action
# https://github.com/einaregilsson/beanstalk-deploy
# https://github.com/rtCamp/action-slack-notify

on:
  push:
    branches:
      - dev
      - main

jobs:
  image_push:
    name: Github Container Registry Push
    if: ${{ github.ref == 'refs/heads/dev' }}
    concurrency:
      group: image_push-${{ github.ref }}
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        env:
          DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
          DOCKER_HUB_USERNAME: ${{ secrets.DOCKER_HUB_USERNAME }}
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: API env for testing
        run: |
          touch .env
          echo NODE_ENV=testing >> .env
          echo HOST=${{ secrets.TESTING_HOST }} >> .env
          echo PORT=${{ secrets.TESTING_PORT }} >> .env
          echo POSTGRES_HOST=${{ secrets.POSTGRES_HOST }} >> .env
          echo POSTGRES_PORT=${{ secrets.POSTGRES_PORT }} >> .env
          echo POSTGRES_USER=${{ secrets.POSTGRES_USER }} >> .env
          echo POSTGRES_PASSWORD=${{ secrets.POSTGRES_PASSWORD }} >> .env
          echo POSTGRES_DB=${{ secrets.POSTGRES_DB }} >> .env
          # echo rest of vars needed to run tests

      - name: Container Build & Image Tag
        id: container_build
        run: |
          docker compose build <SERVICE NAME>
          docker tag <CONTAINER NAME>:latest  ghcr.io/<GITHUB ORG NAME>/<CONTAINER NAME>

      - name: GitHub Container Registry Auth
        id: ghcr_auth
        run:
          echo ${{ secrets.GITHUB_TOKEN }} | docker login ghcr.io -u $
          --password-stdin

      - name: Image Push
        id: image_push
        run: docker push ghcr.io/<GITHUB ORG NAME>/<CONTAINER NAME>:latest

      - name: Slack Notification
        if: always()
        uses: rtCamp/action-slack-notify@v2
        env:
          SLACK_CHANNEL: ci
          SLACK_COLOR: ${{ job.status }}
          SLACK_FOOTER: ''
          SLACK_LINK_NAMES: true
          SLACK_MESSAGE: 'Image published on ghcr'
          SLACK_USERNAME: <SLACK BOT USERNAME>
          SLACK_WEBHOOK: ${{ secrets.CI_SLACK_WEBHOOK }}

  dev_deploy:
    # runs on push events to dev
    name: dev/test deploy
    if: ${{ github.ref == 'refs/heads/dev' }}
    # cancel workflow if currently running
    concurrency:
      group: dev_deploy-${{ github.ref }}
      cancel-in-progress: true
    runs-on: ubuntu-latest
    env:
      NODE_ENV: 'production'
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Node Setup
        uses: actions/setup-node@v4
        with:
          node-version: 16.17.0

      - name: Cache node modules
        id: cache-npm
        uses: actions/cache@v3
        env:
          cache-name: cache-node-modules
        with:
          # npm cache files are stored in `~/.npm` on Linux/macOS
          path: ~/.npm
          key: ${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
          restore-keys: |
            ${{ env.cache-name }}-

      - if: ${{ steps.cache-npm.outputs.cache-hit != 'true' }}
        name: List the state of node modules
        continue-on-error: true
        run: npm list

      - name: TSC Install
        run: |
          npm install -g typescript
          tsc -v

      - name: Dependency Install
        run: npm install --production=false

      - name: Compile Application
        run: npm run compile

      - name: Generate Bundle
        run: zip -r deploy.zip . -x '.*git*'

      - name: Grab Timestamp
        uses: gerred/actions/current-time@master
        id: current-time

      - name: Format Timestamp
        uses: frabert/replace-string-action@master
        id: format-time
        with:
          pattern: '[:\.]+'
          string: '${{ steps.current-time.outputs.time }}'
          replace-with: '-'
          flags: 'g'

      - name: Elastic Beanstalk Dev Deploy
        uses: einaregilsson/beanstalk-deploy@v21
        with:
          aws_access_key: ${{ secrets.AWS_EB_ACCESS_KEY }}
          aws_secret_key: ${{ secrets.AWS_EB_SECRET_KEY }}
          application_name: ${{ secrets.AWS_EB_APP_NAME }}
          deployment_package: deploy.zip
          environment_name: ${{ secrets.AWS_EB_APP_ENV_DEV }}
          region: us-east-1
          version_label:
            '<DESIRED APP LABEL> -${{ steps.format-time.outputs.replaced }}'

      - name: Get Commit Message
        id: deploy_message
        run: |
          echo "::setOutput name=commit_msg::$(git log --format=%B -n 1 $(git log -1 --pretty=format:%h))"
          echo "::setOutput name=commit_sha::$(git log -1 --pretty=format:%H)"

      - name: Slack Notification
        if: always()
        uses: rtCamp/action-slack-notify@v2
        env:
          SLACK_CHANNEL: deploy-release
          SLACK_COLOR: ${{ job.status }}
          SLACK_FOOTER: ''
          SLACK_LINK_NAMES: true
          SLACK_MESSAGE: ${{ steps.deploy_message.outputs.commit_msg }}
          SLACK_USERNAME: <SLACK BOT USERNAME>
          SLACK_WEBHOOK: ${{ secrets.DEPLOY_SLACK_WEBHOOK }}

  prod_deploy:
    # should only run on push events to main
    name: prod deploy
    if: ${{ github.ref == 'refs/heads/main' }}
    # cancel workflow if currently running
    concurrency:
      group: prod_deploy-${{ github.ref }}
      cancel-in-progress: true
    runs-on: ubuntu-latest
    env:
      NODE_ENV: 'production'
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Node Setup
        uses: actions/setup-node@v4
        with:
          node-version: 16.17.0

      - name: Cache node modules
        id: cache-npm
        uses: actions/cache@v3
        env:
          cache-name: cache-node-modules
        with:
          # npm cache files are stored in `~/.npm` on Linux/macOS
          path: ~/.npm
          key: ${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
          restore-keys: |
            ${{ env.cache-name }}-

      - if: ${{ steps.cache-npm.outputs.cache-hit != 'true' }}
        name: List the state of node modules
        continue-on-error: true
        run: npm list

      - name: TSC Install
        run: |
          npm install -g typescript
          tsc -v

      - name: Dependency Install
        run: npm install --production=false

      - name: Compile Application
        run: npm run compile # "compile": "tsc -p .",

      - name: Source Map Upload to Bugsnag
        run: npm run postbuild # "postbuild": "node lib/scripts/upload-bugsnag-sourcemaps.js",

      - name: Generate Bundle
        run: zip -r deploy.zip . -x '.*git*'

      - name: Grab Timestamp
        uses: gerred/actions/current-time@master
        id: current-time

      - name: Format Timestamp
        uses: frabert/replace-string-action@master
        id: format-time
        with:
          pattern: '[:\.]+'
          string: '${{ steps.current-time.outputs.time }}'
          replace-with: '-'
          flags: 'g'

      - name: Elastic Beanstalk Prod Deploy
        uses: einaregilsson/beanstalk-deploy@v21
        with:
          aws_access_key: ${{ secrets.AWS_EB_ACCESS_KEY }}
          aws_secret_key: ${{ secrets.AWS_EB_SECRET_KEY }}
          application_name: ${{ secrets.AWS_EB_APP_NAME }}
          deployment_package: deploy.zip
          environment_name: ${{ secrets.AWS_EB_APP_ENV_PROD }}
          region: us-east-1
          version_label:
            '<DESIRED APP -${{ steps.format-time.outputs.replaced }}'

      - name: Get Commit Message
        id: deploy_message
        run: |
          echo "::setOutput name=commit_msg::$(git log --format=%B -n 1 $(git log -1 --pretty=format:%h))"
          echo "::setOutput name=commit_sha::$(git log -1 --pretty=format:%H)"

      - name: Slack Notification
        if: always()
        uses: rtCamp/action-slack-notify@v2
        env:
          SLACK_CHANNEL: deploy-release
          SLACK_COLOR: ${{ job.status }}
          SLACK_FOOTER: ''
          SLACK_LINK_NAMES: true
          SLACK_MESSAGE: ${{ steps.deploy_message.outputs.commit_msg }}
          SLACK_USERNAME: <SLACK BOT USERNAME>
          SLACK_WEBHOOK: ${{ secrets.DEPLOY_SLACK_WEBHOOK }}
# add/remove metrics as needed
files:
  "/opt/aws/amazon-cloudwatch-agent/bin/config.json":
    mode: "00600"
    owner: root
    group: root
    content: |
      {
        "metrics": {
          "aggregation_dimensions": [
            ["InstanceId"],
            ["AutoScalingGroupName"],
            ["ImageId"],
            ["InstanceType"],
            ["PrivateIpAddress"]
          ],
          "append_dimensions": {
            "AutoScalingGroupName": "${aws:AutoScalingGroupName}",
            "ImageId": "${aws:ImageId}",
            "InstanceId": "${aws:InstanceId}",
            "InstanceType": "${aws:InstanceType}",
          },
          "metrics_collected": {
            "cpu": {
              "measurement": [
                "cpu_time_active",
                "cpu_time_guest",
                "cpu_time_guest_nice",
                "cpu_time_idle",
                "cpu_time_iowait",
                "cpu_time_irq",
                "cpu_time_nice",
                "cpu_time_softirq",
                "cpu_time_steal",
                "cpu_time_system",
                "cpu_time_user",
                "cpu_usage_active",
                "cpu_usage_guest",
                "cpu_usage_guest_nice",
                "cpu_usage_idle",
                "cpu_usage_iowait",
                "cpu_usage_irq",
                "cpu_usage_nice",
                "cpu_usage_softirq",
                "cpu_usage_steal",
                "cpu_usage_system",
                "cpu_usage_user"
              ],
              "metrics_collection_interval": 60,
              "statistic": [
                "Average",
                "Minimum",
                "Maximum",
                "Sum",
                "SampleCount"
              ]
            },
            "disk": {
              "measurement": [
                "disk_free",
                "disk_inodes_free",
                "disk_inodes_total",
                "disk_inodes_used",
                "disk_total",
                "disk_used",
                "disk_used_percent"
              ],
              "metrics_collection_interval": 60,
              "resources": [
                "*"
              ],
              "statistic": [
                "Average",
                "Minimum",
                "Maximum",
                "Sum",
                "SampleCount"
              ]
            },
            "diskio": {
              "measurement": [
                "diskio_io_time",
                "diskio_iops_in_progress",
                "diskio_read_bytes",
                "diskio_read_time",
                "diskio_reads",
                "diskio_write_bytes",
                "diskio_write_time",
                "diskio_writes"
              ],
              "metrics_collection_interval": 60,
              "resources": [
                "*"
              ],
              "statistic": [
                "Average",
                "Minimum",
                "Maximum",
                "Sum",
                "SampleCount"
              ]
            },
            "mem": {
              "measurement": [
                "mem_active",
                "mem_available",
                "mem_available_percent",
                "mem_buffered",
                "mem_cached",
                "mem_free",
                "mem_inactive",
                "mem_used",
                "mem_used_percent"
              ],
              "metrics_collection_interval": 60,
              "statistic": [
                "Average",
                "Minimum",
                "Maximum",
                "Sum",
                "SampleCount"
              ]
            },
            "net": {
              "measurement": [
                "bytes_in",
                "bytes_out",
                "drop_in",
                "drop_out",
                "err_in",
                "err_out",
                "packets_in",
                "packets_out"
              ],
              "metrics_collection_interval": 60,
              "resources": [
                "eth0"
              ],
              "statistic": [
                "Average",
                "Minimum",
                "Maximum",
                "Sum",
                "SampleCount"
              ]
            },
            "netstat": {
              "measurement": [
                "netstat_tcp_close",
                "netstat_tcp_close_wait",
                "netstat_tcp_closing",
                "netstat_tcp_established",
                "netstat_tcp_fin_wait1",
                "netstat_tcp_fin_wait2",
                "netstat_tcp_last_ack",
                "netstat_tcp_listen",
                "netstat_tcp_none",
                "netstat_tcp_syn_recv",
                "netstat_tcp_syn_sent",
                "netstat_tcp_time_wait",
                "netstat_udp_socket"
              ],
              "metrics_collection_interval": 60,
              "statistic": [
                "Average",
                "Minimum",
                "Maximum",
                "Sum",
                "SampleCount"
              ]
            },
            "processes": {
              "measurement": [
                "processes_blocked",
                "processes_dead",
                "processes_idle",
                "processes_paging",
                "processes_running",
                "processes_sleeping",
                "processes_stopped",
                "processes_total",
                "processes_total_threads",
                "processes_wait",
                "processes_zombies"
              ],
              "metrics_collection_interval": 60,
              "statistic": [
                "Average",
                "Minimum",
                "Maximum",
                "Sum",
                "SampleCount"
              ]
            },
            "swap": {
              "measurement": [
                "swap_free",
                "swap_used",
                "swap_used_percent"
              ],
              "metrics_collection_interval": 60,
              "statistic": [
                "Average",
                "Minimum",
                "Maximum",
                "Sum",
                "SampleCount"
              ]
            },
            "ethtool": {
              "interface_include": [
                "eth0"
              ],
              "metrics_include": [
                "bw_in_allowance_exceeded",
                "bw_out_allowance_exceeded",
                "conntrack_allowance_exceeded",
                "linklocal_allowance_exceeded",
                "pps_allowance_exceeded",
                "rx_packets",
                "tx_packets"
              ],
              "metrics_collection_interval": 60,
              "statistic": [
                "Average",
                "Minimum",
                "Maximum",
                "Sum",
                "SampleCount"
              ]
            },
            "collect_list": [
              {
                "name": "syslog",
                "parameters": {
                  "file_path": "/var/log/messages",
                  "log_group_name": "${my_log_group}",
                  "log_stream_name": "${instance_id}-syslog",
                  "timezone": "UTC"
                }
              },
              {
                "name": "applog",
                "parameters": {
                  "file_path": "/path/to/my/app.log",
                  "log_group_name": "${my_log_group}",
                  "log_stream_name": "${instance_id}-applog",
                  "timezone": "Local"
                }
              }
            ]
          }
        }
      }

container_commands:
  start_cloud_watch_agent:
    command: /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -c file:/opt/aws/amazon-cloudwatch-agent/bin/config.json -s
branch-defaults:
  dev:
    environment: <DEV ENVIRONMENT>
    group_suffix: null
  main:
    environment: <PROD ENVIRONMENT>
    group_suffix: null
environment-defaults:
  <DEV ENVIRONMENT>:
    branch: dev
    repository: null
  <PROD ENVIRONMENT>:
    branch: main
    repository: null
global:
  application_name: <APPLICATION NAME FROM BEANSTALK>
  branch: null
  default_ec2_keyname: <EC2 KEY NAME>
  default_platform: <DEFAULT PLATFORM>
  default_region: <DEFAULT REGION>
  include_git_submodules: true
  profile: <AWS CLI PROFILE>
  sc: git
  workspace_type: Application
web: npm start # or whatever the start command is
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment