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

## 2.0.9 (2026-08-21)

### Fixes

- Suppressed stray output from the stackql binary PATH lookup. The `which`/`where` check inherited the terminal's stdout, so the resolved binary path was printed once per lookup (four times during `info`). The check now captures the child process output and only inspects the exit status.

## 2.0.8 (2026-06-29)

### Features
Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "stackql-deploy"
version = "2.0.8"
version = "2.0.9"
edition = "2021"
rust-version = "1.75"
description = "Infrastructure-as-code framework for declarative cloud resource management using StackQL"
Expand Down
4 changes: 2 additions & 2 deletions examples/azure/azure-web-server/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ flowchart LR

| # | Resource | Provider Resource | Description |
|---|----------|-------------------|-------------|
| 1 | `example_resource_group` | `azure.resources.resource_groups` | Resource group for all stack resources |
| 1 | `example_resource_group` | `azure.resource.resource_groups` | Resource group for all stack resources |
| 2 | `example_vnet` | `azure.network.virtual_networks` | Virtual network with environment-specific CIDR |
| 3 | `example_subnet` | `azure.network.subnets` | Subnet within the VNet |
| 4 | `example_public_ip` | `azure.network.public_ip_addresses` | Static public IP for the VM |
| 5 | `example_nsg` | `azure.network.network_security_groups` | NSG allowing HTTP (8080) and SSH (22 from VNet) |
| 6 | `example_nic` | `azure.network.network_interfaces` | NIC with subnet, public IP, and NSG |
| 7 | `example_web_server` | `azure.compute.virtual_machines` | Ubuntu 18.04 VM (Standard_DS1_v2) |
| 7 | `example_web_server` | `azure.compute.virtual_machines` | Ubuntu 24.04 VM (size set by `hardwareProfile` in the manifest) |
| 8 | `example_vm_ext` | `azure.compute.virtual_machine_extensions` | Custom script extension to start a web server |

## Environment-Specific CIDR Blocks
Expand Down
71 changes: 36 additions & 35 deletions examples/azure/azure-web-server/resources/example_nic.iql
Original file line number Diff line number Diff line change
@@ -1,35 +1,36 @@
/*+ createorupdate */
INSERT INTO azure.network.interfaces(
networkInterfaceName,
resourceGroupName,
subscriptionId,
data__location,
data__properties,
data__tags
)
SELECT
'{{ nic_name }}',
'{{ resource_group_name }}',
'{{ subscription_id }}',
'{{ location }}',
'{"ipConfigurations": [ {{ nic_ip_config }} ], "networkSecurityGroup": { "id": "{{ network_security_group_id }}"}}',
'{{ global_tags }}';

/*+ statecheck, retries=5, retry_delay=5 */
SELECT COUNT(*) as count FROM azure.network.interfaces
WHERE subscriptionId = '{{ subscription_id }}'
AND resourceGroupName = '{{ resource_group_name }}'
AND networkInterfaceName = '{{ nic_name }}';

/*+ exports */
SELECT id as network_interface_id
FROM azure.network.interfaces
WHERE subscriptionId = '{{ subscription_id }}'
AND resourceGroupName = '{{ resource_group_name }}'
AND networkInterfaceName = '{{ nic_name }}';

/*+ delete */
DELETE FROM azure.network.interfaces
WHERE subscriptionId = '{{ subscription_id }}'
AND resourceGroupName = '{{ resource_group_name }}'
AND networkInterfaceName = '{{ nic_name }}';
/*+ createorupdate */
INSERT INTO azure.network.network_interfaces(
network_interface_name,
resource_group_name,
subscription_id,
location,
properties,
tags
)
SELECT
'{{ nic_name }}',
'{{ resource_group_name }}',
'{{ subscription_id }}',
'{{ location }}',
'{"ipConfigurations": [ {{ nic_ip_config }} ], "networkSecurityGroup": { "id": "{{ network_security_group_id }}"}}',
'{{ global_tags }}';

/*+ statecheck, retries=5, retry_delay=5 */
SELECT COUNT(*) as count FROM azure.network.network_interfaces
WHERE subscription_id = '{{ subscription_id }}'
AND resource_group_name = '{{ resource_group_name }}'
AND network_interface_name = '{{ nic_name }}'
AND provisioning_state = 'Succeeded'

/*+ exports */
SELECT id as network_interface_id
FROM azure.network.network_interfaces
WHERE subscription_id = '{{ subscription_id }}'
AND resource_group_name = '{{ resource_group_name }}'
AND network_interface_name = '{{ nic_name }}'

/*+ delete */
DELETE FROM azure.network.network_interfaces
WHERE subscription_id = '{{ subscription_id }}'
AND resource_group_name = '{{ resource_group_name }}'
AND network_interface_name = '{{ nic_name }}'
72 changes: 36 additions & 36 deletions examples/azure/azure-web-server/resources/example_nsg.iql
Original file line number Diff line number Diff line change
@@ -1,36 +1,36 @@
/*+ createorupdate */
INSERT INTO azure.network.security_groups(
networkSecurityGroupName,
resourceGroupName,
subscriptionId,
data__location,
data__properties,
data__tags
)
SELECT
'{{ nsg_name }}',
'{{ resource_group_name }}',
'{{ subscription_id }}',
'{{ location }}',
'{"securityRules":{{ security_rules }}}',
'{{ global_tags }}';
/*+ statecheck, retries=5, retry_delay=5 */
SELECT COUNT(*) as count FROM azure.network.security_groups
WHERE subscriptionId = '{{ subscription_id }}'
AND resourceGroupName = '{{ resource_group_name }}'
AND networkSecurityGroupName = '{{ nsg_name }}'
AND JSON_EXTRACT(properties, '$.securityRules') IS NOT NULL
/*+ exports */
SELECT id as network_security_group_id
FROM azure.network.security_groups
WHERE subscriptionId = '{{ subscription_id }}'
AND resourceGroupName = '{{ resource_group_name }}'
AND networkSecurityGroupName = '{{ nsg_name }}'
/*+ delete */
DELETE FROM azure.network.security_groups
WHERE subscriptionId = '{{ subscription_id }}'
AND resourceGroupName = '{{ resource_group_name }}'
AND networkSecurityGroupName = '{{ nsg_name }}'
/*+ createorupdate */
INSERT INTO azure.network.network_security_groups(
network_security_group_name,
resource_group_name,
subscription_id,
location,
properties,
tags
)
SELECT
'{{ nsg_name }}',
'{{ resource_group_name }}',
'{{ subscription_id }}',
'{{ location }}',
'{"securityRules":{{ security_rules }}}',
'{{ global_tags }}';

/*+ statecheck, retries=5, retry_delay=5 */
SELECT COUNT(*) as count FROM azure.network.network_security_groups
WHERE subscription_id = '{{ subscription_id }}'
AND resource_group_name = '{{ resource_group_name }}'
AND network_security_group_name = '{{ nsg_name }}'
AND security_rules IS NOT NULL

/*+ exports */
SELECT id as network_security_group_id
FROM azure.network.network_security_groups
WHERE subscription_id = '{{ subscription_id }}'
AND resource_group_name = '{{ resource_group_name }}'
AND network_security_group_name = '{{ nsg_name }}'

/*+ delete */
DELETE FROM azure.network.network_security_groups
WHERE subscription_id = '{{ subscription_id }}'
AND resource_group_name = '{{ resource_group_name }}'
AND network_security_group_name = '{{ nsg_name }}'
78 changes: 39 additions & 39 deletions examples/azure/azure-web-server/resources/example_public_ip.iql
Original file line number Diff line number Diff line change
@@ -1,39 +1,39 @@
/*+ createorupdate */
INSERT INTO azure.network.public_ip_addresses(
publicIpAddressName,
resourceGroupName,
subscriptionId,
data__location,
data__sku,
data__properties,
data__tags
)
SELECT
'{{ public_ip_name }}',
'{{ resource_group_name }}',
'{{ subscription_id }}',
'{{ location }}',
'{"name":"Standard","tier":"Regional"}',
'{"publicIPAllocationMethod":"Static"}',
'{{ global_tags }}'
/*+ statecheck, retries=5, retry_delay=5 */
SELECT COUNT(*) as count FROM azure.network.public_ip_addresses
WHERE subscriptionId = '{{ subscription_id }}'
AND resourceGroupName = '{{ resource_group_name }}'
AND publicIpAddressName = '{{ public_ip_name }}'
/*+ exports */
SELECT '{{ public_ip_name }}' as public_ip_name,
JSON_EXTRACT(properties, '$.ipAddress') as public_ip_address,
id as public_ip_id
FROM azure.network.public_ip_addresses
WHERE subscriptionId = '{{ subscription_id }}'
AND resourceGroupName = '{{ resource_group_name }}'
AND publicIpAddressName = '{{ public_ip_name }}'
/*+ delete */
DELETE FROM azure.network.public_ip_addresses
WHERE subscriptionId = '{{ subscription_id }}'
AND resourceGroupName = '{{ resource_group_name }}'
AND publicIpAddressName = '{{ public_ip_name }}'
/*+ createorupdate */
INSERT INTO azure.network.public_ip_addresses(
public_ip_address_name,
resource_group_name,
subscription_id,
location,
sku,
properties,
tags
)
SELECT
'{{ public_ip_name }}',
'{{ resource_group_name }}',
'{{ subscription_id }}',
'{{ location }}',
'{"name":"Standard","tier":"Regional"}',
'{"publicIPAllocationMethod":"Static"}',
'{{ global_tags }}'

/*+ statecheck, retries=5, retry_delay=5 */
SELECT COUNT(*) as count FROM azure.network.public_ip_addresses
WHERE subscription_id = '{{ subscription_id }}'
AND resource_group_name = '{{ resource_group_name }}'
AND public_ip_address_name = '{{ public_ip_name }}'

/*+ exports */
SELECT '{{ public_ip_name }}' as public_ip_name,
ip_address as public_ip_address,
id as public_ip_id
FROM azure.network.public_ip_addresses
WHERE subscription_id = '{{ subscription_id }}'
AND resource_group_name = '{{ resource_group_name }}'
AND public_ip_address_name = '{{ public_ip_name }}'

/*+ delete */
DELETE FROM azure.network.public_ip_addresses
WHERE subscription_id = '{{ subscription_id }}'
AND resource_group_name = '{{ resource_group_name }}'
AND public_ip_address_name = '{{ public_ip_name }}'
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
/*+ exists */
SELECT COUNT(*) as count FROM azure.resources.resource_groups
WHERE subscriptionId = '{{ subscription_id }}'
AND resourceGroupName = '{{ resource_group_name }}'
/*+ create */
INSERT INTO azure.resources.resource_groups(
resourceGroupName,
subscriptionId,
data__location,
data__tags
)
SELECT
'{{ resource_group_name }}',
'{{ subscription_id }}',
'{{ location }}',
'{{ global_tags }}'
/*+ statecheck, retries=5, retry_delay=5 */
SELECT COUNT(*) as count FROM azure.resources.resource_groups
WHERE subscriptionId = '{{ subscription_id }}'
AND resourceGroupName = '{{ resource_group_name }}'
AND location = '{{ location }}'
AND JSON_EXTRACT(properties, '$.provisioningState') = 'Succeeded'
/*+ exports */
SELECT '{{ resource_group_name }}' as resource_group_name
/*+ delete */
DELETE FROM azure.resources.resource_groups
WHERE resourceGroupName = '{{ resource_group_name }}' AND subscriptionId = '{{ subscription_id }}'
/*+ exists */
SELECT COUNT(*) as count FROM azure.resource.resource_groups
WHERE subscription_id = '{{ subscription_id }}'
AND resource_group_name = '{{ resource_group_name }}'

/*+ create */
INSERT INTO azure.resource.resource_groups(
resource_group_name,
subscription_id,
location,
tags
)
SELECT
'{{ resource_group_name }}',
'{{ subscription_id }}',
'{{ location }}',
'{{ global_tags }}'

/*+ statecheck, retries=5, retry_delay=5 */
SELECT COUNT(*) as count FROM azure.resource.resource_groups
WHERE subscription_id = '{{ subscription_id }}'
AND resource_group_name = '{{ resource_group_name }}'
AND location = '{{ location }}'
AND provisioning_state = 'Succeeded'

/*+ exports */
SELECT '{{ resource_group_name }}' as resource_group_name

/*+ delete */
DELETE FROM azure.resource.resource_groups
WHERE resource_group_name = '{{ resource_group_name }}' AND subscription_id = '{{ subscription_id }}'
Loading