Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Environment Promotion Workflow #6

Merged
merged 9 commits into from
Sep 18, 2024
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
7 changes: 3 additions & 4 deletions .github/workflows/tyk-assets-cicd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,10 @@ on:
- 'dev/**'

jobs:
# Run linter and validation workflow
# Set up dev APIs and Policies
tyk-dev-env:
uses: ./.github/workflows/tyk-lint.yml
with:
environment: 'dev'
uses: ./.github/workflows/tyk-dev.yml
secrets: inherit

# Set up staging APIs and Policies if the Dev assets pass the linter / validation
tyk-staging-env:
Expand Down
52 changes: 26 additions & 26 deletions .github/workflows/tyk-env-promotion.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Tyk assets environment promotion
name: Tyk Assets Environment Promotion

# Perform the env promotion only on push to main branch
on:
Expand All @@ -19,29 +19,29 @@ jobs:
- name: 'Checkout Repository'
uses: actions/checkout@v4

# - name: Create .tyk.json
# run: |
# cd ./stg
# echo '{' > .tyk.json
# echo ' "type": "apidef",' >> .tyk.json
# echo ' "files": [' >> .tyk.json
# find . -type f -name '*.json' -path './apis/*' -exec echo ' {"file": "{}"},' \; | sed '$ s/,$//' >> .tyk.json
# echo ' ],' >> .tyk.json
# echo ' "policies": [' >> .tyk.json
# find . -type f -name '*.json' -path './policies/*' -exec echo ' {"file": "{}"},' \; | sed '$ s/,$//' >> .tyk.json
# echo ' ],' >> .tyk.json
# echo ' "assets": [' >> .tyk.json
# find . -type f -name '*.json' -path './assets/*' -exec echo ' {"file": "{}"},' \; | sed '$ s/,$//' >> .tyk.json
# echo ' ]' >> .tyk.json
# echo '}' >> .tyk.json
# cat .tyk.json
- name: Create .tyk.json
run: |
cd ./${{ inputs.environment }}
echo '{' > .tyk.json
echo ' "type": "apidef",' >> .tyk.json
echo ' "files": [' >> .tyk.json
find . -type f -name '*.json' -path './apis/*' -exec echo ' {"file": "{}"},' \; | sed '$ s/,$//' >> .tyk.json
echo ' ],' >> .tyk.json
echo ' "policies": [' >> .tyk.json
find . -type f -name '*.json' -path './policies/*' -exec echo ' {"file": "{}"},' \; | sed '$ s/,$//' >> .tyk.json
echo ' ],' >> .tyk.json
echo ' "assets": [' >> .tyk.json
find . -type f -name '*.json' -path './assets/*' -exec echo ' {"file": "{}"},' \; | sed '$ s/,$//' >> .tyk.json
echo ' ]' >> .tyk.json
echo '}' >> .tyk.json
cat .tyk.json

# - name: Sync with Tyk
# env:
# TYK_SYNC_REPO: ${{ vars.TYK_SYNC_REPO }}
# TYK_SYNC_VERSION: ${{ vars.TYK_SYNC_VERSION }}
# TYK_DASHBOARD_URL: ${{ secrets.TYK_DASHBOARD_URL }}
# TYK_DASHBOARD_SECRET: ${{ secrets.TYK_DASHBOARD_SECRET }}
# run: |
# docker run ${TYK_SYNC_REPO}:${TYK_SYNC_VERSION} version
# docker run -v ${{ github.workspace }}:/app/data ${TYK_SYNC_REPO}:${TYK_SYNC_VERSION} sync --path /app/data --dashboard ${TYK_DASHBOARD_URL} --secret ${TYK_DASHBOARD_SECRET}
- name: Sync with Tyk
env:
TYK_SYNC_REPO: ${{ vars.TYK_SYNC_REPO }}
TYK_SYNC_VERSION: ${{ vars.TYK_SYNC_VERSION }}
TYK_DASHBOARD_URL: ${{ inputs.environment == 'stg' && secrets.TYK_STG_DASHBOARD_URL || secrets.TYK_PROD_DASHBOARD_URL }}
TYK_DASHBOARD_SECRET: ${{ inputs.environment == 'stg' && secrets.TYK_STG_DASHBOARD_SECRET || secrets.TYK_PROD_DASHBOARD_SECRET }}
run: |
docker run ${TYK_SYNC_REPO}:${TYK_SYNC_VERSION} version
docker run -v ${{ github.workspace }}/${{ inputs.environment }}:/app/data ${TYK_SYNC_REPO}:${TYK_SYNC_VERSION} sync --path /app/data --dashboard ${TYK_DASHBOARD_URL} --secret ${TYK_DASHBOARD_SECRET}
129 changes: 91 additions & 38 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,56 +1,109 @@
# tyk-cicd-dev-demo
Demo of CICD using Tyk Sync and GH Actions
Configuration Example
# Tyk CICD Example using Tyk Sync (WIP)
This project demonstrates how to create a GitOps/CICD pipeline for API Management with Tyk. It shows secure and effective ways to promote assets from lower to upper environments using accessible tools like [Tyk Sync](https://tyk.io/docs/product-stack/tyk-sync/overview/), [Spectral](https://github.com/stoplightio/spectral), and Shell Scripting. These solutions are just examples and not the only ways to address common DevOps challenges in the API promotion workflow.

## Overview
This repository assumes you have three standard environments: `dev`, `staging`, and `production`. The diagram below shows how these environments relate to each other and illustrates the workflow from development to staging and then to production.

![Screenshot of an example CICD workflow demonstrating the Tyk asset promotion between environments](./assets/imgs/tyk-cicd-workflow-example.png)


Example VCS folder structure
```
├── infrastructure
├── dev
│ └── tyk
│ ├── apis
│ ├── assets
│ └── policies
├── production
│ └── tyk
│ ├── apis
│ ├── assets
│ └── policies
└── staging
└── tyk
├── apis
├── assets
└── policies
```

The GitHub Action workflow files may look a bit messy because they demonstrate various methods for API linting and validation. By using different solutions like Shell Scripts and Spectral linting, the goal is to showcase all possible options available for these tasks.

You can review the complete CICD pipeline here: [https://github.com/TykTechnologies/tyk-cicd-dev-demo/actions/runs/10923225077](https://github.com/TykTechnologies/tyk-cicd-dev-demo/actions/runs/10923225077)


## Getting Started
### Prerequisites
1. Two Tyk environments that can be acceesible

### Steps
#### Step 1: Clone this repository and set up your GitHub repositories with two environments named staging and production.

#### Step 2: Configure GitHub Security for each deployment (staging and production)
Repository variables example
```
TYK_SYNC_REPO=tykio/tyk-sync
TYK_SYNC_VERSION=v1.5.1
```

Repository secrets example
```
TYK_STG_DASHBOARD_SECRET={TYK_DASHBOARD_API_CREDENTIALS}
TYK_STG_DASHBOARD_URL={TYK_DASHBOARD_URL}
STG_US_CONFIG_DATA={\"routes\": {\"default\": \"https://stg.httpbin.com\",\"stg1\": \"https://stg1.httpbin.com\",\"stg2\": \"https://stg2.httpbin.com\"}}
STG_US_PROXY_TARGET_URL=http://httpbin.org/get?env=stg

TYK_PROD_DASHBOARD_SECRET={TYK_DASHBOARD_API_CREDENTIALS}
TYK_PROD_DASHBOARD_URL={TYK_DASHBOARD_URL}
PROD_US_CONFIG_DATA={\"routes\": {\"default\": \"https://prod.httpbin.com\",\"prod1\": \"https://prod1.httpbin.com\",\"prod2\": \"https://prod2.httpbin.com\"}}
PROD_US_PROXY_TARGET_URL=http://httpbin.org/get?env=prod
```

Tyk Sync Dump Command Example

## Useful Resources
Tyk Sync Dump Example Command
```
docker run -it --rm -v $(pwd):/tmp/data tykio/tyk-sync:v1.5.1 dump -d="http://host.docker.internal:3000" -s="{TYK_DASHBOARD_API_CREDENTIAL}" -t="/tmp/data" --apis="{API_ID}"
docker run -it --rm -v $(pwd):/tmp/data tykio/tyk-sync:v1.5.1 dump -d="{TYK_DASHBOARD_URL}" -s="{TYK_DASHBOARD_API_CREDENTIAL}" -t="/tmp/data" --apis="{API_ID}"
```

Execute Pipeline using Act Example
Local GH Action Development Using [act](https://nektosact.com/) Example Command
```
act push -s STG_US_CONFIG_DATA={\"hello\"\:\"world\"} -s ORG_NAME=tyk -s [email protected] -s STG_US_PROXY_TARGET_URL=httpbin2.org
```

Spectral / Stoplight Ruleset Example
```
# no-empty-target-url:
# description: APIs must have a target_url
# given: "$.api_definition.proxy"
# severity: error
# then:
# field: 'target_url'
# function: 'pattern'
# functionOptions:
# match: '^(?!\s*$).+'

# check-for-mtls-auth:
# description: MutualTLS is not enabled
# given: "$.api_definition"
# severity: warning
# then:
# field: enable_jwt
# function: falsy

# ensure-authentication-method:
# description: "Ensure that at least one of 'enable_jwt' or 'use_mutual_tls_auth' is true."
# given: "$.api_definition"
# then:
# - field: "enable_jwt"
# function: truthy
# functionOptions:
# negation: true # Should not be false
# - field: "use_mutual_tls_auth"
# function: truthy
# functionOptions:
# negation: true # Should not be false
# severity: error
# message: "At least one of 'api_definition.enable_jwt' or 'api_definition.use_mutual_tls_auth' must be true."
rules:
no-empty-target-url:
description: APIs must have a target_url
given: "$.api_definition.proxy"
severity: error
then:
field: 'target_url'
function: 'pattern'
functionOptions:
match: '^(?!\s*$).+'

check-for-mtls-auth:
description: MutualTLS is not enabled
given: "$.api_definition"
severity: warning
then:
field: enable_jwt
function: falsy

validate-auth-methods:
description: "Ensure that at least one of 'enable_jwt' or 'use_mutual_tls_auth' is true."
given: "$.api_definition"
then:
- field: "enable_jwt"
function: truthy
functionOptions:
negation: true # Should not be false
- field: "use_mutual_tls_auth"
function: truthy
functionOptions:
negation: true # Should not be false
severity: error
message: "At least one of 'api_definition.enable_jwt' or 'api_definition.use_mutual_tls_auth' must be true."
```
Binary file added assets/imgs/tyk-cicd-workflow-example.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 1 addition & 16 deletions dev/tykapi-ruleset.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,4 @@ rules:
field: 'target_url'
function: pattern
functionOptions:
match: '^(?!\s*$).+'

# check-authentication-methods:
# description: "At least one of 'enable_jwt' or 'use_mutual_tls_auth' must be true."
# given: "$.api_definition"
# then:
# - field: "enable_jwt"
# function: truthy
# functionOptions:
# negation: true # Should not be false
# - field: "use_mutual_tls_auth"
# function: truthy
# functionOptions:
# negation: true # Should not be false
# severity: error
# message: "At least one of 'api_definition.enable_jwt' or 'api_definition.use_mutual_tls_auth' must be true."
match: '^(?!\s*$).+'
17 changes: 1 addition & 16 deletions prod/tykapi-ruleset.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,4 @@ rules:
field: 'target_url'
function: pattern
functionOptions:
match: '^(?!\s*$).+'

# check-authentication-methods:
# description: "At least one of 'enable_jwt' or 'use_mutual_tls_auth' must be true."
# given: "$.api_definition"
# then:
# - field: "enable_jwt"
# function: truthy
# functionOptions:
# negation: true # Should not be false
# - field: "use_mutual_tls_auth"
# function: truthy
# functionOptions:
# negation: true # Should not be false
# severity: error
# message: "At least one of 'api_definition.enable_jwt' or 'api_definition.use_mutual_tls_auth' must be true."
match: '^(?!\s*$).+'
17 changes: 1 addition & 16 deletions stg/tykapi-ruleset.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,4 @@ rules:
field: 'target_url'
function: pattern
functionOptions:
match: '^(?!\s*$).+'

# check-authentication-methods:
# description: "At least one of 'enable_jwt' or 'use_mutual_tls_auth' must be true."
# given: "$.api_definition"
# then:
# - field: "enable_jwt"
# function: truthy
# functionOptions:
# negation: true # Should not be false
# - field: "use_mutual_tls_auth"
# function: truthy
# functionOptions:
# negation: true # Should not be false
# severity: error
# message: "At least one of 'api_definition.enable_jwt' or 'api_definition.use_mutual_tls_auth' must be true."
match: '^(?!\s*$).+'