DEV Community

Cover image for Deploy a React Application to Elastic Beanstalk using GitHub Actions and Provision with Terraform
Khadga shrestha
Khadga shrestha

Posted on

Deploy a React Application to Elastic Beanstalk using GitHub Actions and Provision with Terraform

In this article, we'll explore how to provision an AWS Elastic Beanstalk application using Terraform and deploy a containerized React application using GitHub Actions.

Prerequisites

To verify your AWS credentials, use the following command:

aws sts get-caller-identity
Enter fullscreen mode Exit fullscreen mode

Terraform Configuration
After successfully setting up AWS credentials, let's create the required Terraform scripts.

Define Variables (variables.tf)
We define necessary variables in the variables.tf file as follows:

variable "aws_region" {
  description = "The AWS region to deploy resources in"
  type        = string
  default     = "us-east-1"
}

variable "application_name" {
  description = "The name of the Elastic Beanstalk application"
  type        = string
  default     = "react-app"
}
Enter fullscreen mode Exit fullscreen mode

IAM Roles and Profiles (iam.tf)
Elastic Beanstalk requires an EC2 instance profile and a service role. Define these resources in iam.tf:

resource "aws_iam_role" "eb_ec2_role" {
  name = "aws-elasticbeanstalk-ec2-role"
  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Effect = "Allow"
        Principal = { Service = "ec2.amazonaws.com" }
        Action = "sts:AssumeRole"
      }
    ]
  })
}

resource "aws_iam_instance_profile" "eb_ec2_profile" {
  name = "aws-elasticbeanstalk-ec2-profile"
  role = aws_iam_role.eb_ec2_role.name
}

resource "aws_iam_role_policy_attachment" "eb_ec2_managed_policy" {
  role       = aws_iam_role.eb_ec2_role.name
  policy_arn = "arn:aws:iam::aws:policy/AWSElasticBeanstalkWebTier"
}
Enter fullscreen mode Exit fullscreen mode

These resources attach the necessary permissions required by Elastic Beanstalk.

Security Group (sg.tf)
We also need a security group allowing HTTP traffic. Define this in sg.tf:

resource "aws_security_group" "this" {
  name        = "react-app-allow-http"
  description = "Allow HTTP inbound traffic and all outbound traffic"
  vpc_id      = data.aws_vpc.default.id
  tags = {
    Name = "react-app-sg"
  }
}

resource "aws_vpc_security_group_ingress_rule" "allow_http" {
  security_group_id = aws_security_group.this.id
  cidr_ipv4         = "0.0.0.0/0"
  from_port         = 80
  to_port           = 80
  ip_protocol       = "tcp"
}
Enter fullscreen mode Exit fullscreen mode

Elastic Beanstalk Application (ebs.tf)
Define your Elastic Beanstalk application and environment in ebs.tf:

resource "aws_elastic_beanstalk_application" "this" {
  name        = var.application_name
  description = "This is a React application deployed on AWS Elastic Beanstalk"
}

resource "aws_elastic_beanstalk_environment" "this" {
  name                = var.environment_name
  application         = aws_elastic_beanstalk_application.this.name
  solution_stack_name = var.solution_stack_name

  setting {
    namespace = "aws:autoscaling:launchconfiguration"
    name      = "InstanceType"
    value     = var.instance_type
  }

  setting {
    namespace = "aws:autoscaling:launchconfiguration"
    name      = "SecurityGroups"
    value     = aws_security_group.this.id
  }
}
Enter fullscreen mode Exit fullscreen mode

Additional configuration options can be customized within the settings block.

Deploying Terraform Configuration
To provision your resources, execute:

terraform plan
terraform apply
Enter fullscreen mode Exit fullscreen mode

You can define outputs in Terraform to display created resources.

output "ebs_application_name" {
  description = "The name of the Elastic Beanstalk application"
  value       = aws_elastic_beanstalk_application.this.name
}

output "ebs_environment_name" {
  description = "The name of the Elastic Beanstalk environment"
  value       = aws_elastic_beanstalk_environment.this.name
}
Enter fullscreen mode Exit fullscreen mode

Deploying the Application with GitHub Actions
After provisioning resources, set up deployment via GitHub Actions. Add your AWS credentials as secrets (AWS_REGION, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY) in your repository.

Create a workflow (.github/workflows/deploy.yml):

name: EBS Deployment
on:
  push:
    branches:
      - main

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Build Docker image and run unit tests
        run: |
          docker image build . -t react-app-dev -f Dockerfile.dev
          docker container run -e CI=true react-app-dev npm run test

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

      - name: Deploy to Elastic Beanstalk
        uses: einaregilsson/beanstalk-deploy@v22
        with:
          aws_access_key: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws_secret_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          application_name: dockerize-react-app
          environment_name: react-app-env
          version_label: ${{ github.sha }}
          region: ${{ secrets.AWS_REGION }}
          deployment_package: deploy.zip
          use_existing_version_if_available: true
Enter fullscreen mode Exit fullscreen mode

This workflow triggers upon pushing to the main branch, creating a deployment package and deploying your application to Elastic Beanstalk. Adjust this trigger as per your requirements.

Source Code

Thank you for reading
You can find the code at here.

source code

Top comments (1)

Collapse
 
deepak_sapkota_5064e62729 profile image
Deepak Sapkota

Seems crazy! I will definitely try one day :)