Migrate from Heroku to AWS in about a day.

Migrate from Heroku to AWS in about a day.

Deploy your app onto a scalable, production-grade AWS architecture, configure a "git push to deploy" CI / CD pipeline, and manage 100% of your infrastructure as code using Terraform, all in ~1 day. Migrate your first app for free!

Step 1: Connect your Git repo

Gruntwork will scan the repo, walk you through a list of migration steps, and open a pull request for each step, so you can customize everything as much as you want!

GitHub
GitHub
GitLab
GitLab
BitBucket
BitBucket
.circleci/config.yml
      
        workflows:
          test-build-push-deploy:
            jobs:
              - run_tests
              - build_docker_image:
                  requires:
                    - run_tests
              - push_docker_image:
                  requires:
                    - build_docker_image
              - deploy_docker_image_to_staging:
                  requires:
                    - push_docker_image_to_ecr
                  filters:
                    branches:
                      only: staging
              - deploy_docker_image_to_production:
                  requires:
                    - push_docker_image_to_ecr
                  filters:
                    branches:
                      only: main
      
    

Step 2: Configure CI / CD

Gruntwork will configure a CI / CD pipeline for AWS that will give you the "git push to deploy" workflow you’re used to with Heroku. You can choose to use CircleCi, GitLab, GitHub Actions, or Jenkins as the CI server to run this pipeline.

CircleCi
CircleCi
Jenkins
Jenkins
GitLab
GitLab

Step 3: Instrument your app

Gruntwork will update your app with cloud-native best practices for packaging, monitoring, logging, service discovery, secrets management, schema migrations, and more.

CloudWatch
CloudWatch
DataDog
DataDog
Prometheus and Grafana
Prometheus and Grafana
ecs-fargate-service/main.tf
  
    module "fargate_service" {
      source  = "github.com/gruntwork-io/service-catalog//ecs-service"
      version = "v0.51.0"

      service_name          = "my-heroku-app"
      launch_type           = "FARGATE"
      ecs_cluster_arn       = module.fargate_cluster.arn

      task_cpu                = 256
      task_memory             = 512
      desired_number_of_tasks = 3

      container_definitions = [
        {
          name         = "my-heroku-app"
          image        = "https://123456789012.dkr.ecr.us-east-1.amazonaws.com/my-heroku-app:v1"
          essential    = true
          portMappings = [
            {
              "hostPort"      = 3000
              "containerPort" = 3000
              "protocol"      = "tcp"
            }
          ]
        }
      ]

      domain_name = "example.your-domain.com"
    }

    module "fargate_cluster" {
      source  = "github.com/gruntwork-io/service-catalog//ecs-fargate-cluster"
      version = "v0.51.0"

      cluster_name = "my-fargate-cluster"
    }
  
  
ecs-cluster/main.tf
  
    module "ecs_service" {
      source  = "github.com/gruntwork-io/service-catalog//ecs-service"
      version = "v0.51.0"

      service_name          = "my-heroku-app"
      launch_type           = "EC2"
      ecs_cluster_arn       = module.ecs_cluster.arn

      desired_number_of_tasks = 3

      container_definitions = [
        {
          name         = "my-heroku-app"
          image        = "https://123456789012.dkr.ecr.us-east-1.amazonaws.com/my-heroku-app:v1"
          essential    = true
          cpu          = 256
          memory       = 512
          portMappings = [
            {
              "hostPort"      = 3000
              "containerPort" = 3000
              "protocol"      = "tcp"
            }
          ]
        }
      ]

      domain_name = "example.your-domain.com"
    }

    module "ecs_cluster" {
      source  = "github.com/gruntwork-io/service-catalog//ecs-cluster"
      version = "v0.51.0"

      cluster_name = "my-ecs-cluster"

      cluster_min_size      = 3
      cluster_max_size      = 10
      cluster_instance_type = "m4.large"
      cluster_instance_ami  = "ami-abcd1234"
    }
  
  
eks-cluster/main.tf
  
    module "k8s_service" {
      source  = "github.com/gruntwork-io/service-catalog//k8s-service"
      version = "v0.51.0"

      application_name       = "my-heroku-app"
      namespace              = "my-namespace"
      desired_number_of_pods = 3

      container_port  = 5000
      container_image = {
        repository = "https://123456789012.dkr.ecr.us-east-1.amazonaws.com/my-heroku-app"
        tag        = "v1"
      }

      domain_name = "example.your-domain.com"
    }

    module "eks_cluster" {
      source  = "github.com/gruntwork-io/service-catalog//eks-cluster"
      version = "v0.51.0"

      cluster_name          = "my-eks-cluster"
      kubernetes_version    = "1.20"
      cluster_instance_ami  = "ami-abcd1234"

      managed_node_group_configurations = {
        default = {
          min_size       = 3
          max_size       = 10
          instance_types = ["m4.large"]
        }
      }
    }

    provider "kubernetes" {
      host                   = module.eks_cluster.endpoint
      cluster_ca_certificate = module.eks_cluster.certificate_authority.0.data
      token                  = module.eks_cluster.kubernetes_token[0].token
    }
  
  

Step 4: Deploy to AWS

Deploy your app onto a battle-tested AWS architecture based on ECS, EKS, EC2, or Fargate. Pick from a variety of "add-ons" such as RDS (PostgreSQL, MySQL, etc), ElastiCache (Redis, Memcached), and Elasticsearch. All the infrastructure is managed as code using Terraform, Docker, and Packer, so you can customize everything!

Terraform
Terraform
Docker
Docker
Packer
Packer

Step 5: You're live!

At this point, your app is up and running in AWS and you can deploy updates any time with "git push."

Meet the Gruntwork community.

Bind
Gridpoint
Intel
Tidal Migrations
Quid
Digital Globe
Fluo
Commonplace
Jumio
Finiata
Iwoca
Healthline