Skip to content

StelvioApp and stlv_app.py

Every Stelvio project has a stlv_app.py file at its root - this is the cornerstone of your infrastructure definition. The CLI automatically looks for this file in your current directory.

Basic Structure

from stelvio.app import StelvioApp
from stelvio.config import StelvioAppConfig, AwsConfig

from stelvio.aws.dynamo_db import DynamoTable
from stelvio.aws.function import Function

# Create your app instance
app = StelvioApp("my-project-name")


# Configuration function - runs first
@app.config
def configuration(env: str) -> StelvioAppConfig:
    return StelvioAppConfig()  # Uses default values/setting


# Infrastructure definition - runs after configuration
@app.run
def run() -> None:
    # Create your AWS resources here
    table = DynamoTable(name="users", ...)
    fn = Function(handler="functions/users.process", links=[table])

The Two Required Decorators

For Stelvio to load and work properly you need to create StelvioApp object with
app = StelvioApp("some-name") and then create two functions.

One which will have @app.config decorator and one with @app.run decorator.

@app.config

  • Purpose: Configures Stelvio for your project and environment
  • Parameters: env: str - the environment name (e.g., "dev", "staging", " prod")
  • Returns: StelvioAppConfig object with AWS settings and other configuration
  • Timing: Runs first, before any infrastructure is created

@app.run

  • Purpose: Defines your infrastructure components
  • Timing: Runs after configuration is loaded
  • Requirement: All Stelvio components must be created inside this function ( or in modules when using auto-discovery). See Project Structure for details on component creation order.

Environment-Specific Configuration

You can customize settings based on the environment:

from stelvio.config import AwsConfig, StelvioAppConfig

@app.config
def configuration(env: str) -> StelvioAppConfig:
    if env == "prod":
        # Production uses separate AWS account
        return StelvioAppConfig(
            aws=AwsConfig(profile="production-account"),
            environments=["staging", "prod"]
        )

    # Staging/personal use default account
    return StelvioAppConfig(environments=["staging", "prod"])

StelvioApp Class

The StelvioApp class is the main entry point for your infrastructure definition and also defines name of your application.

app = StelvioApp("my-project-name")

Note

The app name is used to identify your infrastructure state. Changing it creates new resources rather than renaming existing ones. See State Management - Renaming for details.

Configuration Options

Function marked with @app.config decorator must return StelvioAppConfig object. It supports several configuration options:

AWS Configuration

Both profile and region are optional overrides. When not specified, Stelvio follows the standard AWS credential and region resolution chain.

Basic Usage

@app.config
def configuration(env: str) -> StelvioAppConfig:
    # Same as 
    # StelvioAppConfig(aws=AwsConfig())
    # Uses standard AWS credential chain described below
    return StelvioAppConfig()  

No AWS configuration needed unless you want to override. This uses the standard AWS resolution order for both credentials and region.

Credential Resolution Order

Stelvio uses boto3 and Pulumi, both following the AWS SDK credential chain:

  1. Explicit profile parameter (override in AwsConfig) - determines which profile's credentials to use
  2. Environment variables: AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN
  3. Assume role providers: AWS_ROLE_ARN + AWS_WEB_IDENTITY_TOKEN_FILE (OIDC/web identity), or role assumption configured in ~/.aws/config
  4. AWS IAM Identity Center (SSO): Configured via aws sso login and ~/.aws/config
  5. Shared credentials file: ~/.aws/credentials
  6. Shared config file: ~/.aws/config
  7. IAM role credentials (when running in AWS): ECS task role, EC2 instance profile, Lambda execution role

Region Resolution Order

  1. Explicit region parameter (override in AwsConfig)
  2. AWS_REGION or AWS_DEFAULT_REGION environment variable
  3. Region from selected profile in ~/.aws/config
  4. If none specified, AWS operations will fail

Examples

Use environment variables (CI/CD):

# Set in environment: AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_REGION
@app.config
def configuration(env: str) -> StelvioAppConfig:
    return StelvioAppConfig()  # Uses env vars automatically

Separate profile for production:

from stelvio.config import AwsConfig

@app.config
def configuration(env: str) -> StelvioAppConfig:
    if env == "prod":
        # Production uses separate AWS account
        return StelvioAppConfig(aws=AwsConfig(profile="production-account"))

    # Staging/personal use default account
    return StelvioAppConfig()

Use AWS SSO:

aws sso login --profile my-sso-profile
from stelvio.config import AwsConfig

@app.config
def configuration(env: str) -> StelvioAppConfig:
    if env=="prod":
        profile = "prod-profile" 
    else:
        profile ="my-sso-profile"

    return StelvioAppConfig(
        aws=AwsConfig(profile=profile)
    )

Override region:

from stelvio.config import AwsConfig

@app.config
def configuration(env: str) -> StelvioAppConfig:
    return StelvioAppConfig(aws=AwsConfig(region="eu-west-1"))

Environment Validation

@app.config
def configuration(env: str) -> StelvioAppConfig:
    return StelvioAppConfig(
        environments=["staging", "prod"]
        # Only these shared environments allowed
    )

With this configuration:

  • Anyone can deploy to their personal environment (username)
  • Only "staging" and "prod" are accepted as shared environments
  • Stelvio will validate environment names and show an error for invalid ones

Common Patterns

Environment-Specific Resources

from stelvio.app import context

...

@app.run
def run() -> None:
    env = context().environment

    if env == "prod":
        # Production-specific resources
        prod_only_lambda = Function(name="backup")

    # Common resources for all environments
    main_table = DynamoTable(name="users", ...)

Next Steps

Now that you understand the StelvioApp structure, you might want to explore: