Stacktape

Sign up



Deployment Scripts

Overview and basic concepts

Deployment script resources enable you to execute custom script as a part of deployment process. On the background, script is bundeled into lambda function which is triggered during deployment or delete process. You can pass information about your infrastructure into the script by using parameters and environment variables and grant script permissions to stack resources. This gives the script ability to interact with other parts of deployed infrastructure.

When to use

Performing provisioning steps related to infrastructure - Deployment of infrastructure is only a part of having the application successfully running. You might need to seed the database or run migrations, both of which are a great fit for a deployment script. Another example might be running a smoke test from your deployment script to ensure that everything is running correctly after deployment.

Basic usage

DeploymentScript  API reference
type
Required
properties.trigger
Required
properties.packaging
Required
properties.runtime
properties.environment
properties.parameters
properties.memory
properties.timeout
Default: 10
properties.joinDefaultVpc
properties.accessControl
overrides

In this example we are using deployment-script to test public API endpoint and integrations after deployment.

Copy

import fetch from 'node-fetch';
export default async (event) => {
const { apiURL } = event;
// do whatever you want with apiURL ...
const result = await fetch(apiURL);
// fail the script if the test fails
if (result.statusCode === 404) {
throw Error('API test failed');
}
};

Example deployment script function written in Typescript (test-url.ts)

Copy

resources:
myHttpApi:
type: http-api-gateway
testApiMethods:
type: deployment-script
properties:
trigger: after:deploy
packaging:
type: stacktape-lambda-buildpack
properties:
entryfilePath: test-url.ts
parameters:
apiURL: $ResourceParam('myHttpApi', 'url')

Stacktape configuration with deployment script

Trigger

Trigger property determines when is the script triggered.

  • Currently available options for triggering script are:
    • after:deploy - executes script at the end of stack deploy operation (after all resources are deployed). If the script fails, whole deployment fails and stack will be rolled back.
    • before:delete - executes script before stack delete operation starts deleting resources. NOTE that even if the script fails, delete will continue and delete all resources.
  • Besides triggering script during stack operations, you can trigger it manually using stacktape deployment-script:run command.

Copy

resources:
myHttpApi:
type: http-api-gateway
testApiMethods:
type: deployment-script
properties:
trigger: after:deploy
packaging:
type: stacktape-lambda-buildpack
properties:
entryfilePath: test-url.ts
parameters:
apiURL: $ResourceParam('myHttpApi', 'url')

Scripts that use triggers associated with stack delete operation (before:delete) are only executed if the script was present during the last deployment. In other words script must be first added to the stack during deployment so that it can be triggered during delete operation.

Packaging

Scripts are during deployment packaged and executed as lambda functions. Refer to lambda functions packaging docs.

Parameters

  • Parameters can be used to pass complex information to your script handler

You cannot pass secret values (i.e using $Secret directive) using parameters. To pass secret values use environment variables instead.

Copy

resources:
myHttpApi:
type: http-api-gateway
testApiMethods:
type: deployment-script
properties:
trigger: after:deploy
packaging:
type: stacktape-lambda-buildpack
properties:
entryfilePath: test-url.ts
parameters:
apiURL: $ResourceParam('myHttpApi', 'url')
testPaths:
- my/path/1
- my/path/2

Environment

  • Environment variables can be used to inject information about infrastructure (database URLS, secrets ...) into script's runtime
  • To pass complex objects into your script use parameters instead
name
Required
value
Required

Copy

resources:
myDatabase:
type: relational-database
properties:
credentials:
masterUserName: adminuser
masterUserPassword: $Secret('my-database-password')
engine:
type: aurora-postgresql-serverless
testDatabase:
type: deployment-script
properties:
trigger: after:deploy
packaging:
type: stacktape-lambda-buildpack
properties:
entryfilePath: test-url.ts
environment:
- name: DATABASE_URL
value: $ResourceParam('myDatabase', 'connectionString')

Accessing other resources

  • For most of the AWS resources, resource-to-resource communication is not allowed by default. This helps to enforce security and resource isolation. Access must be explicitly granted using IAM (Identity and Access Management) permissions.

  • Access control of Relational Databases is not managed by IAM. These resources are not "cloud-native" by design and have their own access control mechanism (connection string with username and password). They are accessible by default, and you don't need to grant any extra IAM permissions. You can further restrict the access to your relational databases by configuring their access control mode.

  • Stacktape automatically handles IAM permissions for the underlying AWS services that it creates (i.e. granting script permission to write logs to Cloudwatch).

AccessControl  API reference
Parent API reference: DeploymentScript
iamRoleStatements
allowAccessTo

If your script needs to communicate with other infrastructure components, you need to add permissions manually. You can do this in 2 ways:

Using allowAccessTo

  • List of resource names that this script will be able to access (basic IAM permissions will be granted automatically). Granted permissions differ based on the resource.
  • Works only for resources managed by Stacktape (not arbitrary Cloudformation resources)
  • This is useful if you don't want to deal with IAM permissions yourself. Handling permissions using raw IAM role statements can be cumbersome, time-consuming and error-prone.

Copy

resources:
myScript:
type: deployment-script
properties:
trigger: after:deploy
packaging:
type: stacktape-lambda-buildpack
properties:
entryfilePath: path/to/my-script.ts
environment:
- name: MY_BUCKET_NAME
value: $ResourceParam('myBucket', 'name')
accessControl:
allowAccessTo:
- myBucket
myBucket:
type: bucket

Using iamRoleStatements

  • IAM Role statements are a low-level, granular and AWS-native way of controlling access to your resources.
  • IAM Role statements can be used to add permissions to any Cloudformation resource.
  • Configured IAM role statement objects will be appended to the script's role.

Copy

resources:
myScript:
type: deployment-script
properties:
packaging:
type: stacktape-lambda-buildpack
properties:
entryfilePath: path/to/my-script.ts
environment:
- name: TOPIC_ARN
value: $CfResourceParam('NotificationTopic', 'Arn')
accessControl:
iamRoleStatements:
- Resource:
- $CfResourceParam('NotificationTopic', 'Arn')
Effect: 'Allow'
Action:
- 'sns:Publish'
cloudformationResources:
NotificationTopic:
Type: AWS::SNS::Topic

API reference

StpIamRoleStatement  API reference
Parent API reference: AccessControl
Resource
Required
Sid
Effect
Action
Condition
Need help? Ask a question on SlackDiscord or info@stacktape.com.