Changing Pulumi Parameters
Overview
In this tutorial, we'll use Klotho config to demonstrate how to change the characteristics of the cloud resources your application uses.
Klotho generates Infrastrucre-as-Code files to define the necessary resources for your application. The infrastructure generation is defined by the resources specified in the compiled klotho.yaml
configuration file.
Using Klotho config you can change the configuration of the underlying services that your application uses.
Learn more about the general concept of Klotho config
Why?
Applications underlying needs will change based on business requirements and scale. Klotho will allow the operator to be in control and make decisions to override infrastructure attributes when necessary.
Getting started with klotho config
Prerequisites
- Klotho CLI installed
curl
- Node.js 16.x+ (& NPM)
- TypeScript
Repository
Clone our sample apps git repo and install the npm packages for the ts-orm
app.
git clone https://github.com/klothoplatform/sample-apps.git
cd sample-apps/ts-orm
npm install
Application Overview
The ts-orm
application utilizes the following annotations
- index.ts
- ./typeorm/logic.ts
- ./sequelize/model.ts
/**
* @klotho::execution_unit {
* id = "sequelize-main"
* }
*/
import * as express from "express";
...
/*
* @klotho::expose {
* target = "public"
* id = "sequelizeApp"
* }
*/
app.listen(3000, async () => {
console.log(`App listening locally`);
});
...
/* @klotho::persist {
* id = "typeormDB"
* }
*/
const AppDataSource = new DataSource({
type: "postgres",
entities: [User],
synchronize: true,
logging: false,
})
...
/**
* @klotho::execution_unit {
* id = "sequelize-main"
* }
*/
...
/** @klotho::persist {
* id = "sequelizeDB"
* }
* */
const sequelize = new Sequelize(`sqlite::memory:`, { logging: false });
...
Klotho compile the application
Let start by compiling our TypeScript application into JavaScript.
npx tsc
Then we'll compile the application using Klotho.
klotho . --app myfirstapp --provider aws
██╗ ██╗██╗ ██████╗ ████████╗██╗ ██╗ ██████╗
██║ ██╔╝██║ ██╔═══██╗╚══██╔══╝██║ ██║██╔═══██╗
█████╔╝ ██║ ██║ ██║ ██║ ███████║██║ ██║
██╔═██╗ ██║ ██║ ██║ ██║ ██╔══██║██║ ██║
██║ ██╗███████╗╚██████╔╝ ██║ ██║ ██║╚██████╔╝
╚═╝ ╚═╝╚══════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝
Adding resource input_file_dependencies:
Adding resource exec_unit:sequelize-main
Found 4 route(s) on server 'app'
Adding resource gateway:sequelizeApp
Adding resource persist_orm:sequelizeDB
Adding resource persist_orm:typeormDB
Adding resource topology:sample
Adding resource infra_as_code:Pulumi (AWS)
Pulumi.myfirstapp.yaml: Make sure to run `pulumi config set aws:region YOUR_REGION --cwd 'compiled/' -s 'myfirstapp'` to configure the target AWS region.
Initial Config of the Application
This initial Klotho compilation will generate a default Klotho configuration file within you compiled directory and look similar to:
app: myfirstapp
provider: aws
path: dist
out_dir: compiled
defaults:
execution_unit:
type: lambda
pulumi_params_by_type:
fargate:
cpu: 256
memory: 512
lambda:
memorySize: 512
timeout: 180
expose:
type: apigateway
persist:
kv:
type: dynamodb
fs:
type: s3
secret:
type: s3
orm:
type: rds_postgres
pulumi_params_by_type:
rds_postgres:
allocatedStorage: 20
instanceClass: db.t4g.micro
skipFinalSnapshot: true
redis:
type: elasticache
pulumi_params_by_type:
elasticache:
nodeType: cache.t3.micro
numCacheNodes: 1
execution_units:
sequelize-main:
type: lambda
pulumi_params:
memorySize: 512
timeout: 180
exposed:
sequelizeApp:
type: apigateway
persisted:
sequelizeDB:
type: rds_postgres
pulumi_params:
allocatedStorage: 20
instanceClass: db.t4g.micro
skipFinalSnapshot: true
typeormDB:
type: rds_postgres
pulumi_params:
allocatedStorage: 20
instanceClass: db.t4g.micro
skipFinalSnapshot: true
In order to deploy the following databases, the application also requires the user to set a username and password via the pulumi config.
pulumi config set sample:sequelizedb_username yourSequelizeUsername
pulumi config set sample:sequelizedb_password yourSequelizePassword
pulumi config set sample:typeormdb_username yourTypeormUsername
pulumi config set sample:typeormdb_password yourTypeormPassword
Deploying the initial application
Now to deploy the application, please refer to the deploying guide.
When deployed to AWS, we can see the characteristics of our Lambda and Relational Database Service (rds) instances in the console. You can see how the allocated storage and lambda timeout match what is defined within the Klotho config.
Changing the klotho configuration
After testing our application, we realize that we need more storage within our sequelizedb rds instance and a larger lambda timeout to prevent errors from being returned to the end user.
In order to change our infrastructure's characteristics we must change the pulumi_params of our target resources. In this case, we will change the params for one of the persist resources and our execution unit.
Copy the generated Klotho configuration file to the root of the application directory by running:
cp ./compiled/klotho.yaml ./klotho.yaml
By making the following modifications to the ./klotho.yaml
Klotho config, we can update pulumi on how we want our resources to exist on our next compilation.
execution_units:
sequelize-main:
type: lambda
pulumi_params:
memorySize: 512
timeout: 300 # 180 -> 300
persisted:
sequelizeDB:
type: rds_postgres
pulumi_params:
allocatedStorage: 40 # 20 -> 40
instanceClass: db.t4g.micro
skipFinalSnapshot: true
Using the configuration changes to compile
Now that the operator has created their klotho.yaml
configuration file to instruct Klotho how to build its applications infrastructure, the operator can rerun Klotho and pass in the specified config file.
klotho --config ./klotho.yaml # Use the configuration file passed in
Klotho will use the defaults and overrides specified in the configuration file, while generating any resources and defaults which are not explicitly defined. Notice how the resources we explicitly defined above (sequelizeDB and sequelizeApp) have updated their characteristics, while typeormDB has the default characteristics.
the final Klotho configuration will now look like:
app: sample
provider: aws
path: dist
out_dir: compiled
defaults:
execution_unit:
type: lambda
pulumi_params_by_type:
fargate:
cpu: 256
memory: 512
lambda:
memorySize: 512
timeout: 180
expose:
type: apigateway
persist:
kv:
type: dynamodb
fs:
type: s3
secret:
type: s3
orm:
type: rds_postgres
pulumi_params_by_type:
rds_postgres:
allocatedStorage: 20
instanceClass: db.t4g.micro
skipFinalSnapshot: true
redis:
type: elasticache
pulumi_params_by_type:
elasticache:
nodeType: cache.t3.micro
numCacheNodes: 1
execution_units:
sequelize-main:
type: lambda
pulumi_params:
memorySize: 512
timeout: 300
exposed:
sequelizeApp:
type: apigateway
persisted:
sequelizeDB:
type: rds_postgres
pulumi_params:
allocatedStorage: 40
instanceClass: db.t4g.micro
skipFinalSnapshot: true
typeormDB:
type: rds_postgres
pulumi_params:
allocatedStorage: 20
instanceClass: db.t4g.micro
skipFinalSnapshot: true
Updating the application
After following the steps in the deploying tutorial again, we can see that the resources within aws have been updated to reflect the attributes we explicitly defined in our Klotho configuration.
The final infrastructure will be represented in the console: