Skip to content
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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## 1.8.8 (2025-10-15)

- Added performance enhancement query strategy

## 1.8.7 (2025-10-14)

- Added tab completion
Expand Down
49 changes: 41 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,18 +130,25 @@ Deployment orchestration using `stackql-deploy` includes:
- **_deployment_** scripts, which are StackQL queries to create or update resoruces (or delete in the case of de-provisioning)
- **_post-deployment_** tests, which are StackQL queries to confirm that resources were deployed and have the desired state

This process is described here:
**Performance Optimization**: `stackql-deploy` uses an intelligent query optimization strategy which is described here:

```mermaid
graph TB
A[Start] --> B{foreach\nresource}
B --> C[exists\ncheck]
C --> D{resource\nexists?}
D -- Yes --> E[run update\nor createorupdate query]
D -- No --> F[run create\nor createorupdate query]
E --> G[run statecheck check]
F --> G
G --> H{End}
B --> C{exports query\navailable?}
C -- Yes --> D[try exports first\n🔄 optimal path]
C -- No --> E[exists\ncheck]
D --> F{exports\nsuccess?}
F -- Yes --> G[✅ validated with\n1 query only]
F -- No --> E
E --> H{resource\nexists?}
H -- Yes --> I[run update\nor createorupdate query]
H -- No --> J[run create\nor createorupdate query]
I --> K[run statecheck check]
J --> K
G --> L[reuse exports result]
K --> M{End}
L --> M
```

### `INSERT`, `UPDATE`, `DELETE` queries
Expand Down Expand Up @@ -187,8 +194,34 @@ WHERE subscriptionId = '{{ subscription_id }}'
AND resourceGroupName = '{{ resource_group_name }}'
AND location = '{{ location }}'
AND JSON_EXTRACT(properties, '$.provisioningState') = 'Succeeded'

/*+ exports */
SELECT resourceGroupName, location, JSON_EXTRACT(properties, '$.provisioningState') as state
FROM azure.resources.resource_groups
WHERE subscriptionId = '{{ subscription_id }}'
AND resourceGroupName = '{{ resource_group_name }}'
```

### Query Optimization

`stackql-deploy` implements intelligent query optimization that significantly improves performance:

**Traditional Flow (3 queries):**
1. `exists` - check if resource exists
2. `statecheck` - validate resource configuration
3. `exports` - extract variables for dependent resources

**Optimized Flow (1 query in happy path):**
1. **Try `exports` first** - if this succeeds, it validates existence, state, and extracts variables in one operation
2. **Fallback to traditional flow** only if exports fails

**Performance Benefits:**
- Up to **66% reduction** in API calls for existing, correctly configured resources
- **2-3x faster** deployments in typical scenarios
- Maintains full validation integrity and backward compatibility

**Best Practice:** Design your `exports` queries to include the validation logic from `statecheck` queries to maximize the benefits of this optimization.

## Usage

<!-- > see [__readthedocs__]() for more detailed documentation -->
Expand Down
17 changes: 7 additions & 10 deletions examples/databricks/serverless/resources/aws/s3/s3_bucket.iql
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,14 @@ WHERE
region = '{{ region }}'
AND data__Identifier = '{{ bucket_name }}'

/*+ statecheck, retries=3, retry_delay=5 */
SELECT COUNT(*) as count FROM (
/*+ exports, retries=3, retry_delay=5 */
SELECT
arn,
bucket_name
FROM (
SELECT
arn,
bucket_name,
JSON_EQUAL(ownership_controls, '{{ ownership_controls }}') as test_ownership_controls,
JSON_EQUAL(bucket_encryption, '{{ bucket_encryption }}') as test_encryption,
JSON_EQUAL(public_access_block_configuration, '{{ public_access_block_configuration }}') as test_public_access_block_configuration,
Expand All @@ -51,11 +56,3 @@ WHERE test_ownership_controls = 1
AND test_encryption = 1
AND test_public_access_block_configuration = 1
AND test_versioning_configuration = 1

/*+ exports, retries=3, retry_delay=5 */
SELECT
arn,
bucket_name
FROM aws.s3.buckets
WHERE region = '{{ region }}'
AND data__Identifier = '{{ bucket_name }}'
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,15 @@ SELECT
'{{ credentials_name }}',
'{{ aws_credentials }}'

/*+ statecheck, retries=3, retry_delay=5 */
SELECT COUNT(*) as count FROM
(
SELECT
credentials_id
FROM databricks_account.provisioning.credentials
WHERE account_id = '{{ databricks_account_id }}'
AND credentials_name = '{{ credentials_name }}'
AND JSON_EXTRACT(aws_credentials, '$.sts_role.role_arn') = '{{ aws_iam_cross_account_role_arn }}'
) t

/*+ exports */
/*+ exports, retries=3, retry_delay=5 */
SELECT
'{{ credentials_name }}' as databricks_credentials_name,
credentials_id as databricks_credentials_id,
JSON_EXTRACT(aws_credentials, '$.sts_role.external_id') as databricks_role_external_id
FROM databricks_account.provisioning.credentials
WHERE account_id = '{{ databricks_account_id }}'
AND credentials_name = '{{ credentials_name }}'
AND JSON_EXTRACT(aws_credentials, '$.sts_role.role_arn') = '{{ aws_iam_cross_account_role_arn }}'

/*+ delete */
DELETE FROM databricks_account.provisioning.credentials
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,26 +19,21 @@ SELECT
'{{ subnet_ids }}',
'{{ security_group_ids }}'

/*+ statecheck, retries=3, retry_delay=5 */
SELECT COUNT(*) as count FROM
(
/*+ exports, retries=3, retry_delay=5 */
SELECT
network_id as databricks_network_id
FROM (
SELECT
network_id,
JSON_EQUAL(subnet_ids, '{{ subnet_ids }}') as subnet_test,
JSON_EQUAL(security_group_ids, '{{ security_group_ids }}') as sg_test
FROM databricks_account.provisioning.networks
WHERE account_id = '{{ databricks_account_id }}'
AND network_name = '{{ databricks_network_name }}'
AND vpc_id = '{{ vpc_id }}'
AND subnet_test = 1
AND sg_test = 1
)t

/*+ exports */
SELECT
network_id as databricks_network_id
FROM databricks_account.provisioning.networks
WHERE account_id = '{{ databricks_account_id }}' AND
network_name = '{{ databricks_network_name }}'
WHERE subnet_test = 1
AND sg_test = 1

/*+ delete */
DELETE FROM databricks_account.provisioning.networks
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,13 @@ SELECT
'{{ storage_configuration_name }}',
'{{ root_bucket_info }}'

/*+ statecheck, retries=3, retry_delay=5 */
SELECT COUNT(*) as count
FROM databricks_account.provisioning.storage
WHERE account_id = '{{ databricks_account_id }}'
AND storage_configuration_name = '{{ storage_configuration_name }}'
AND JSON_EXTRACT(root_bucket_info, '$.bucket_name') = '{{ aws_s3_workspace_bucket_name }}'

/*+ exports */
/*+ exports, retries=3, retry_delay=5 */
SELECT
storage_configuration_id as databricks_storage_configuration_id
FROM databricks_account.provisioning.storage
WHERE account_id = '{{ databricks_account_id }}'
AND storage_configuration_name = '{{ storage_configuration_name }}'
AND JSON_EXTRACT(root_bucket_info, '$.bucket_name') = '{{ aws_s3_workspace_bucket_name }}'

/*+ delete */
DELETE FROM databricks_account.provisioning.storage
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,24 +21,18 @@ SELECT
'{{ storage_configuration_id }}',
'{{ pricing_tier }}'

/*+ statecheck, retries=3, retry_delay=5 */
SELECT COUNT(*) as count
FROM databricks_account.provisioning.workspaces
WHERE account_id = '{{ databricks_account_id }}'
AND workspace_name = '{{ workspace_name }}'
AND aws_region = '{{ aws_region }}'
AND credentials_id = '{{ credentials_id }}'
AND storage_configuration_id = '{{ storage_configuration_id }}'
AND pricing_tier = '{{ pricing_tier }}'

/*+ exports */
/*+ exports, retries=3, retry_delay=5 */
SELECT
'{{ workspace_name }}' AS databricks_workspace_name,
workspace_id AS databricks_workspace_id,
deployment_name AS databricks_deployment_name
FROM databricks_account.provisioning.workspaces
WHERE account_id = '{{ databricks_account_id }}'
AND workspace_name = '{{ workspace_name }}'
AND aws_region = '{{ aws_region }}'
AND credentials_id = '{{ credentials_id }}'
AND storage_configuration_id = '{{ storage_configuration_id }}'
AND pricing_tier = '{{ pricing_tier }}'

/*+ delete */
DELETE FROM databricks_account.provisioning.workspaces
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,7 @@ SELECT
'{{ databricks_account_id }}',
'{{ display_name }}'

/*+ statecheck, retries=3, retry_delay=5 */
SELECT COUNT(*) as count
FROM databricks_account.iam.groups
WHERE account_id = '{{ databricks_account_id }}'
AND displayName = '{{ display_name }}'

/*+ exports */
/*+ exports, retries=3, retry_delay=5 */
SELECT id AS databricks_group_id,
displayName AS databricks_group_name
FROM databricks_account.iam.groups
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,21 +24,15 @@ SELECT
{{ skip_validation }}
;

/*+ statecheck, retries=3, retry_delay=5 */
SELECT COUNT(*) as count
/*+ exports, retries=3, retry_delay=5 */
SELECT name as external_location_name
FROM databricks_workspace.unitycatalog.external_locations
WHERE name = '{{ name | replace('-', '_') }}' AND
deployment_name = '{{ databricks_deployment_name }}'
AND url = '{{ url }}' AND
credential_name = '{{ credential_name | replace('-', '_') }}' AND
read_only = {{ read_only }} AND
comment = '{{ comment }}';

/*+ exports */
SELECT name as external_location_name
FROM databricks_workspace.unitycatalog.external_locations
WHERE name = '{{ name | replace('-', '_') }}' AND
deployment_name = '{{ databricks_deployment_name }}'

/*+ delete */
DELETE FROM databricks_workspace.unitycatalog.external_locations
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,14 @@ SELECT
'{{ skip_validation }}'
;

/*+ statecheck, retries=3, retry_delay=5 */
SELECT COUNT(*) as count
FROM databricks_workspace.unitycatalog.storage_credentials
WHERE name = '{{ name | replace('-', '_') | upper }}' AND
deployment_name = '{{ databricks_deployment_name }}' AND
JSON_EXTRACT(aws_iam_role, '$.role_arn') = '{{ metastore_access_role_arn }}';

/*+ exports */
/*+ exports, retries=3, retry_delay=5 */
SELECT
name as storage_credential_name,
JSON_EXTRACT(aws_iam_role, '$.external_id') as storage_credential_external_id
FROM databricks_workspace.unitycatalog.storage_credentials
WHERE name = '{{ name | replace('-', '_') | upper }}' AND
deployment_name = '{{ databricks_deployment_name }}';
deployment_name = '{{ databricks_deployment_name }}' AND
JSON_EXTRACT(aws_iam_role, '$.role_arn') = '{{ metastore_access_role_arn }}';

/*+ delete */
DELETE FROM databricks_workspace.unitycatalog.storage_credentials
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

setup(
name='stackql-deploy',
version='1.8.7',
version='1.8.8',
description='Model driven resource provisioning and deployment framework using StackQL.',
long_description=readme,
long_description_content_type='text/x-rst',
Expand Down
2 changes: 1 addition & 1 deletion stackql_deploy/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '1.8.7'
__version__ = '1.8.8'
Loading
Loading