Skip to content

Terraform deployment #21

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
node_modules
.git
Terraform
30 changes: 30 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/dist
.env
.DS_Store
/uploads
/node_modules
yarn-error.log

.idea

coverage

!src/**
.terraform
*.tfstate.*
*.tfstate
.terraform.lock.*
./tsconfig.tsbuildinfo
package-lock.json
medusa-db.sql
build
.cache

.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions

.medusa
14 changes: 14 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
FROM node:20

WORKDIR /app

COPY package.json yarn.lock ./

RUN yarn global add @medusajs/medusa-cli@latest

RUN yarn install

COPY . .

# or "start" for production
CMD ["yarn", "dev"]
213 changes: 117 additions & 96 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,134 +3,155 @@
<img alt="Medusa" src="https://user-images.githubusercontent.com/7554214/153162406-bf8fd16f-aa98-4604-b87b-e13ab4baf604.png" width="100" />
</a>
</p>
<h1 align="center">
Medusa
</h1>

<h4 align="center">
<a href="https://github.com/medusajs/admin">Medusa Admin</a> |
<a href="https://www.medusajs.com">Website</a> |
<a href="https://www.medusajs.com/blog">Blog</a> |
<a href="https://www.linkedin.com/company/medusa-commerce">LinkedIn</a> |
<a href="https://twitter.com/medusajs">Twitter</a> |
<a href="https://docs.medusajs.com">Documentation</a> |
<a href="https://medusajs.notion.site/medusajs/Medusa-Home-3485f8605d834a07949b17d1a9f7eafd">Notion</a>
</h4>

<p align="center">
Medusa is an open-source headless commerce engine that enables developers to create amazing digital commerce experiences.
</p>
<p align="center">
<a href="https://github.com/medusajs/medusa/blob/master/LICENSE">
<img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="Medusa is released under the MIT license." />
</a>
<a href="https://github.com/medusajs/medusa/blob/master/CONTRIBUTING.md">
<img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat" alt="PRs welcome!" />
</a>
<a href="https://www.producthunt.com/posts/medusa"><img src="https://img.shields.io/badge/Product%20Hunt-%231%20Product%20of%20the%20Day-%23DA552E" alt="Product Hunt"></a>
<a href="https://discord.gg/xpCwq3Kfn8">
<img src="https://img.shields.io/badge/chat-on%20discord-7289DA.svg" alt="Discord Chat" />
</a>
<a href="https://twitter.com/intent/follow?screen_name=medusajs">
<img src="https://img.shields.io/twitter/follow/medusajs.svg?label=Follow%20@medusajs" alt="Follow @medusajs" />
</a>
</p>
# Medusa Backend AWS Infrastructure setup

This repository contains the infrastructure as code (IaC) setup using Terraform and Docker for deploying Medusa e-commerce platform on AWS.

## Please note
This repo is managed by the Medusa Community. Medusa does not provide official support for Docker, but we will accept fixes and documentation. Use at your own risk.
## Architecture Overview

**This project is inteded for development only at this time.**
The infrastructure setup includes:
- ECS Fargate for container orchestration
- Application Load Balancer (ALB) for traffic distribution
- ElastiCache Redis for caching
- Neon Database (external) for PostgreSQL
- Route53 for DNS management
- ACM for SSL/TLS certificates
- ECR for container registry
- VPC with public subnets across multiple AZs

The files for both the <i>Medusa server</i> and the <i>Storefront</i> are loaded in Bind Mounts allowing you to change the server functionality and have the change be hot-reloaded onto your running containers.
## Prerequisites

</p>
- AWS CLI configured with appropriate credentials
- Terraform >= 1.0
- Docker
- Domain name with Route53 hosted zone and certificate
- Database account and connection string eg. Neon DB

---
## Quick Start

## Requirements
1. Clone this repository:
```bash
git clone <repository-url>
cd medusa-infrastructure
```

To use Docker with Medusa, you should have created a Medusa project. Check out our [Quickstart](https://github.com/medusajs/medusa#quickstart) to get started.
2. Update `terraform.tfvars` with your values:
```hcl
aws_region = "your-region"
domain_name = "your-domain.com"
subdomain = "manage"
neon_db_url = "your-neon-db-url"
certificate_domain = "*.your-domain.com"
```

Additionally, you should have `docker` and `docker-compose` installed on your system.
3. Initialize Terraform:
```bash
terraform init
```

## Getting Started
4. Deploy the infrastructure:
```bash
terraform plan
terraform apply
```

To set up Medusa in a development environment with Docker, you should copy files `docker-compose.yml`, `docker-compose.override.yml, `backend/develop.sh`, and `backend/Dockerfile` to your Medusa project.
5. Build and push Docker image:
```bash
# Login to ECR
aws ecr get-login-password --region <region> | docker login --username AWS --password-stdin <aws-account-id>.dkr.ecr.<region>.amazonaws.com

Then build the images since they are not published on dockerhub. This is accomplished by adding the `--build` flag as shown below:
# Build image
docker build -t medusa-repo .

```bash
docker compose up --build
```
# Tag image
docker tag medusa-repo:latest <aws-account-id>.dkr.ecr.<region>.amazonaws.com/medusa-repo:latest

Having already built the Docker images you can run docker compose without the `--build` flag.
# Create repo
aws ecr create-repository --repository-name your-repo-name

```
docker compose up
# Push image
docker push <aws-account-id>.dkr.ecr.<region>.amazonaws.com/medusa-repo:latest

## Infrastructure Components
```

Your local Medusa setup is now running with each of the services occupying the following ports:
### Networking
- VPC with CIDR block 10.0.0.0/16
- Two public subnets across different AZs
- Internet Gateway for public internet access
- Route tables for subnet routing

<ul>
<li><b>Medusa Server</b>: 9000
<li><b>Medusa Admin</b>: 7000
<li><b>Storefront</b>: 8000
<li><b>postgres</b>: 5432
<li><b>redis</b>: 6379
</ul>
### Security
- Security groups for ALB, ECS tasks, and Redis
- IAM roles and policies for ECS tasks
- SSL/TLS certificate management

_Note: If you change the dependencies of your projects by adding new packages you can simply rebuild that package with the same tag `test` and run `docker compose up` once again to update your environment._
### Container Infrastructure
- ECS Cluster with Fargate launch type
- Auto-scaling policies based on CPU and memory utilization
- ECR repository with lifecycle policies

### Seeding your Medusa store
### Load Balancing
- Application Load Balancer
- HTTPS listener with SSL certificate
- HTTP to HTTPS redirect
- Health checks configuration

To add seed data to your medusa store run this command in a seperate
### Caching
- Redis ElastiCache cluster
- Subnet group for Redis deployment
- Security group for Redis access

```
docker exec medusa-server medusa seed -f ./data/seed.json
```
## Environment Variables

## Running Medusa with docker in production
The following environment variables are configured in the ECS task definition:
- `REDIS_URL`: Auto-generated from ElastiCache, use this in .env file
- `NODE_ENV`: Set to "production"
- `DATABASE_URL`: Provided via terraform.tfvars

This repository and each of the services contain dockerfiles for both development and production, named `Dockerfile` and `Dockerfile.prod` respectively. The `Dockerfile.prod` copies the local files from disk and builds a production ready image based on your local development progress. Your specific needs for a production like container might differ from the `Dockerfile.prod` but it should provide a template and an idea of the requirements for each of the basic services.
## Monitoring and Logging

To run the services in a production state `docker compose` is simply run with the `docker-compose.production.yml` file as well as the basic `docker-compose.yml` file as seen below. If you wish to build the production ready images and then start them run `docker compose up` with the `--build` flag as described above.
- CloudWatch Log Groups for container logs
- Container Insights enabled on ECS cluster
- ALB access logs (optional)

```
docker compose up -f docker-compose.yml -f docker-compose.production.yml up
```
## Security Considerations

`docker-compose.production.yml` contains production relevant overrides to the services described in the `docker-compose.yml` development file.
- All resources are deployed within a VPC
- Security groups limit access to required ports only
- HTTPS enforced with HTTP to HTTPS redirect
- IAM roles follow principle of least privilege
- Redis access restricted to ECS tasks

## Try it out
## Cost Optimization

```
curl -X GET localhost:9000/store/products | python -m json.tool
```
- Fargate Spot can be used for cost savings
- Auto-scaling based on demand
- ECR lifecycle policies to manage image storage
- ElastiCache instance sized appropriately

After the seed script has run you will have the following things in you database:
## Maintenance

- a User with the email: [email protected] and password: supersecret
- a Region called Default Region with the countries GB, DE, DK, SE, FR, ES, IT
- a Shipping Option called Standard Shipping which costs 10 EUR
- a Product called Cool Test Product with 4 Product Variants that all cost 19.50 EUR
### Updating the Application
1. Build new Docker image
2. Push to ECR
3. Update ECS service (automatic with latest tag)

Visit [docs.medusa-commerce.com](https://docs.medusa-comerce.com) for further guides.
### Infrastructure Updates
1. Update Terraform code
2. Run `terraform plan` to review changes
3. Apply changes with `terraform apply`

<p>
<a href="https://www.medusa-commerce.com">
Website
</a>
|
<a href="https://medusajs.notion.site/medusajs/Medusa-Home-3485f8605d834a07949b17d1a9f7eafd">
Notion Home
</a>
|
<a href="https://twitter.com/intent/follow?screen_name=medusajs">
Twitter
</a>
|
<a href="https://docs.medusa-commerce.com">
Docs
</a>
</p>
## Contributing

1. Fork the repository
2. Create your feature branch
3. Commit your changes
4. Push to the branch
5. Create a new Pull Request

## License

This project is licensed under the MIT License - see the LICENSE file for details.
23 changes: 23 additions & 0 deletions Terraform/acm.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
data "aws_route53_zone" "medusa_zone" {
name = var.domain_name
private_zone = false
}

# Fetch the existing ACM certificate
data "aws_acm_certificate" "existing_cert" {
domain = var.certificate_domain
statuses = ["ISSUED"]
most_recent = true
}

resource "aws_route53_record" "medusa_domain" {
zone_id = data.aws_route53_zone.medusa_zone.zone_id
name = local.full_domain
type = "A"

alias {
name = aws_lb.medusa_alb.dns_name
zone_id = aws_lb.medusa_alb.zone_id
evaluate_target_health = true
}
}
Loading