DEV Community

Romaric P.
Romaric P.

Posted on

Deploy an app on AWS with GitHub, Qovery and Terraform

This ready to use tutorial show you how to deploy an application from GitHub on AWS and make it accessible via HTTPS. All of that in just a few lines of Terraform file.

Behind the scene

Behind the scene, Qovery will:

  1. Create a full Kubernetes infrastructure on your AWS account (VPC, Security Groups, Subnet, EKS...)
  2. Create Qovery resources:
    1. Organization Terraform Demo
    2. Project URL Shortener
    3. Environment production
    4. Application web app
  3. Build the web app application
  4. Push the web app container image in your ECR registry
  5. Deploy it on your EKS cluster (created by Qovery)
  6. Create an AWS Network Load Balancer
  7. Generate a TLS certificate for your app
  8. Expose publicly via HTTPS your application

It will take approximately 20 minutes to create your infrastructure and less than 5 minutes to deploy your application.

How to use

  1. Clone this repository
  2. Sign in to Qovery
  3. Install the Qovery CLI and generate an API Token with this guide.
  4. Generate your AWS credentials (Access Key ID and Secret Access Key) with this guide
  5. Open you terminal and run the following command by changing the values:
export TF_VAR_aws_access_key_id=YOUR_AWS_ACCESS_KEY_ID \
TF_VAR_aws_secret_access_key=YOUR_AWS_SECRET_ACCESS_KEY \
TF_VAR_qovery_access_token=YOUR_QOVERY_API_TOKEN \
TF_VAR_qovery_organization_id=YOUR_QOVERY_ORG_ID
Enter fullscreen mode Exit fullscreen mode
  1. Clone my URL Shortener application
  2. Edit the main.tf file and change https://github.com/evoxmusic/ShortMe-URL-Shortener.git with yours
  3. You can now run the Terraform commands
terraform init
Enter fullscreen mode Exit fullscreen mode
terraform plan
Enter fullscreen mode Exit fullscreen mode
terraform apply
Enter fullscreen mode Exit fullscreen mode
  1. Open your Qovery console to find out the HTTPS URL of your deployed app.
  2. To tear down your infrastructure and avoid unnecessary cloud costs you can run terraform destroy.

--

And here is what happened when running terraform apply

terraform apply

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated
with the following symbols:
  + create

Terraform will perform the following actions:

  # qovery_application.backend will be created
  + resource "qovery_application" "backend" {
      + auto_preview                   = false
      + build_mode                     = "BUILDPACKS"
      + buildpack_language             = "PYTHON"
      + built_in_environment_variables = [
        ] -> (known after apply)
      + cpu                            = 500
      + environment_id                 = (known after apply)
      + environment_variables          = [
          + {
              + id    = (known after apply)
              + key   = "DEBUG"
              + value = "false"
            },
          + {
              + id    = (known after apply)
              + key   = "PORT"
              + value = "3333"
            },
        ]
      + git_repository                 = {
          + branch    = "main"
          + root_path = "/"
          + url       = "https://github.com/evoxmusic/ShortMe-URL-Shortener.git"
        }
      + id                             = (known after apply)
      + max_running_instances          = 1
      + memory                         = 256
      + min_running_instances          = 1
      + name                           = "backend"
      + ports                          = [
          + {
              + external_port       = 443
              + id                  = (known after apply)
              + internal_port       = 3333
              + protocol            = "HTTP"
              + publicly_accessible = true
            },
        ]
      + state                          = "RUNNING"
    }

  # qovery_aws_credentials.my_aws_creds will be created
  + resource "qovery_aws_credentials" "my_aws_creds" {
      + access_key_id     = (sensitive value)
      + id                = (known after apply)
      + name              = "URL Shortener"
      + organization_id   = "67df37d8-6139-42eb-8c60-452395d12222"
      + secret_access_key = (sensitive value)
    }

  # qovery_cluster.my_cluster will be created
  + resource "qovery_cluster" "my_cluster" {
      + cloud_provider    = "AWS"
      + credentials_id    = (known after apply)
      + description       = "Terraform demo cluster"
      + features          = {
          + vpc_subnet = (known after apply)
        }
      + id                = (known after apply)
      + instance_type     = "T3A_MEDIUM"
      + max_running_nodes = 4
      + min_running_nodes = 3
      + name              = "Demo cluster"
      + organization_id   = "67df37d8-6139-42eb-8c60-452395d1c2ab"
      + region            = "us-east-2"
      + state             = "RUNNING"
    }

  # qovery_environment.production will be created
  + resource "qovery_environment" "production" {
      + built_in_environment_variables = [
        ] -> (known after apply)
      + cluster_id                     = (known after apply)
      + id                             = (known after apply)
      + mode                           = "DEVELOPMENT"
      + name                           = "dev"
      + project_id                     = (known after apply)
    }

  # qovery_project.my_project will be created
  + resource "qovery_project" "my_project" {
      + built_in_environment_variables = [
        ] -> (known after apply)
      + description                    = (known after apply)
      + id                             = (known after apply)
      + name                           = "URL Shortener"
      + organization_id                = "67df37d8-6139-42eb-8c60-452395d1c2ab"
    }

Plan: 5 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

qovery_aws_credentials.my_aws_creds: Creating...
qovery_aws_credentials.my_aws_creds: Creation complete after 0s [id=d2cfe19d-6381-4676-99e6-6721182f0c4c]
qovery_cluster.my_cluster: Creating...
qovery_cluster.my_cluster: Still creating... [10s elapsed]
qovery_cluster.my_cluster: Still creating... [20s elapsed]
qovery_cluster.my_cluster: Still creating... [30s elapsed]
qovery_cluster.my_cluster: Still creating... [40s elapsed]
qovery_cluster.my_cluster: Still creating... [50s elapsed]
qovery_cluster.my_cluster: Still creating... [1m0s elapsed]
qovery_cluster.my_cluster: Still creating... [1m10s elapsed]
qovery_cluster.my_cluster: Still creating... [1m20s elapsed]
qovery_cluster.my_cluster: Still creating... [1m30s elapsed]
qovery_cluster.my_cluster: Still creating... [1m40s elapsed]
qovery_cluster.my_cluster: Still creating... [1m50s elapsed]
qovery_cluster.my_cluster: Still creating... [2m0s elapsed]
qovery_cluster.my_cluster: Still creating... [2m10s elapsed]
qovery_cluster.my_cluster: Still creating... [2m20s elapsed]
qovery_cluster.my_cluster: Still creating... [2m30s elapsed]
qovery_cluster.my_cluster: Still creating... [2m40s elapsed]
qovery_cluster.my_cluster: Still creating... [2m50s elapsed]
qovery_cluster.my_cluster: Still creating... [3m0s elapsed]
qovery_cluster.my_cluster: Still creating... [3m10s elapsed]
qovery_cluster.my_cluster: Still creating... [3m20s elapsed]
qovery_cluster.my_cluster: Still creating... [3m30s elapsed]
qovery_cluster.my_cluster: Still creating... [3m40s elapsed]
qovery_cluster.my_cluster: Still creating... [3m50s elapsed]
qovery_cluster.my_cluster: Still creating... [4m0s elapsed]
qovery_cluster.my_cluster: Still creating... [4m10s elapsed]
qovery_cluster.my_cluster: Still creating... [4m20s elapsed]
qovery_cluster.my_cluster: Still creating... [4m30s elapsed]
qovery_cluster.my_cluster: Still creating... [4m40s elapsed]
qovery_cluster.my_cluster: Still creating... [4m50s elapsed]
qovery_cluster.my_cluster: Still creating... [5m0s elapsed]
qovery_cluster.my_cluster: Still creating... [5m10s elapsed]
qovery_cluster.my_cluster: Still creating... [5m20s elapsed]
qovery_cluster.my_cluster: Still creating... [5m30s elapsed]
qovery_cluster.my_cluster: Still creating... [5m40s elapsed]
qovery_cluster.my_cluster: Still creating... [5m50s elapsed]
qovery_cluster.my_cluster: Still creating... [6m0s elapsed]
qovery_cluster.my_cluster: Still creating... [6m10s elapsed]
qovery_cluster.my_cluster: Still creating... [6m20s elapsed]
qovery_cluster.my_cluster: Still creating... [6m30s elapsed]
qovery_cluster.my_cluster: Still creating... [6m40s elapsed]
qovery_cluster.my_cluster: Still creating... [6m50s elapsed]
qovery_cluster.my_cluster: Still creating... [7m0s elapsed]
qovery_cluster.my_cluster: Still creating... [7m10s elapsed]
qovery_cluster.my_cluster: Still creating... [7m20s elapsed]
qovery_cluster.my_cluster: Still creating... [7m30s elapsed]
qovery_cluster.my_cluster: Still creating... [7m40s elapsed]
qovery_cluster.my_cluster: Still creating... [7m50s elapsed]
qovery_cluster.my_cluster: Still creating... [8m0s elapsed]
qovery_cluster.my_cluster: Still creating... [8m10s elapsed]
qovery_cluster.my_cluster: Still creating... [8m20s elapsed]
qovery_cluster.my_cluster: Still creating... [8m30s elapsed]
qovery_cluster.my_cluster: Still creating... [8m40s elapsed]
qovery_cluster.my_cluster: Still creating... [8m50s elapsed]
qovery_cluster.my_cluster: Still creating... [9m0s elapsed]
qovery_cluster.my_cluster: Still creating... [9m10s elapsed]
qovery_cluster.my_cluster: Still creating... [9m20s elapsed]
qovery_cluster.my_cluster: Still creating... [9m30s elapsed]
qovery_cluster.my_cluster: Still creating... [9m40s elapsed]
qovery_cluster.my_cluster: Still creating... [9m50s elapsed]
qovery_cluster.my_cluster: Still creating... [10m0s elapsed]
qovery_cluster.my_cluster: Still creating... [10m10s elapsed]
qovery_cluster.my_cluster: Still creating... [10m20s elapsed]
qovery_cluster.my_cluster: Still creating... [10m30s elapsed]
qovery_cluster.my_cluster: Still creating... [10m40s elapsed]
qovery_cluster.my_cluster: Still creating... [10m50s elapsed]
qovery_cluster.my_cluster: Still creating... [11m0s elapsed]
qovery_cluster.my_cluster: Still creating... [11m10s elapsed]
qovery_cluster.my_cluster: Still creating... [11m20s elapsed]
qovery_cluster.my_cluster: Still creating... [11m30s elapsed]
qovery_cluster.my_cluster: Still creating... [11m40s elapsed]
qovery_cluster.my_cluster: Still creating... [11m50s elapsed]
qovery_cluster.my_cluster: Still creating... [12m0s elapsed]
qovery_cluster.my_cluster: Still creating... [12m10s elapsed]
qovery_cluster.my_cluster: Still creating... [12m20s elapsed]
qovery_cluster.my_cluster: Still creating... [12m30s elapsed]
qovery_cluster.my_cluster: Still creating... [12m40s elapsed]
qovery_cluster.my_cluster: Still creating... [12m50s elapsed]
qovery_cluster.my_cluster: Still creating... [13m0s elapsed]
qovery_cluster.my_cluster: Still creating... [13m10s elapsed]
qovery_cluster.my_cluster: Still creating... [13m20s elapsed]
qovery_cluster.my_cluster: Still creating... [13m30s elapsed]
qovery_cluster.my_cluster: Still creating... [13m40s elapsed]
qovery_cluster.my_cluster: Still creating... [13m50s elapsed]
qovery_cluster.my_cluster: Still creating... [14m0s elapsed]
qovery_cluster.my_cluster: Still creating... [14m10s elapsed]
qovery_cluster.my_cluster: Still creating... [14m20s elapsed]
qovery_cluster.my_cluster: Still creating... [14m30s elapsed]
qovery_cluster.my_cluster: Still creating... [14m40s elapsed]
qovery_cluster.my_cluster: Still creating... [14m50s elapsed]
qovery_cluster.my_cluster: Still creating... [15m0s elapsed]
qovery_cluster.my_cluster: Still creating... [15m10s elapsed]
qovery_cluster.my_cluster: Still creating... [15m20s elapsed]
qovery_cluster.my_cluster: Still creating... [15m30s elapsed]
qovery_cluster.my_cluster: Still creating... [15m40s elapsed]
qovery_cluster.my_cluster: Still creating... [15m50s elapsed]
qovery_cluster.my_cluster: Still creating... [16m0s elapsed]
qovery_cluster.my_cluster: Still creating... [16m10s elapsed]
qovery_cluster.my_cluster: Still creating... [16m20s elapsed]
qovery_cluster.my_cluster: Still creating... [16m30s elapsed]
qovery_cluster.my_cluster: Still creating... [16m40s elapsed]
qovery_cluster.my_cluster: Still creating... [16m50s elapsed]
qovery_cluster.my_cluster: Still creating... [17m0s elapsed]
qovery_cluster.my_cluster: Still creating... [17m10s elapsed]
qovery_cluster.my_cluster: Still creating... [17m20s elapsed]
qovery_cluster.my_cluster: Still creating... [17m30s elapsed]
qovery_cluster.my_cluster: Still creating... [17m40s elapsed]
qovery_cluster.my_cluster: Still creating... [17m50s elapsed]
qovery_cluster.my_cluster: Still creating... [18m0s elapsed]
qovery_cluster.my_cluster: Still creating... [18m10s elapsed]
qovery_cluster.my_cluster: Creation complete after 18m12s [id=782f5b71-5786-4ff6-895a-277cd432dc1e]
qovery_project.my_project: Creating...
qovery_project.my_project: Creation complete after 0s [id=2fa442d0-f798-46f8-9a1a-b33317c507ea]
qovery_environment.production: Creating...
qovery_environment.production: Creation complete after 0s [id=8418d920-c508-4ea2-b669-72b1fedc3a3e]
qovery_application.backend: Creating...
qovery_application.backend: Still creating... [10s elapsed]
qovery_application.backend: Still creating... [20s elapsed]
qovery_application.backend: Still creating... [30s elapsed]
qovery_application.backend: Still creating... [40s elapsed]
qovery_application.backend: Still creating... [50s elapsed]
qovery_application.backend: Still creating... [1m0s elapsed]
qovery_application.backend: Still creating... [1m10s elapsed]
qovery_application.backend: Still creating... [1m20s elapsed]
qovery_application.backend: Still creating... [1m30s elapsed]
qovery_application.backend: Still creating... [1m40s elapsed]
qovery_application.backend: Still creating... [1m50s elapsed]
qovery_application.backend: Still creating... [2m0s elapsed]
qovery_application.backend: Still creating... [2m10s elapsed]
qovery_application.backend: Still creating... [2m20s elapsed]
qovery_application.backend: Creation complete after 2m23s [id=8dd99960-939c-4328-9a38-fdea20d7db8a]

Apply complete! Resources: 5 added, 0 changed, 0 destroyed.
Enter fullscreen mode Exit fullscreen mode

I hope you liked it!

Discussion (0)