Skip to content
Merged
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
38 changes: 38 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 2
versioning-strategy: "auto"
groups:
all-dependencies:
patterns:
- "*"
commit-message:
prefix: "chore"
prefix-development: "chore"
include: "scope"

- package-ecosystem: "pip"
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 2
versioning-strategy: "auto"
groups:
all-dependencies:
patterns:
- "*"
commit-message:
prefix: "chore"
prefix-development: "chore"
include: "scope"

- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 5

108 changes: 108 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
name: CI

on:
push:
branches:
- main
pull_request:
workflow_dispatch:

# Required for AWS OIDC authentication
permissions:
id-token: write
contents: read

jobs:
test:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v5

- name: Set up Node.js
uses: actions/setup-node@v6
with:
node-version: '22'

- name: Install uv
uses: astral-sh/setup-uv@v7

- name: Install Python dependencies
run: uv sync

- name: Install Node dependencies
run: npm install

- name: Run pre-commit
run: uv run pre-commit run --all-files

- name: Synthesize CDK stack
env:
AWS_ACCESS_KEY_ID: AKIAIOSFODNN7EXAMPLE
AWS_SECRET_ACCESS_KEY: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
AWS_REGION: us-east-1
AWS_DEFAULT_REGION: us-east-1
DATA_ACCESS_ROLE_ARN: arn:aws:iam::123456789012:role/DummyDataAccessRole

run: uv run npx cdk synth --all

# Example deployment job - demonstrates how to deploy using GitHub environments
# To use:
# 1. Create a GitHub environment (Settings > Environments)
# 2. Configure environment variables in that environment
# 3. Set up AWS OIDC provider and IAM role with trust relationship to GitHub
# 4. Customize as needed
deploy:
if: github.event_name == 'workflow_dispatch'
needs: test
runs-on: ubuntu-latest

# Reference your GitHub environment here
# This pulls in environment-specific variables and protection rules
environment:
name: production # Change to your environment name
url: ${{ steps.deploy.outputs.url }} # Optional: link to deployed application

steps:
- name: Checkout code
uses: actions/checkout@v5

- name: Set up Node.js
uses: actions/setup-node@v6
with:
node-version-file: '.nvmrc'

- name: Install uv
uses: astral-sh/setup-uv@v7

- name: Install Python dependencies
run: uv sync

- name: Install Node dependencies
run: npm install

- name: Configure AWS credentials from OIDC
uses: aws-actions/configure-aws-credentials@v4
with:
# This role ARN should be stored as an environment variable in GitHub
# The role must have a trust policy allowing GitHub OIDC authentication
role-to-assume: ${{ vars.AWS_DEPLOYMENT_ROLE_ARN }}
aws-region: ${{ vars.AWS_REGION }}
# Optional: role session name for CloudTrail auditing
role-session-name: GitHubActions-${{ github.run_id }}

- name: Deploy CDK stack
id: deploy
env:
# Pull additional configuration from GitHub environment variables
# These should be set in Settings > Environments > [environment-name] > Variables
DATA_ACCESS_ROLE_ARN: ${{ vars.DATA_ACCESS_ROLE_ARN }}
# Add any other environment-specific variables here
# PROJECT_ID: ${{ vars.PROJECT_ID }}
# STAGE: ${{ vars.STAGE }}
run: |
uv run npx cdk deploy --all --require-approval never

# Optional: capture and output deployment URLs
# echo "url=https://your-api-url.com" >> $GITHUB_OUTPUT
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -168,3 +168,4 @@ node_modules/
.pgdata

.ruff_cache/
.envrc
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
22.20.0
13 changes: 5 additions & 8 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
repos:
- repo: https://github.com/PyCQA/isort
rev: 5.13.2
- repo: https://github.com/tsvikas/sync-with-uv
rev: v0.4.0
hooks:
- id: isort
language_version: python
args: ["-m", "3","--trailing-comma", "-l", "88"]

- id: sync-with-uv
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.4.4
rev: v0.14.3
hooks:
- id: ruff
args: ["--fix"]
- id: ruff-format

- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.10.0
rev: v1.18.2
hooks:
- id: mypy
language_version: python
Expand Down
1 change: 1 addition & 0 deletions .python-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.12
84 changes: 68 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,59 +6,111 @@ Template repository to deploy [eoapi](https://eoapi.dev) on AWS using the [eoapi

- python >=3.9
- docker
- node >=14
- node >=18
- AWS credentials environment variables configured to point to an account.
- **Optional** a `config.yaml` file to override the default deployment settings defined in `config.py`.

## Installation

Install python dependencies with
Install python dependencies with `uv`

```
python -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txt
```bash
uv sync
```

And node dependencies with

```
```bash
npm install
```

Verify that the `cdk` CLI is available. Since `aws-cdk` is installed as a local dependency, you can use the `npx` node package runner tool, that comes with `npm`.

```
```bash
npx cdk --version
```

## Deployment

First, synthesize the app
### Configuration

You can configure your eoAPI deployment using either environment variables (defined manually or in a `.env` file) or a configuration yaml file (see [config.py](./infrastructure/config.py) for more details on all of the configurable parameters.

Feel free to add or subtract from these configuration parameters to suit your needs!

To start you can copy [config.yaml.example](./config.yaml.example) to config.yaml:

```bash
cp config.yaml.example config.yaml
```
npx cdk synth --all

Then update the values according to your preferences.
Be sure to set `project_id` to something recognizable and to look closely at all of the components that you are including with each setting.

### AWS credentials

For the deployment steps to work, you will need to have your environment configured with your AWS account credentials.
There are lots of ways to do this so choose whatever method you want to define `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `AWS_REGION`, dtc.

### Synthesize the CDK Stack

You can test your deployment configuration without deploying any actual resources to AWS by using the `cdk synth` command.

```bash
uv run npx cdk synth --all
```

Then, deploy

```bash
uv run npx cdk deploy --all --require-approval never
```
npx cdk deploy --all --require-approval never
```

## GitHub Actions

The repository includes a CI workflow (`.github/workflows/ci.yml`) that runs on every push to `main` and on all pull requests. The workflow:

1. Sets up the build environment with Node.js 22 and Python (via `uv`)
2. Installs all project dependencies (both Python and Node)
3. Runs pre-commit hooks to check code quality and formatting
4. Synthesizes the CDK stack to validate the infrastructure-as-code configuration

This ensures that all code changes pass quality checks and that the CDK stack can be successfully synthesized before merging.

### Automated Deployment

The workflow also includes an example `deploy` job that demonstrates how to automatically deploy your eoAPI stack to AWS using GitHub Actions. This job showcases:

- **AWS OIDC authentication** - Secure, keyless authentication using GitHub's OIDC provider
- **GitHub Environments** - Pulling deployment configuration from environment-specific variables
- **Protection rules** - Leveraging GitHub's environment protection features (approvals, branch restrictions)

> [!NOTE]
> This deployment job is a basic starting point and can be triggered manually via `workflow_dispatch`. You should tailor it to match your specific deployment strategy, such as:
>
> - Adding multiple environments (staging, production, etc.)
> - Implementing deployment approval workflows
> - Adding post-deployment validation or smoke tests
> - Customizing environment variables for different stages
> - Integrating with monitoring or notification systems

To set up AWS OIDC authentication for GitHub Actions, refer to the [AWS documentation on configuring OIDC with GitHub](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc.html) and the [GitHub documentation for Configuring OpenID Connect in AWS](https://docs.github.com/en/actions/how-tos/secure-your-work/security-harden-deployments/oidc-in-aws).

## Docker

Before deploying the application on the cloud, you can start by exploring it with a local *Docker* deployment

```
```bash
docker compose up
```

Once the applications are *up*, you'll need to add STAC **Collections** and **Items** to the PgSTAC database. If you don't have, you can use the follow the [MAXAR open data demo](https://github.com/vincentsarago/MAXAR_opendata_to_pgstac) (or get inspired by the other [demos](https://github.com/developmentseed/eoAPI/tree/main/demo)).

Then you can start exploring your dataset with:

- the STAC Metadata service [http://localhost:8081](http://localhost:8081)
- the Raster service [http://localhost:8082](http://localhost:8082)
- the browser UI [http://localhost:8085](http://localhost:8085)
- the STAC Metadata service [http://localhost:8081](http://localhost:8081)
- the Raster service [http://localhost:8082](http://localhost:8082)
- the Vector service [http://localhost:8083](http://localhost:8083)
- the browser UI [http://localhost:8085](http://localhost:8085)

If you've added a vector dataset to the `public` schema in the Postgres database, they will be available through the **Vector** service at [http://localhost:8083](http://localhost:8083).
6 changes: 3 additions & 3 deletions config.yaml.example
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
project_id: "eoapi-yo"
stage: "production"
project_id: "eoapi"
stage: "test"
tags: {owner: user_a}

# Ingest Options
Expand All @@ -12,7 +12,7 @@ db_allocated_storage: 5
public_db_subnet: False

# VPC Options
nat_gateway_count: 4
nat_gateway_count: 0

# Bastion Host Options
bastion_host: True
Expand Down
19 changes: 8 additions & 11 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,8 @@ services:
- database

stac:
# Note:
# the official ghcr.io/stac-utils/stac-fastapi-pgstac image uses python 3.8 and uvicorn
# which is why here we use a custom Dockerfile using python 3.11 and gunicorn
build:
context: .
dockerfile: dockerfiles/Dockerfile.stac
platform: linux/amd64
image: ghcr.io/stac-utils/stac-fastapi-pgstac:6.0.2
ports:
- "${MY_DOCKER_IP:-127.0.0.1}:8081:8081"
environment:
Expand All @@ -46,7 +42,7 @@ services:
- DB_MAX_CONN_SIZE=10
depends_on:
- database
command: bash -c "bash /tmp/scripts/wait-for-it.sh -t 120 -h database -p 5432 && /start.sh"
command: bash -c "bash /tmp/scripts/wait-for-it.sh -t 120 -h database -p 5432 && uvicorn stac_fastapi.pgstac.app:app --host 0.0.0.0 --port 8081 --workers 1"
volumes:
- ./dockerfiles/scripts:/tmp/scripts

Expand Down Expand Up @@ -95,12 +91,12 @@ services:
- AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}
depends_on:
- database
command: bash -c "bash /tmp/scripts/wait-for-it.sh -t 120 -h database -p 5432 && gunicorn -k uvicorn.workers.UvicornWorker titiler.pgstac.main:app --bind 0.0.0.0:8082 --workers 1"
command: bash -c "bash /tmp/scripts/wait-for-it.sh -t 120 -h database -p 5432 && uvicorn titiler.pgstac.main:app --host 0.0.0.0 --port 8082 --workers 5"
volumes:
- ./dockerfiles/scripts:/tmp/scripts

vector:
image: ghcr.io/developmentseed/tipg:0.6.3
image: ghcr.io/developmentseed/tipg:1.2.1
ports:
- "${MY_DOCKER_IP:-127.0.0.1}:8083:8083"
environment:
Expand All @@ -121,14 +117,15 @@ services:
- POSTGRES_PORT=5432
- DB_MIN_CONN_SIZE=1
- DB_MAX_CONN_SIZE=10
command: bash -c "bash /tmp/scripts/wait-for-it.sh -t 120 -h database -p 5432 && /start.sh"
command:
bash -c "bash /tmp/scripts/wait-for-it.sh database:5432 --timeout=30 && uvicorn tipg.main:app --host 0.0.0.0 --port 8081 --workers 5"
depends_on:
- database
volumes:
- ./dockerfiles/scripts:/tmp/scripts

database:
image: ghcr.io/stac-utils/pgstac:v0.8.5
image: ghcr.io/stac-utils/pgstac:v0.9.8
environment:
- POSTGRES_USER=username
- POSTGRES_PASSWORD=password
Expand Down
10 changes: 0 additions & 10 deletions dockerfiles/Dockerfile.stac

This file was deleted.

Loading