This Action allow users of EDP Deploy (Formerly Runtimes) to deploy infrastructures with the plan step easilly. This GitHub Action is designed to facilitate the deployment of infrastructure using a self-hosted runtime. It supports both AWS IAM roles and AWS access keys for authentication, and it orchestrates the deployment of infrastructure using Terraform.
To use this action, you will need the following:
-
StackSpot Account:
- You must have a StackSpot account with access to the EDP Deploy (formerly Runtimes) service.
- Obtain the following credentials from the StackSpot Portal:
CLIENT_ID
CLIENT_KEY
CLIENT_REALM
- These credentials can be generated by logging in as an ADMIN user on the StackSpot Portal and navigating to the Access Token section.
-
AWS Credentials:
- You must provide either:
- AWS IAM Role: Use the
aws-iam-role
input to specify the IAM role ARN so we can assume this role. - AWS Access Keys: Use the
aws-access-key-id
,aws-secret-access-key
, andaws-session-token
inputs to provide AWS access credentials.
- AWS IAM Role: Use the
- Important: You must provide either the IAM role or the access keys, but not both. If both are provided, the action will fail.
- You must provide either:
-
GitHub Secrets:
- Store sensitive information such as
CLIENT_ID
,CLIENT_KEY
,CLIENT_REALM
, and AWS credentials (AWS_ACCESS_KEY_ID
,AWS_SECRET_ACCESS_KEY
,AWS_SESSION_TOKEN
, orAWS_ROLE_ARN
) as GitHub Secrets to ensure security.
- Store sensitive information such as
-
S3 Buckets:
- You will need two S3 buckets:
- tfstate-bucket-name: For storing Terraform state files.
- iac-bucket-name: For storing Infrastructure as Code (IaC) files and .tfplan files.
- These buckets could be the same.
- Ensure that these buckets are created and accessible in the specified AWS region, by the specified runner.
- You will need two S3 buckets:
-
Terraform:
- This action orchestrates infrastructure deployment using Terraform. Ensure that your infrastructure code is compatible with Terraform and that the necessary Terraform modules are available.
-
GitHub Runner:
- The action requires a GitHub runner that has access to your cloud account (AWS) and can execute the necessary Terraform commands.
Here is an example of how to use this action in your GitHub workflow:
⚠️ Important Note: This action should NOT be used on its own.
It is designed to work in conjunction with the following actions:
- stack-spot/runtime-tasks-action
- stack-spot/runtime-cancel-run-action
Please refer to the example below to see how these actions are used together.
name: Deploy Infrastructure
on:
push:
branches:
- main
jobs:
orquestrate_and_plan:
runs-on: ubuntu-latest # Here you should use a runner that can access your cloud account
outputs:
apply_tasks: ${{ steps.orchestration_and_plan.outputs.apply_tasks }}
run_id: ${{ steps.orchestration_and_plan.outputs.run_id }}
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Deploy Infrastructure
uses: stackspot/edp-deploy-orchestration-action@v1
id: orquestration_and_plan
with:
TFSTATE_BUCKET_NAME: "my-tfstate-bucket"
TFSTATE_BUCKET_REGION: sa-east-1
IAC_BUCKET_NAME: "my-iac-bucket"
IAC_BUCKET_REGION: sa-east-1
WORKSPACE: "my-workspace"
ENVIRONMENT: "production"
VERSION: "v1.0.0"
REPOSITORY_NAME: ${{ github.event.repository.name }}
PATH_TO_MOUNT: /home/runner/_work/${{ github.event.repository.name }}/${{ github.event.repository.name }}
WORKDIR: /path/to/.stk # In case your repo has an .stk not on the repository root folder
STK_CLIENT_ID: ${{ secrets.STK_CLIENT_ID }}
STK_CLIENT_SECRET: ${{ secrets.STK_CLIENT_SECRET }}
STK_REALM: ${{ secrets.STK_REALM }}
AWS_IAM_ROLE: ${{ secrets.AWS_ROLE_ARN }}
AWS_REGION: sa-east-1
FEATURES_TERRAFORM_MODULES: >-
[
{
"sourceType": "gitHttps",
"path": "github.com/stack-spot",
"private": true,
"app": "app",
"token": "token"
},
{
"sourceType": "terraformRegistry",
"path": "hashicorp/stack-spot",
"private": false
}
]
plan_approve_and_apply:
name: Deploy
needs: [orquestrate_and_plan]
runs-on: ubuntu-latest # Here you should use a runner that can access your cloud account
environment: production # Here you set the environments that the user is supposed to aprrove the changes planned from orquestration step
steps:
- name: Service Provision
id: run-task
uses: stack-spot/runtime-tasks-action@stg
if: needs.orquestrate_and_plan.outputs.run_id != ''
with:
RUN_ID: ${{ needs.orquestrate_and_plan.outputs.run_id }}
TASK_LIST: ${{ needs.orquestrate_and_plan.outputs.apply_tasks }}
REPOSITORY_NAME: ${{ github.event.repository.name }}
PATH_TO_MOUNT: /home/runner/_work/${{ github.event.repository.name }}/${{ github.event.repository.name }}
AWS_REGION: sa-east-1
AWS_ROLE_ARN: ${{ secrets.AWS_ROLE_ARN }}
FEATURES_TERRAFORM_MODULES: >-
[
{
"sourceType": "gitHttps",
"path": "github.com/stack-spot",
"private": true,
"app": "app",
"token": "token"
},
{
"sourceType": "terraformRegistry",
"path": "hashicorp/stack-spot",
"private": false
}
]
CLIENT_ID: ${{ secrets.STK_CLIENT_ID }}
CLIENT_KEY: ${{ secrets.STK_CLIENT_SECRET }}
CLIENT_REALM: ${{ secrets.STK_REALM }}
cancel: # in case something in your pipeline breaks, or someone cancels it mid deployment, its required to run this action in order to let Stackspot know that an error has ocurred and not block next deployments
runs-on: ubuntu-latest # Here you should use a runner that can access your cloud account
needs: [orquestrate_and_plan, plan_approve_and_apply]
if: ${{ always() && (contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')) }}
steps:
- name: Cancel run
if: needs.orquestrate_and_plan.outputs.run_id != ''
id: run-cancel
uses: stack-spot/runtime-cancel-run-action@stg
with:
CLIENT_ID: ${{ secrets.STK_CLIENT_ID }}
CLIENT_KEY: ${{ secrets.STK_CLIENT_SECRET }}
CLIENT_REALM: ${{ secrets.STK_REALM }}
RUN_ID: ${{ needs.orquestrate_and_plan.outputs.run_id }}
Name | Description | Required | Default | Secret is Recommended |
---|---|---|---|---|
LEVEL_LOG |
The runtime log level. | No | info |
No |
TFSTATE_BUCKET_NAME |
The bucket for runtime inventory. | Yes | N/A | No |
TFSTATE_BUCKET_REGION |
The region of the bucket for runtime inventory. | No | sa-east-1 |
No |
IAC_BUCKET_NAME |
The bucket for storing IaC (Infrastructure as Code) files. | Yes | N/A | No |
IAC_BUCKET_REGION |
The region of the bucket for IaC files. | No | sa-east-1 |
No |
CONTAINER_IAC_VERSION |
The container version for IaC tasks. | No | stackspot/runtime-job-iac:latest |
No |
CONTAINER_DEPLOY_VERSION |
The container version for deployment tasks. | No | stackspot/runtime-job-deploy:latest |
No |
CONTAINER_DESTROY_VERSION |
The container version for destroy tasks. | No | stackspot/runtime-job-destroy:latest |
No |
CONTAINER_UNIFIED_VERSION |
The container version for unified tasks. | No | stackspot/runtime-job-unified:latest |
No |
DYNAMIC_INPUTS |
Dynamic inputs for the action. | No | "" |
No |
WORKSPACE |
The slug of the workspace. | Yes | N/A | No |
ENVIRONMENT |
The environment for the deployment. | Yes | "" |
No |
VERSION |
The version of the deployment. | Yes | N/A | No |
TERRAFORM_PARALLELISM |
The parallelism level for Terraform. | No | 10 |
No |
WORKDIR |
The path to the directory where the .stk is located. |
No | ./ |
No |
CHECKOUT_BRANCH |
Whether or not to enable branch checkout. | No | false |
No |
REPOSITORY_NAME |
The name of the Git repository. | Yes | N/A | No |
PATH_TO_MOUNT |
The path to mount inside the provisioning Docker container. | Yes | N/A | No |
AWS_REGION |
The AWS where infrastructure will be deployed. | Yes | sa-east-1 |
No |
AWS_IAM_ROLE |
The AWS IAM role to use for deploying infrastructure. | No | N/A | Yes |
AWS_ACCESS_KEY_ID |
The AWS access key ID for deploying infrastructure. | No | N/A | Yes |
AWS_SECRET_ACCESS_KEY |
The AWS secret access key for deploying infrastructure. | No | N/A | Yes |
AWS_SESSION_TOKEN |
The AWS session token for deploying infrastructure. | No | N/A | Yes |
STK_CLIENT_ID |
The client identifier of the account. | Yes | N/A | Yes |
STK_CLIENT_SECRET |
The client secret of the account. | Yes | N/A | Yes |
STK_REALM |
The realm of the account. | Yes | N/A | No |
FEATURES_TERRAFORM_MODULES |
Terraform modules to be used. | No | N/A | No |
TF_LOG_PROVIDER |
The log level for Terraform (info, debug, warn, trace). | No | N/A | No |
BASE_PATH_OUTPUT |
The file name to save outputs. | No | outputs.json |
No |
LOCAL_EXEC_ENABLED |
Whether to allow execution of the local-exec command within Terraform. |
No | false |
No |
VERBOSE |
Whether to show extra logs during execution. | No | false |
No |
OPEN_API_PATH |
The path to the OpenAPI/Swagger file within the repository. | No | N/A | No |
Name | Description |
---|---|
APPLY_TASKS |
Post-plan tasks. |
RUN_ID |
The ID of the current run. |
This action supports two methods of AWS authentication:
Using an AWS IAM Role: Provide the aws-iam-role input. Using AWS Access Keys: Provide the aws-access-key-id, aws-secret-access-key, and aws-session-token inputs. Note: You must provide either the IAM role or the access keys, but not both. If both are provided, the action will fail.
- name: Deploy Infrastructure with AWS Access Keys
uses: stackspot/edp-deploy-orchestration-action@v1
with:
# AWS_IAM_ROLE: ${{ secrets.AWS_ROLE_ARN }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_SESSION_TOKEN: ${{ secrets.AWS_SESSION_TOKEN }}
AWS_REGION: sa-east-1
When the input CHECKOUT_BRANCH
is used, within the IAC step of the tasks, the repository will be cloned within the iac.zip
with the following structure, in case repository files are necessary within terraform. it works in tandem with PATH_TO_MOUNT
input, which should point to your repository after checkout, the value we indicate using for PATH_TO_MOUNT
is /home/runner/_work/${{ github.event.repository.name }}/${{ github.event.repository.name }}
, so terraform has access to the files, but you can change this however you wish.
Note: the contents of the branch input don't really matter, the branch cloned will be the branch used to dispatch the workflow as long as it is not empty
├── main.tf
├── outputs.tf
├── repodir
│ ├── .git/
│ ├── .stk/
│ │ └── stk.yaml
│ ├── src/
│ ├── tests/
│ └── ... {repository-files}
└── variables.tf
└── ... {templates-deploy}
When the input DYNAMIC_INPUTS
is used, the flags passes in these inputs will be added to every plugin applied as their input, and could be used by Jinja engine to modify the IaC file created
e.g:
DYNAMIC_INPUTS = --app_repository="https:#github.com/stack-spot/edp-deploy-orchestrator-action"
main.tf
{% if app_repository is defined %}
resource_source = {{ app_repository }}
{% else %}
resource_source = "default"
{% endif %}
When FEATURES_TERRAFORM_MODULES
is used, the application will allow the modules provided in this inputs to be executed. This is a security measurement to only allow trusted modules to be used.
It should follow this structure:
FEATURES_TERRAFORM_MODULES: >-
[
{
"sourceType": "gitHttps",
"path": "github.com/stack-spot", # Allows all repositories on stack-spot org
"private": true,
"app": "app", # Substitute with appName
"token": "token" # Substitute with GitHub access token
},
{
"sourceType": "terraformRegistry",
"path": "hashicorp/stack-spot", # Allows all modules on stack-spot org
"private": false
}
]
If both AWS IAM role and AWS access keys are provided, the action will fail with an error.
If neither AWS IAM role nor AWS access keys are provided, the action will fail with an error.
In case of a Deployment error, please look at Stackspot EDP Portal at your workspace and application/shared infrastructure within the environment deployed and look at activities tab, there should be the error messages.
This project is licensed under the MIT License.