Skip to content

Commit

Permalink
Merge pull request #13 from gruntwork-io/client-server-example
Browse files Browse the repository at this point in the history
Client server example
  • Loading branch information
denis256 authored Aug 21, 2024
2 parents 6a69622 + 9feaf91 commit 0c43299
Show file tree
Hide file tree
Showing 19 changed files with 1,042 additions and 22 deletions.
60 changes: 50 additions & 10 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -1,22 +1,29 @@
version: 2.1

orbs:
go: circleci/[email protected]

env: &env
environment:
GO111MODULE: auto
GRUNTWORK_INSTALLER_VERSION: v0.0.36
MODULE_CI_VERSION: v0.54.0
GRUNTWORK_INSTALLER_VERSION: v0.0.39
MODULE_CI_VERSION: v0.57.0
TERRATEST_LOG_PARSER_VERSION: v0.37.0
GOLANG_VERSION: 1.21.1

defaults: &defaults
machine:
enabled: true
image: ubuntu-2004:2022.10.1
<<: *env
docker:
- image: 087285199408.dkr.ecr.us-east-1.amazonaws.com/circle-ci-test-image-base:go1.21.9-tf1.5-tg58.8-pck1.8-ci56.0

run_precommit: &run_precommit
# Fail the build if the pre-commit hooks don't pass. Note: if you run $ pre-commit install locally within this repo, these hooks will
# execute automatically every time before you commit, ensuring the build never fails at this step!
name: run pre-commit hooks
command: |
pre-commit install
pre-commit run --all-files
install_gruntwork_utils: &install_gruntwork_utils
name: install gruntwork utils
command: |
Expand All @@ -30,15 +37,13 @@ install_gruntwork_utils: &install_gruntwork_utils
--terragrunt-version "NONE" \
--packer-version "NONE" \
--go-version ${GOLANG_VERSION}
version: 2.1
#----------------------------------------------------------------------------------------------------------------------
# BUILD JOBS
#----------------------------------------------------------------------------------------------------------------------
jobs:
precommit:
<<: *env
docker:
- image: 087285199408.dkr.ecr.us-east-1.amazonaws.com/circle-ci-test-image-base:go1.21.9-tf1.5-tg39.1-pck1.8-ci54.0
<<: *defaults
steps:
- checkout
# Fail the build if the pre-commit hooks don't pass. Note: if you run pre-commit install locally, these hooks will
Expand Down Expand Up @@ -73,13 +78,36 @@ jobs:
- run:
name: Terratest log parser
command: |
gruntwork-install --binary-name 'terratest_log_parser' --repo 'https://github.com/gruntwork-io/terratest' --tag 'v0.30.0'
terratest_log_parser --testlog logs/tests.log --outputdir logs
when: always
- store_artifacts:
path: logs
- store_test_results:
path: logs
build:
resource_class: xlarge
<<: *defaults
steps:
- checkout
- run:
<<: *install_gruntwork_utils
- run: |
go mod tidy
pushd examples/client-server/client
build-go-binaries --app-name terragrunt-iac-engine-client --dest-path bin --ld-flags "-X github.com/gruntwork-io/go-commons/version.Version=$CIRCLE_TAG -extldflags '-static'"
popd
pushd examples/client-server/server
build-go-binaries --app-name terragrunt-iac-engine-server --dest-path bin --ld-flags "-X github.com/gruntwork-io/go-commons/version.Version=$CIRCLE_TAG -extldflags '-static'"
- persist_to_workspace:
root: .
paths:
- examples/client-server/client/bin
- examples/client-server/server/bin
- store_artifacts:
path: examples/client-server/client/bin
- store_artifacts:
path: examples/client-server/server/bin

#----------------------------------------------------------------------------------------------------------------------
# WORKFLOWS
#----------------------------------------------------------------------------------------------------------------------
Expand All @@ -106,3 +134,15 @@ workflows:
filters:
tags:
only: /^v.*/
- build:
filters:
tags:
only: /^v.*/
requires:
- precommit
context:
- AWS__PHXDEVOPS__circle-ci-test
- GCP__automated-tests
- GITHUB__PAT__gruntwork-ci
- APPLE__OSX__code-signing
- TERRAGRUNT_ENGINE__circle-ci
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,6 @@ vendor
.DS_Store
mocks/
.go-version
terragrunt-engine-client
terragrunt-engine-server

2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ tools:
go install google.golang.org/grpc/cmd/[email protected]
go install github.com/golangci/golangci-lint/cmd/[email protected]

protoc: $(shell find . -name '*.proto')
protoc: $(shell find ./proto -name '*.proto')
protoc --go_out=. --go_opt=paths=source_relative proto/engine.proto
protoc --go-grpc_out=. --go-grpc_opt=paths=source_relative proto/engine.proto

Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@ Make commands:

## Engines

Impelmentations of the Terragrunt Engine include:
Implementations of the Terragrunt Engine include:

- [terragrunt-engine-opentofu](https://github.com/gruntwork-io/terragrunt-engine-opentofu)
- [terragrunt-engine-client-server](./examples/client-server)

## Example Engine Implementation

Expand Down
46 changes: 46 additions & 0 deletions engine/meta.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package engine

import (
"encoding/json"
"fmt"
"strconv"

"github.com/gruntwork-io/terragrunt-engine-go/proto"
"google.golang.org/protobuf/types/known/structpb"
)

// Meta extracts request.Meta to go map[string]interface{} struct.
func Meta(request *proto.RunRequest) (map[string]interface{}, error) {
protoMeta := request.Meta
meta := make(map[string]interface{})
for key, anyValue := range protoMeta {
var value structpb.Value
if err := anyValue.UnmarshalTo(&value); err != nil {
return nil, fmt.Errorf("error unmarshaling any value to structpb.Value: %w", err)
}
jsonData, err := value.MarshalJSON()
if err != nil {
return nil, fmt.Errorf("error marshaling structpb.Value to JSON: %w", err)
}
var result interface{}
if err := json.Unmarshal(jsonData, &result); err != nil {
return nil, fmt.Errorf("error unmarshaling JSON to interface{}: %w", err)
}
meta[key] = result
}

return meta, nil
}

// MetaString returns the value of a meta key from the RunRequest. If the key does not exist, an empty string is returned.
func MetaString(request *proto.RunRequest, key string) (string, error) {
meta, err := Meta(request)
if err != nil {
return "", err
}
value, ok := meta[key]
if !ok {
return "", nil
}
return strconv.Unquote(fmt.Sprintf("%v", value))
}
28 changes: 28 additions & 0 deletions examples/client-server/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
FROM golang:1.21.13-bullseye as builder

ARG ENGINE_VERSION=v0.0.3-rc2024081902

# clone base engine repo
WORKDIR src
RUN git clone https://github.com/gruntwork-io/terragrunt-engine-go.git -b ${ENGINE_VERSION} .
# add examples from working directory
RUN rm -rf ./examples/*
COPY . ./examples/client-server

# build engine
WORKDIR examples/client-server
RUN make

FROM gruntwork/terragrunt:0.2.0

ENV LISTEN_ADDRESS=0.0.0.0:50051

RUN mise use --global -y [email protected]
RUN ln -s /root/.local/share/mise/installs/opentofu/1.7.0/bin/tofu /bin/tofu

COPY --from=builder /go/src/examples/client-server/terragrunt-engine-server /opt/terragrunt-engine-server

RUN mkdir /app
WORKDIR /app
ENTRYPOINT ["/opt/terragrunt-engine-server"]

26 changes: 26 additions & 0 deletions examples/client-server/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
default: build

tools:
go install google.golang.org/protobuf/cmd/[email protected]
go install google.golang.org/grpc/cmd/[email protected]
go install github.com/golangci/golangci-lint/cmd/[email protected]

protoc: $(shell find ./examples/client-server -name '*.proto')
protoc --go_out=. --go_opt=paths=source_relative proto/proto.proto
protoc --go-grpc_out=. --go-grpc_opt=paths=source_relative proto/proto.proto

build:
set -xe ;\
cd client ;\
go build -o ../terragrunt-engine-client -ldflags "-extldflags '-static'" . ;\
cd .. ;\
cd server ;\
go build -o ../terragrunt-engine-server -ldflags "-extldflags '-static'" .

docker:
docker build -t terragrunt-engine-server .

pre-commit:
pre-commit run --all-files

.PHONY: default lint protoc test tools
39 changes: 39 additions & 0 deletions examples/client-server/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Example Engine Client - Server implementation

Example implementation of the Terragrunt IaC engine client and server.
Use it only for testing purposes since it is allowing execution of arbitrary bash commands on the server.

To build the client and server locally, run the `make` command:
```bash
make
```
This will build the `terragrunt-engine-client` and `terragrunt-engine-server` binaries.

## Example HCL Configuration

Here is an example of how you can configure the IaC engine client in your Terragrunt configuration for AMD64 Linux:
* run `docker compose up` to start the server
* prepare the client configuration in `terragrunt.hcl` file
```hcl
# terragrunt.hcl
engine {
source = "./terragrunt-iac-engine-client"
meta = {
# server endpoint
endpoint = "127.0.0.1:50051"
# authentication token
token = get_env("TG_SERVER_TOKEN")
}
}
```

Terragrunt execution:
```bash
export TG_EXPERIMENTAL_ENGINE=1
export TG_SERVER_TOKEN=secret-token

terragrunt apply --auto-approve
```

End to end example:
[![asciicast](https://asciinema.org/a/672387.svg)](https://asciinema.org/a/672387)
Loading

0 comments on commit 0c43299

Please sign in to comment.