Skip to content

Commit e9312a7

Browse files
committed
Add terraform
Signed-off-by: haroldsphinx <adedayoakinpelu@gmail.com>
0 parents  commit e9312a7

14 files changed

Lines changed: 670 additions & 0 deletions

File tree

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
name: Production Deployment
2+
concurrency: deploy-to-production
3+
on:
4+
pull_request:
5+
branches:
6+
- main
7+
8+
env:
9+
ENVIRONMENT: production
10+
DOCKER_HUB_USERNAME: ${{ secrets.DOCKER_HUB_USERNAME }}
11+
DOCKER_HUB_ACCESS_TOKEN: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
12+
AWS_REGION: eu-west-1
13+
14+
jobs:
15+
build:
16+
runs-on: ubuntu-latest
17+
18+
steps:
19+
- name: Checkout code
20+
uses: actions/checkout@v2
21+
22+
- name: Setup Go Environment
23+
uses: actions/setup-go@v2
24+
with:
25+
go-version: 1.16
26+
27+
- name: Install linter
28+
run: |
29+
go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.41.1
30+
echo "$(go env GOPATH)/bin" >> $GITHUB_PATH
31+
32+
- name: Run lint
33+
run: make lint
34+
35+
- name: Run tests
36+
run: make test
37+
38+
- name: Set up Docker Buildx
39+
uses: docker/setup-buildx-action@v1
40+
41+
publish:
42+
needs: build
43+
runs-on: ubuntu-latest
44+
45+
steps:
46+
- name: Checkout code
47+
uses: actions/checkout@v2
48+
49+
- name: Login to DockerHub
50+
uses: docker/login-action@v1
51+
with:
52+
username: ${{ secrets.DOCKER_HUB_USERNAME }}
53+
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
54+
55+
- name: Build Docker image
56+
run: make docker-build
57+
58+
- name: Push Docker image
59+
run: make docker-push
60+
61+
deploy:
62+
needs: publish
63+
runs-on: ubuntu-latest
64+
65+
steps:
66+
- name: Checkout code
67+
uses: actions/checkout@v2
68+
69+
- name: Configure AWS Credentials
70+
uses: aws-actions/configure-aws-credentials@v1
71+
with:
72+
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
73+
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
74+
aws-region: ${{ env.AWS_REGION }}
75+
76+
- name: Login to Amazon ECR
77+
id: login-ecr
78+
uses: aws-actions/amazon-ecr-login@v1
79+
80+
- name: Setup kubeconfig
81+
run: |
82+
aws eks --region eu-west-1 update-kubeconfig --name ${{ secrets.EKS_CLUSTER_NAME }}
83+
84+
- name: Deploy to EKS
85+
run: make deploy
86+
87+
# - name: Notify Slack
88+
# if: always() # Always run this step even if the build job fails
89+
# uses: 8398a7/action-slack@v3
90+
# with:
91+
# status: ${{ job.status }}
92+
# fields: repo,commit,author,eventName,ref,workflow
93+
# env:
94+
# SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/build/*
2+
.env
3+
.terraform/*

Dockerfile

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# syntax=docker/dockerfile:1
2+
3+
FROM golang:1.22.2
4+
5+
ENV PORT=3000
6+
7+
8+
WORKDIR /app
9+
10+
COPY go.mod go.sum ./
11+
RUN go mod download
12+
13+
COPY *.go ./
14+
15+
RUN CGO_ENABLED=0 GOOS=linux go build -o trust-wallet-gateway
16+
17+
18+
EXPOSE ${PORT}
19+
20+
CMD ["/app/trust-wallet-gateway"]

Makefile

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
BINARY_NAME=trust-wallet-gateway
2+
BUILD_DIR=./build/bin
3+
IMAGE=haroldsphinx/trust-wallet-gateway
4+
TF_DIR=./terraform
5+
6+
7+
all: build-app docker-build
8+
9+
install-dependencies:
10+
@echo " > Installing dependencies"
11+
# Install golangci-lint
12+
brew install golangci/tap/golangci-lint
13+
14+
lint:
15+
@echo " > Running Lint"
16+
@golangci-lint run ./...
17+
18+
test:
19+
@echo " > Running tests"
20+
@go test -v ./...
21+
22+
build-app:
23+
go build -o $(BINARY_NAME) main.go
24+
mkdir -p $(BUILD_DIR)
25+
mv $(BINARY_NAME) $(BUILD_DIR)
26+
27+
docker-build:
28+
@echo " > Building docker image"
29+
@docker buildx build --platform linux/amd64 -t $(IMAGE) .
30+
31+
terraform-init:
32+
cd $(TF_DIR) && terraform init
33+
34+
terraform-plan:
35+
cd $(TF_DIR) && terraform plan
36+
37+
terraform-apply:
38+
cd $(TF_DIR) && terraform apply

README.md

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# Trust-Wallet-Gateway Application Deployment on AWS ECS Fargate with GitHub Actions
2+
3+
This repository contains the necessary codebase and deployment artifacts for deploying a trust-wallet-gateway service on AWS ECS FARgate.
4+
5+
## Architecture
6+
7+
The architecture includes the use of GitHub for source code management and GitHub Actions for Continuous Integration and Continuous Deployment (CI/CD). The CI/CD pipeline lints, tests, builds, and deploys the Go service to a Kubernetes cluster in AWS ECS.
8+
9+
Here is a high-level view of the architecture:
10+
```
11+
[GitHub] --- [GitHub Actions] --- [Docker Hub]
12+
\ /
13+
-- [AWS ECS Fargate (Kubernetes)] --
14+
```
15+
16+
17+
## Prerequisites
18+
19+
- Go 1.16+
20+
- Docker
21+
- AWS
22+
- terraform
23+
24+
## Deployment Steps
25+
26+
1. Clone this repository and navigate to the project directory.
27+
2. Run `make install-dependencies` to install required dependencies.
28+
3. Set the required environment variables in your local environment and GitHub secrets for GitHub Actions.
29+
4. Push your changes to the `main` branch.
30+
5. GitHub Actions will automatically lint, test, build the Docker image, push the image to Docker Hub, and deploy the service to the AWS Fargate.
31+
32+
33+
## Builld and Deployment Configuration
34+
35+
The Makefile includes the commands to lint, test, build the Docker image, and push the image to Docker Hub.
36+
37+
```shell
38+
make lint # Run lint
39+
make test # Run tests
40+
make docker-build # Build Docker image
41+
make docker-push # Push Docker image
42+
make install-dependencies # Install dependencies
43+
make deploy # Deploy to AWS ECS Fargate
44+
```
45+
46+
## Continuous Integration and Deployment
47+
48+
This project uses GitHub Actions for CI/CD. When changes are pushed to the `main` branch, the following steps are executed:
49+
50+
1. Linting and testing of the Go code.
51+
2. Building of the Docker image.
52+
3. Pushing of the Docker image to Docker Hub.
53+
4. Deployment of the Docker image to the Kubernetes cluster in the AWS EKS environment.
54+
5. Setting up the AWS ECS Fargate cluster and deploying the service.
55+
6. The service is accessible via the public IP address of the AWS ECS Fargate cluster.
56+
7. The GitHub Actions workflow is defined in the `.github/workflows/deploy.yml` file and its used to autoae the deployment of the service to AWS ECS Fargate.
57+
8.
58+
59+
60+
- Github Action Steps
61+
https://github.com/haroldsphinx/trust-wallet-gateway/blob/main/.github/workflows/deploy.yml
62+
63+
64+
- Architectural Diagram
65+
66+
67+

go.mod

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module trust-wallet-gateway
2+
3+
go 1.22.2

go.sum

Whitespace-only changes.

main.go

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
package main
2+
3+
import (
4+
"bytes"
5+
"encoding/json"
6+
"log"
7+
"net/http"
8+
"fmt"
9+
"os"
10+
)
11+
12+
type RpcRequestPayload struct {
13+
JSONRPC string `json:"jsonrpc"`
14+
Method string `json:"method"`
15+
Params []interface{} `json:"params"`
16+
ID int `json:"id"`
17+
}
18+
19+
type RpcResponsePayload struct {
20+
JSONRPC string `json:"jsonrpc"`
21+
ID int `json:"id"`
22+
Result interface{} `json:"result"`
23+
}
24+
25+
var RpcURL string
26+
27+
28+
func GetBlockNumber(w http.ResponseWriter, r *http.Request) {
29+
requestBody := RpcRequestPayload{
30+
JSONRPC: "2.0",
31+
Method: "eth_blockNumber",
32+
ID: 1,
33+
}
34+
35+
responseBody, err := PostRPCRequest(requestBody)
36+
if err != nil {
37+
http.Error(w, err.Error(), http.StatusInternalServerError)
38+
return
39+
}
40+
41+
json.NewEncoder(w).Encode(responseBody)
42+
}
43+
44+
func GetBlockByNumber(w http.ResponseWriter, r *http.Request) {
45+
requestBody := RpcRequestPayload{
46+
JSONRPC: "2.0",
47+
Method: "eth_getBlockByNumber",
48+
Params: []interface{}{
49+
"0x134e82a",
50+
true,
51+
},
52+
ID: 2,
53+
}
54+
55+
responseBody, err := PostRPCRequest(requestBody)
56+
if err != nil {
57+
http.Error(w, err.Error(), http.StatusInternalServerError)
58+
return
59+
}
60+
61+
json.NewEncoder(w).Encode(responseBody)
62+
}
63+
64+
func PostRPCRequest(requestBody RpcRequestPayload) (RpcResponsePayload, error) {
65+
RpcURL := os.Getenv("RPC_URL")
66+
log.Println("RPC_URL: ", RpcURL)
67+
68+
if RpcURL == "" {
69+
log.Fatal("RPC_URL environment variable is not set")
70+
}
71+
72+
requestBytes, err := json.Marshal(requestBody)
73+
if err != nil {
74+
return RpcResponsePayload{}, err
75+
}
76+
77+
resp, err := http.Post(RpcURL, "application/json", bytes.NewBuffer(requestBytes))
78+
if err != nil {
79+
return RpcResponsePayload{}, err
80+
}
81+
defer resp.Body.Close()
82+
83+
var responseBody RpcResponsePayload
84+
err = json.NewDecoder(resp.Body).Decode(&responseBody)
85+
if err != nil {
86+
return RpcResponsePayload{}, err
87+
}
88+
89+
return responseBody, nil
90+
}
91+
92+
func main() {
93+
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
94+
fmt.Fprintf(w, "TrustWallet RPC Gateway!")
95+
})
96+
97+
http.HandleFunc("/getBlock", GetBlockNumber)
98+
http.HandleFunc("/getBlockByNumber", GetBlockByNumber)
99+
100+
port := os.Getenv("APP_PORT")
101+
if port == "" {
102+
port = "3000"
103+
}
104+
105+
log.Println("Gateway listening on port 3000...")
106+
log.Fatal(http.ListenAndServe(":"+port, nil))
107+
}

0 commit comments

Comments
 (0)