Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save glaszczak/7daff15fa28043d0d2900315f2f650ff to your computer and use it in GitHub Desktop.
Save glaszczak/7daff15fa28043d0d2900315f2f650ff to your computer and use it in GitHub Desktop.

How to deploy reaction commerce on AWS using terraform

STATUS: IN PROGRESS

Reaction Commerce Repository

Steps that has to be done

  1. Create MongoDB cluster and connect it with AWS
  2. Create Hydra PostgreSQL database AWS
  3. Building Docker images and pushing to ECR (AWS)
  4. Setup Load Balancers
  5. Setup ECS (AWS) cluster
  6. Deploy Reaction Commerce API, Hydra's API, Identity, Admin panel and Storefront


Create Local Variables

MongoDB Atlas Variables

ATLAS_PUBLIC_KEY > This is the MongoDB Atlas API public_key which should be created by user > Go to MongoDB Atlas account > Projects > Access Manager > Api Keys tab > Create API Key or select existing

ATLAS_PRIVATE_KEY > Same section as above

ATLAS_ORGANIZATION_ID > Go to MongoDB Atlas account > Projects > Settings

ATLAS_CIDR_BLOCK > Go to MongoDB Atlas account > Projects > Select Project > Network Access > Peering tab > Add Peering Connection > Select aws > copy VPC CIDR

AWS Variables

AWS_DEFAULT_VPD_CIDR > Go to AWS Console > Services > VPC > Your VPCs (left menu) > Select 'IPv4 CIDR' field for specific VPC

AWS_DEFAULT_VPC_ID > Go to AWS Console > Services > VPC > Your VPCs (left menu) > Select 'VPC ID' field for specific VPC

AWS_ACCOUNT_ID > Go to AWS Console > Select 'My Account' (top dropdown mentu for current user) > Copy 'Account Id'

PostgreSQL Variables

POSTGRES_IDENTIFIER > Set itentifier - can be the same as database name

POSTGRES_DB_NAME > Set database name

YOUR_USERNAME > Set unique user name

YOUR_PASSWORD > Set unique user password

POSTGRES_DB_INSTANCE_NAME > Unique name cross all DB instances owned by current AWS account

POSTGRES_DB_PASSWORD > Set database password

POSTGRES_PORT > Default port for PostgreSQL: 5432


Some Arguments Explenation

local-exec commands > Get commands to build docker images based on each repository > Go to AWS Console > Services > ECR > Select repository > View push commands


Final Output File deploy-reaction-commerce-aws.tf

locals {
  atlas_mongo_public_key  = ATLAS_PUBLIC_KEY
  atlas_mongo_private_key = ATLAS_PRIVATE_KEY
  atlas_org_id            = ATLAS_ORGANIZATION_ID
  atlas_cidr_block        = ATLAS_CIDR_BLOCK

  aws_default_vpc_cidr = AWS_DEFAULT_VPD_CIDR
  aws_default_vpc_id   = AWS_DEFAULT_VPC_ID
  aws_account_id       = AWS_ACCOUNT_ID

  postgres_identifier    = POSTGRES_IDENTIFIER
  postgres_name          = POSTGRES_DB_NAME
  postgres_user_name     = YOUR_USERNAME
  postgres_user_password = YOUR_PASSWORD
  postgres_instance_name = POSTGRES_DB_INSTANCE_NAME
  postgres_db_password   = POSTGRES_DB_PASSWORD
  postgres_port          = POSTGRES_PORT
}

// PROVIDERS
provider "aws" {
  region                  = "eu-central-1"
  shared_credentials_file = "$HOME/.aws/credentials"
}

provider "mongodbatlas" {
  public_key  = local.atlas_mongo_public_key
  private_key = local.atlas_mongo_private_key
}

provider "postgresql" {
  host            = aws_db_instance.postgres.address
  port            = local.postgres_port
  database        = local.postgres_database_name
  username        = local.postgres_username
  password        = local.postgres_password
  sslmode         = "require"
  connect_timeout = 15
  superuser       = false
}

// MONGO SETUP
resource "mongodbatlas_project" "project_name" {
  name   = "project_name"
  org_id = local.atlas_org_id
}

resource "mongodbatlas_cluster" "cluster_name" {
  project_id = mongodbatlas_project.<project_name>.id
  name       = "cluster_name"
  num_shards = 1

  replication_factor           = 3
  provider_backup_enabled      = true
  auto_scaling_disk_gb_enabled = true
  mongo_db_major_version       = "4.2"

  provider_name               = "AWS"
  provider_volume_type        = "STANDARD"
  provider_instance_size_name = "M10"
  provider_region_name        = "EU_CENTRAL_1"
}

resource "mongodbatlas_network_container" "container_name" {
  project_id       = mongodbatlas_project.<project_name>.id
  atlas_cidr_block = local.atlas_cidr_block
  provider_name    = "AWS"
  region_name      = "EU_CENTRAL_1"
}

resource "mongodbatlas_network_peering" "network_peering_name" {
  accepter_region_name   = "EU_CENTRAL_1"
  project_id             = mongodbatlas_project.<project_name>.id
  container_id           = mongodbatlas_network_container.<container_name>.container_id
  provider_name          = "AWS"
  route_table_cidr_block = local.aws_default_vpc_cidr
  vpc_id                 = local.aws_default_vpc_id
  aws_account_id         = local.aws_account_id
}

resource "aws_vpc_peering_connection_accepter" "peer_name" {
  vpc_peering_connection_id = mongodbatlas_network_peering.reaction_network_peering.connection_id
  auto_accept               = true
}

// POSTGRES
resource "aws_security_group" "security_group_name" {
  name = "security_group_name"

  ingress {
    from_port   = local.postgres_port
    to_port     = local.postgres_port
    protocol    = "tcp"
    description = "PostgreSQL"
    cidr_blocks = ["0.0.0.0/0"] // >
  }

  ingress {
    from_port        = local.postgres_port
    to_port          = local.postgres_port
    protocol         = "tcp"
    description      = "PostgreSQL"
    ipv6_cidr_blocks = ["::/0"] // >
  }
}

resource "aws_db_instance" "instance_name" {
  allocated_storage      = 20
  storage_type           = "gp2"
  engine                 = "postgres"
  engine_version         = "12.2"
  instance_class         = "db.t2.micro"
  identifier             = local.postgres_identifier
  name                   = local.postgres_instance_name
  username               = local.postgres_user_name
  password               = local.postgres_db_password
  publicly_accessible    = true
  parameter_group_name   = "default.postgres12"
  vpc_security_group_ids = [aws_security_group.<security_group_name>.id]
  skip_final_snapshot    = true
}

resource "postgresql_role" "user_name" {
  name                = local.postgres_user_name
  login               = true
  password            = local.postgres_user_password
  encrypted_password  = true
  create_database     = true
  create_role         = true
  skip_reassign_owned = true
}

// ECR
resource "aws_ecr_repository" "rc_admin" {
  name                 = "rc_admin"
  image_tag_mutability = "MUTABLE"
}

resource "null_resource" "rc_admin_deploy" {
  depends_on = [aws_ecr_repository.rc_admin]
  provisioner "local-exec" {
    command     = <<EOT
			aws ecr get-login-password --region <reion-name> | docker login --username AWS --password-stdin $REPOSITORY_URL $$
			docker build -t rc_admin . $$
			docker tag rc_admin:latest $REPOSITORY_URL_LATEST $$
			docker push $REPOSITORY_URL_LATEST
		EOT
    working_dir = local.admin_repo_path
    environment = {
      REPOSITORY_URL        = aws_ecr_repository.rc_admin.repository_url
      REPOSITORY_URL_LATEST = "${aws_ecr_repository.rc_admin.repository_url}:latest"
    }
  }

}


resource "aws_ecr_repository" "rc_backend" {
  name                 = "rc_backend"
  image_tag_mutability = "MUTABLE"
}
resource "aws_ecr_repository" "rc_identity" {
  name                 = "rc_identity"
  image_tag_mutability = "MUTABLE"
}
resource "aws_ecr_repository" "rc_storefront" {
  name                 = "rc_storefront"
  image_tag_mutability = "MUTABLE"
}

Links

Deploying Reaction Commerce 3 on AWS ECS Tutorial

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment