Skip to content

Commit

Permalink
ec2-secrets
Browse files Browse the repository at this point in the history
  • Loading branch information
gian2dchris committed Nov 7, 2022
1 parent 23f2397 commit a2f9be7
Show file tree
Hide file tree
Showing 3 changed files with 165 additions and 2 deletions.
44 changes: 44 additions & 0 deletions .github/workflows/publish-ec2-artifact.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: Publish EC2 entrypoint artifact

on:
push:
tags: "v[0-9]+.[0-9]+.[0-9]+"
branches:
- "main"
- "develop/*"
paths:
- 'cmd/ec2_secrets/**'
- 'internal/**'
- 'pkg/**'
workflow_dispatch:

permissions:
contents: write

jobs:
publish-ec2-artifact:
runs-on: ubuntu-latest

steps:
- name: Checkout
id: checkout
uses: actions/checkout@v3

- name: Go build
id: build
run:
make ec2-secrets-amd64

# - name: Set Release Tag
# id: tag
# run: |
# TAG=${GITHUB_REF##*/}
# echo $TAG
# echo "TAG=$TAG" >> $GITHUB_ENV

- name: Release
id: release
uses: softprops/action-gh-release@v1
if: startsWith(github.ref, 'refs/tags/')
with:
files: ec2/ec2-secrets
8 changes: 6 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ zip-amd64: build-amd64
zip -r aws-lambda-secrets-amd64.zip extensions/
@echo "Extension amd64 zip archive created"


fetch-secrets-arm64:
GOOS=$(GOOS) GOARCH=arm64 go build \
-o extensions/fetch-secrets \
Expand All @@ -38,7 +37,12 @@ zip-arm64: build-arm64

release: zip-amd64 zip-arm64 clean

ec2-secrets-amd64:
GOOS=$(GOOS) GOARCH=amd64 go build \
-o ec2/ec2-secrets \
cmd/ec2-secrets/main.go

clean:
-rm -rf extensions
-rm -rf extensions ec2

.PHONY: build zip clean mod
115 changes: 115 additions & 0 deletions cmd/ec2-secrets/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package main

import (
"flag"
"fmt"
"log"
"os"
"syscall"

"github.com/joho/godotenv"
"github.com/skroutz/aws-lambda-secrets/internal/smsecrets"
"github.com/skroutz/aws-lambda-secrets/internal/utils"
)

// Constants for default values if none are supplied
const DEFAULT_TIMEOUT = 5000
const DEFAULT_REGION = "eu-central-1"
const DEFAULT_SECRETS_FILE = "secrets.yaml"
const DEFAULT_OUTPUT_FILE = "/tmp/lambda-secrets.env"
const DEFAULT_ENTRYPOINT_ENV_VAR = "ENTRYPOINT"

var (
timeout int
region string
secretsFile string
outputFileName string
entrypointEnvVar string
entrypointArray []string

sm *smsecrets.SecretsManager
)

func getCommandParams() {
// Setup command line args
flag.IntVar(&timeout, "t", utils.EnvOrInt("SECRETS_TIMEOUT", DEFAULT_TIMEOUT), "The amount of time to wait for any API call")
flag.StringVar(&region, "r", utils.EnvOrString("SECRETS_AWS_REGION", DEFAULT_REGION), "The Amazon Region to use")
flag.StringVar(&secretsFile, "f", utils.EnvOrString("SECRETS_FILE", DEFAULT_SECRETS_FILE),
"The YAML file containing SecretsManager ARNs and Env Var names")
flag.StringVar(&outputFileName, "o", utils.EnvOrString("SECRETS_OUTPUT_FILE", DEFAULT_OUTPUT_FILE),
"The file that will be populated with SecretsManager secrets as Env Vars")
flag.StringVar(&entrypointEnvVar, "e", utils.EnvOrString("ENTRYPOINT", DEFAULT_ENTRYPOINT_ENV_VAR),
"The name of the Env Var storing the application entrypoint (Default: ENTRYPOINT)")

// Parse all of the command line args into the specified vars with the defaults
flag.Parse()

if flag.NArg() != 0 {
log.Printf("[*] Positional Argument treated as entrypoint: %s", flag.Args())
entrypointArray = flag.Args()
} else if os.Getenv(entrypointEnvVar) != "" {
log.Printf("[*] Environment Variable '%s' is treated as entrypoint: %s", DEFAULT_ENTRYPOINT_ENV_VAR, os.Getenv(DEFAULT_ENTRYPOINT_ENV_VAR))
} else {
log.Println("[!] No entrypoint found")
}
}

func ExecuteEntrypoint() (string, error) {
err := godotenv.Load(outputFileName)
if err != nil {
log.Printf("[-] Error loading EnvVars from '%s' file. %s", outputFileName, err.Error())
return "", err
}

cmd := []byte{}
if entrypointArray == nil {
entrypoint := os.Getenv(entrypointEnvVar)
log.Printf("[+] Passing execution to entrypoint var '%s'\n\n", entrypoint)
err = syscall.Exec(entrypoint, nil, os.Environ())
} else {
log.Printf("[+] Passing execution to positional entrypoint '%s'\n\n", entrypointArray)
err = syscall.Exec(entrypointArray[0], entrypointArray, os.Environ())
}
if err != nil {
log.Printf("[-] Error running the entrypoint. '%s'", err)
return "", err
}

fmt.Println(string(cmd))

log.Printf("[+] Execution finished")
return string(cmd), nil
}

func LoadLambdaSecrets() (string, error) {

// Check if output file exists
// If it does load it, pass execution and exit
log.Printf("[*] Looking for Dotenv file '%s'", outputFileName)
if stat, err := os.Stat(outputFileName); err == nil {
if stat.Size() != 0 {
log.Printf("Dotenv file '%s' found!", outputFileName)
}
} else {
log.Printf("[!] Dotenv file '%s' NOT found!", outputFileName)
log.Println("[*] Loading Secrets from AWS SecretsManager")
sm = smsecrets.NewSecretsManager(region, timeout)
secretArns := smsecrets.GetSecretArns(secretsFile)
sm.FetchSecrets(secretArns["secrets"])
smsecrets.WriteEnvFile(outputFileName)
}

// Now that the secrets are hopefully set
output, err := ExecuteEntrypoint()

return output, err

}

func main() {

getCommandParams()

LoadLambdaSecrets()

}

0 comments on commit a2f9be7

Please sign in to comment.