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
2 changes: 1 addition & 1 deletion .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@
]
}
},
"forwardPorts": [3000],
"forwardPorts": [3000]
}
33 changes: 24 additions & 9 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,28 @@ name: CI Pipeline

on:
push:
branches: [ main ]
pull_request:
branches: [ main ]

jobs:
build-and-docker:
test-and-build:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v2
uses: actions/setup-go@v4
with:
go-version: 1.25
go-version: '1.26'

- name: Install dependencies
run: go mod tidy

- name: Run tests
run: go test -v ./...

- name: Build static Linux binary
run: |
mkdir -p output
Expand All @@ -33,20 +35,33 @@ jobs:
name: awsserver-linux-amd64
path: ./output/awsserver

- name: Set up QEMU
uses: docker/setup-qemu-action@v3

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Build Docker image (test only)
if: github.ref != 'refs/heads/main'
uses: docker/build-push-action@v6
with:
context: .
push: false
platforms: linux/amd64

- name: Log in to GitHub Container Registry
if: github.ref == 'refs/heads/main'
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Build and push Docker image
if: github.ref == 'refs/heads/main'
uses: docker/build-push-action@v6
with:
context: .
push: true
platforms: linux/amd64,linux/arm64
tags: ghcr.io/${{ github.repository_owner }}/awsserver:latest

44 changes: 26 additions & 18 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,40 +10,44 @@ jobs:

steps:
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v2
uses: actions/setup-go@v4
with:
go-version: 1.25
go-version: '1.26'

- name: Install dependencies
run: go mod tidy

- name: Build Binary
run: CGO_ENABLED=0 go build -ldflags '-extldflags "-static"' -o awsserver ./cmd/server
- name: Run tests
run: go test -v ./...

- name: Get build architecture
id: arch
run: echo "ARCH=$(uname -m)" >> $GITHUB_ENV
- name: Build binaries
run: |
mkdir -p dist
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags '-extldflags "-static"' -o dist/awsserver-linux-amd64 ./cmd/server
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -ldflags '-extldflags "-static"' -o dist/awsserver-linux-arm64 ./cmd/server
CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build -ldflags '-extldflags "-static"' -o dist/awsserver-darwin-amd64 ./cmd/server
CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 go build -ldflags '-extldflags "-static"' -o dist/awsserver-darwin-arm64 ./cmd/server

- name: Package Binary
- name: Package binaries
run: |
ARCH=${{ env.ARCH }}
TAR_NAME="awsserver-linux-${ARCH}.tar.gz"
tar -czvf ${TAR_NAME} awsserver
echo "RELEASE_FILE=${TAR_NAME}" >> $GITHUB_ENV
cd dist
for f in awsserver-*; do
tar -czvf "${f}.tar.gz" "$f"
done

- name: Upload release artifact
- name: Upload release artifacts
uses: actions/upload-artifact@v4
with:
name: awsserver-linux-${{ env.ARCH }}
path: ${{ env.RELEASE_FILE }}
name: awsserver-binaries
path: dist/*.tar.gz

- name: Upload artifact to GitHub Release
- name: Upload binaries to GitHub Release
uses: softprops/action-gh-release@v2
with:
files: ${{ env.RELEASE_FILE }}
files: dist/*.tar.gz
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Expand All @@ -54,6 +58,9 @@ jobs:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Set up QEMU
uses: docker/setup-qemu-action@v3

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

Expand All @@ -62,4 +69,5 @@ jobs:
with:
context: .
push: true
platforms: linux/amd64,linux/arm64
tags: ghcr.io/${{ github.repository_owner }}/awsserver:${{ github.ref_name }}
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
output
output
dist
8 changes: 6 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
FROM golang AS builder
FROM golang:1.26-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -ldflags '-extldflags "-static"' -o ./output/awsserver ./cmd/server

FROM alpine
FROM scratch
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=builder /app/output/awsserver /usr/local/bin/awsserver
EXPOSE 3000
USER 65534:65534
ENTRYPOINT ["/usr/local/bin/awsserver"]
124 changes: 75 additions & 49 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,60 +5,73 @@ This project provides an HTTP server using Go, which interacts with AWS Services
## Features

- Fetch decrypted parameters from AWS SSM.
- Put parameters to AWS SSM.
- Fetch secrets from AWS Secrets Manager.
- Fetch and serve files from AWS S3.
- Upload files to AWS S3.
- Fetch ECR authorization token.
- Fetch caller identity from AWS STS.
- Basic CI/CD pipeline using GitHub Actions for automatic builds and tests.
- CI/CD pipeline using GitHub Actions for automatic builds, tests, and container image publishing.

## Requirements

- Go 1.17 or later
- AWS CLI configured with necessary permissions
- Go 1.26 or later
- AWS credentials configured (e.g. `~/.aws/credentials`, environment variables, or IAM role)
- Git installed

## Container Image

Get the Container Image
```sh
docker pull ghcr.io/leneffets/awsserver:v2.0.0
docker pull ghcr.io/leneffets/awsserver:latest
```

```sh
docker pull ghcr.io/leneffets/awsserver:v1.0.0
docker pull ghcr.io/leneffets/awsserver:latest
```
The container image uses a `scratch` base (zero OS packages), runs as a non-root user, and is available for `linux/amd64` and `linux/arm64`.

## Setup

1. **Clone the repository:**

```sh
git clone git@github.com:USERNAME/REPO_NAME.git
cd REPO_NAME
git clone git@github.com:leneffets/awsserver.git
cd awsserver
```

2. **Initialize the Go module:**
2. **Install dependencies:**

```sh
go mod tidy
```

3. **Configure AWS credentials:**
## Running the Server

Ensure you have AWS credentials configured, typically in `~/.aws/credentials`.
The server binds to `0.0.0.0` by default. To start it:

## Running the Server
```sh
# Port may be changed via environment variable, default 3000
export PORT=3000

To start the HTTP server locally on port 3000, run the following command:

# Port may be changed via Environment, default 3000
export PORT=3000
go run cmd/server/main.go
# Bind address may be changed, default 0.0.0.0
export BIND_ADDRESS=127.0.0.1

go run cmd/server/main.go
```

The server shuts down gracefully on SIGINT/SIGTERM, finishing in-flight requests before stopping.

## Endpoints

### Fetch SSM Parameter
### Health Check

Fetch a decrypted parameter from AWS SSM.
- **URL:** `/healthz`
- **Method:** `GET`
- **Example:**

```sh
curl "http://localhost:3000/healthz"
```

### Fetch SSM Parameter

- **URL:** `/ssm`
- **Method:** `GET`
Expand All @@ -72,23 +85,31 @@ Fetch a decrypted parameter from AWS SSM.

### Put SSM Parameter

Put a parameter to AWS SSM.

- **URL:** `/ssm`
- **Method:** `POST`
- **Query Parameters:**
- `name`: Name of the SSM parameter to put.
- `value`: Value of the SSM parameter to put.
- `type`: Type of the SSM parameter to put. (String, SecureString)
- **Form Parameters:**
- `name`: Name of the SSM parameter.
- `value`: Value of the SSM parameter.
- `type`: Type of the SSM parameter (`String` or `SecureString`).
- **Example:**

```sh
curl -X POST -d "name=/path/to/parameter&value=somevalue&type=String" http://localhost:3000/ssm
```

### Fetch S3 File
### Fetch Secret from Secrets Manager

Fetch a file from an S3 bucket.
- **URL:** `/secrets`
- **Method:** `GET`
- **Query Parameters:**
- `name`: Name or ARN of the secret to fetch.
- **Example:**

```sh
curl "http://localhost:3000/secrets?name=my-app/db-credentials"
```

### Fetch S3 File

- **URL:** `/s3`
- **Method:** `GET`
Expand All @@ -103,8 +124,6 @@ Fetch a file from an S3 bucket.

### Upload S3 File

Upload a file to an S3 bucket.

- **URL:** `/s3`
- **Method:** `POST`
- **Query Parameters:**
Expand All @@ -118,20 +137,16 @@ Upload a file to an S3 bucket.

### Get ECR Login

Fetch an authorization token for ECR.

- **URL:** `/ecr/login`
- **Method:** `GET`
- **Example:**

```sh
curl "http://localhost:3000/ecr/login" | docker login --username AWS --password-stdin aws-account-id.dkr.ecr.eu-central-1.amazonaws.com
curl "http://localhost:3000/ecr/login" | docker login --username AWS --password-stdin <account-id>.dkr.ecr.<region>.amazonaws.com
```

### Get Caller Identity

Fetch the caller identity from AWS STS.

- **URL:** `/sts`
- **Method:** `GET`
- **Example:**
Expand All @@ -140,25 +155,37 @@ Fetch the caller identity from AWS STS.
curl "http://localhost:3000/sts"
```

## Running Tests
## Usage as a GitLab CI Sidecar

To run the tests:
This server is designed to run as a sidecar service in GitLab CI, giving your jobs easy access to AWS services without installing the AWS CLI.

go test -v ./...
```yaml
my-job:
image: alpine:latest
services:
- name: ghcr.io/leneffets/awsserver:latest
alias: awsserver
variables:
AWS_REGION: eu-central-1
script:
- SECRET=$(curl -s "http://awsserver:3000/ssm?name=/my-app/db-password")
- echo "Fetched secret successfully"
```

## CI/CD Pipeline with GitHub Actions
> **Note:** When running as a GitLab CI service, the server is reachable via the `alias` hostname (here `awsserver`) on port 3000. Make sure your AWS credentials are set as [CI/CD variables](https://docs.gitlab.com/ee/ci/variables/) in your project or group settings.

This project uses GitHub Actions for continuous integration. The pipeline is defined in `.github/workflows/ci.yml` and performs the following actions on each push or pull request to the `main` branch:
## Running Tests

```sh
go test -v ./...
```

- Checks out the code.
- Sets up the Go environment.
- Installs dependencies.
- Builds the project.
- Runs tests.
## CI/CD Pipeline

3. **Review pipeline runs:**
This project uses GitHub Actions with two workflows:

Go to the `Actions` tab in your GitHub repository to view the status of the workflow runs.
- **CI Pipeline** (`.github/workflows/ci.yml`): Runs on pushes and PRs to `main`. Checks out code, runs tests, builds a static binary, and pushes a Docker image (`:latest`) on pushes to `main`.
- **Release Pipeline** (`.github/workflows/release.yml`): Runs on published releases. Builds static binaries for linux/darwin (amd64/arm64), uploads them as release artifacts (`.tar.gz`), and pushes a multi-arch Docker image tagged with the release version.

## Contribution

Expand All @@ -167,4 +194,3 @@ Feel free to fork this repository and create pull requests. For major changes, p
## License

This project is licensed under the MIT License.

Loading
Loading