alchemy 0.60.2 → 0.62.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. package/README.md +1 -2
  2. package/bin/alchemy.js +1480 -1498
  3. package/bin/commands/init.ts +94 -25
  4. package/bin/services/execute-alchemy.ts +32 -23
  5. package/lib/alchemy.d.ts +2 -2
  6. package/lib/alchemy.d.ts.map +1 -1
  7. package/lib/alchemy.js +1 -0
  8. package/lib/alchemy.js.map +1 -1
  9. package/lib/aws/client-props.d.ts +149 -0
  10. package/lib/aws/client-props.d.ts.map +1 -0
  11. package/lib/aws/client-props.js +1 -0
  12. package/lib/aws/client-props.js.map +1 -0
  13. package/lib/aws/credentials.d.ts +68 -5
  14. package/lib/aws/credentials.d.ts.map +1 -1
  15. package/lib/aws/credentials.js +148 -0
  16. package/lib/aws/credentials.js.map +1 -1
  17. package/lib/aws/ec2/internet-gateway-attachment.d.ts +57 -3
  18. package/lib/aws/ec2/internet-gateway-attachment.d.ts.map +1 -1
  19. package/lib/aws/ec2/internet-gateway-attachment.js +57 -3
  20. package/lib/aws/ec2/internet-gateway-attachment.js.map +1 -1
  21. package/lib/aws/ec2/internet-gateway.d.ts +68 -40
  22. package/lib/aws/ec2/internet-gateway.d.ts.map +1 -1
  23. package/lib/aws/ec2/internet-gateway.js +68 -40
  24. package/lib/aws/ec2/internet-gateway.js.map +1 -1
  25. package/lib/aws/ec2/nat-gateway.d.ts +99 -18
  26. package/lib/aws/ec2/nat-gateway.d.ts.map +1 -1
  27. package/lib/aws/ec2/nat-gateway.js +113 -37
  28. package/lib/aws/ec2/nat-gateway.js.map +1 -1
  29. package/lib/aws/ec2/route-table-association.d.ts +1 -1
  30. package/lib/aws/ec2/route-table-association.js +1 -1
  31. package/lib/aws/ec2/route-table.d.ts +64 -1
  32. package/lib/aws/ec2/route-table.d.ts.map +1 -1
  33. package/lib/aws/ec2/route-table.js +64 -1
  34. package/lib/aws/ec2/route-table.js.map +1 -1
  35. package/lib/aws/ec2/route.d.ts +60 -1
  36. package/lib/aws/ec2/route.d.ts.map +1 -1
  37. package/lib/aws/ec2/route.js +60 -1
  38. package/lib/aws/ec2/route.js.map +1 -1
  39. package/lib/aws/ec2/security-group.d.ts +96 -3
  40. package/lib/aws/ec2/security-group.d.ts.map +1 -1
  41. package/lib/aws/ec2/security-group.js +96 -3
  42. package/lib/aws/ec2/security-group.js.map +1 -1
  43. package/lib/aws/ec2/subnet.d.ts +61 -3
  44. package/lib/aws/ec2/subnet.d.ts.map +1 -1
  45. package/lib/aws/ec2/subnet.js +61 -3
  46. package/lib/aws/ec2/subnet.js.map +1 -1
  47. package/lib/aws/ec2/utils.d.ts +10 -2
  48. package/lib/aws/ec2/utils.d.ts.map +1 -1
  49. package/lib/aws/ec2/utils.js +68 -7
  50. package/lib/aws/ec2/utils.js.map +1 -1
  51. package/lib/aws/ec2/vpc.d.ts +50 -2
  52. package/lib/aws/ec2/vpc.d.ts.map +1 -1
  53. package/lib/aws/ec2/vpc.js +50 -2
  54. package/lib/aws/ec2/vpc.js.map +1 -1
  55. package/lib/aws/index.d.ts +2 -0
  56. package/lib/aws/index.d.ts.map +1 -1
  57. package/lib/aws/index.js +2 -0
  58. package/lib/aws/index.js.map +1 -1
  59. package/lib/cloudflare/api-response.js +2 -2
  60. package/lib/cloudflare/api-response.js.map +1 -1
  61. package/lib/cloudflare/api.d.ts +19 -0
  62. package/lib/cloudflare/api.d.ts.map +1 -1
  63. package/lib/cloudflare/api.js +4 -0
  64. package/lib/cloudflare/api.js.map +1 -1
  65. package/lib/cloudflare/assets.d.ts.map +1 -1
  66. package/lib/cloudflare/assets.js +3 -4
  67. package/lib/cloudflare/assets.js.map +1 -1
  68. package/lib/cloudflare/bucket.d.ts +5 -3
  69. package/lib/cloudflare/bucket.d.ts.map +1 -1
  70. package/lib/cloudflare/bucket.js +28 -20
  71. package/lib/cloudflare/bucket.js.map +1 -1
  72. package/lib/cloudflare/bundle/plugin-compat-warning.js +7 -7
  73. package/lib/cloudflare/bundle/plugin-compat-warning.js.map +1 -1
  74. package/lib/cloudflare/cloudflare-env-proxy.js.map +1 -1
  75. package/lib/cloudflare/compatibility-date.gen.d.ts +1 -1
  76. package/lib/cloudflare/compatibility-date.gen.js +1 -1
  77. package/lib/cloudflare/d1-migrations.d.ts.map +1 -1
  78. package/lib/cloudflare/d1-migrations.js +3 -2
  79. package/lib/cloudflare/d1-migrations.js.map +1 -1
  80. package/lib/cloudflare/index.d.ts +2 -1
  81. package/lib/cloudflare/index.d.ts.map +1 -1
  82. package/lib/cloudflare/index.js +2 -1
  83. package/lib/cloudflare/index.js.map +1 -1
  84. package/lib/cloudflare/kv-namespace.d.ts +2 -2
  85. package/lib/cloudflare/kv-namespace.d.ts.map +1 -1
  86. package/lib/cloudflare/kv-namespace.js.map +1 -1
  87. package/lib/cloudflare/miniflare/build-worker-options.d.ts.map +1 -1
  88. package/lib/cloudflare/miniflare/build-worker-options.js +16 -3
  89. package/lib/cloudflare/miniflare/build-worker-options.js.map +1 -1
  90. package/lib/cloudflare/miniflare/miniflare-controller.d.ts.map +1 -1
  91. package/lib/cloudflare/miniflare/miniflare-controller.js +3 -0
  92. package/lib/cloudflare/miniflare/miniflare-controller.js.map +1 -1
  93. package/lib/cloudflare/oauth.js +3 -3
  94. package/lib/cloudflare/oauth.js.map +1 -1
  95. package/lib/cloudflare/quick-tunnel.d.ts +17 -0
  96. package/lib/cloudflare/quick-tunnel.d.ts.map +1 -0
  97. package/lib/cloudflare/quick-tunnel.js +26 -0
  98. package/lib/cloudflare/quick-tunnel.js.map +1 -0
  99. package/lib/cloudflare/sveltekit/plugin.d.ts +2 -2
  100. package/lib/cloudflare/sveltekit/plugin.d.ts.map +1 -1
  101. package/lib/cloudflare/sveltekit/plugin.js +5 -4
  102. package/lib/cloudflare/sveltekit/plugin.js.map +1 -1
  103. package/lib/cloudflare/website.d.ts.map +1 -1
  104. package/lib/cloudflare/website.js +26 -97
  105. package/lib/cloudflare/website.js.map +1 -1
  106. package/lib/cloudflare/worker-bundle.d.ts.map +1 -1
  107. package/lib/cloudflare/worker-bundle.js +11 -9
  108. package/lib/cloudflare/worker-bundle.js.map +1 -1
  109. package/lib/cloudflare/worker-tail.d.ts.map +1 -1
  110. package/lib/cloudflare/worker-tail.js +6 -6
  111. package/lib/cloudflare/worker-tail.js.map +1 -1
  112. package/lib/resource.d.ts +1 -0
  113. package/lib/resource.d.ts.map +1 -1
  114. package/lib/resource.js +13 -2
  115. package/lib/resource.js.map +1 -1
  116. package/lib/scope.d.ts +38 -1
  117. package/lib/scope.d.ts.map +1 -1
  118. package/lib/scope.js +44 -19
  119. package/lib/scope.js.map +1 -1
  120. package/lib/state/cloudflare-state-store.d.ts.map +1 -1
  121. package/lib/state/cloudflare-state-store.js +2 -1
  122. package/lib/state/cloudflare-state-store.js.map +1 -1
  123. package/lib/util/idempotent-spawn.d.ts +24 -0
  124. package/lib/util/idempotent-spawn.d.ts.map +1 -0
  125. package/lib/util/idempotent-spawn.js +237 -0
  126. package/lib/util/idempotent-spawn.js.map +1 -0
  127. package/lib/util/index.d.ts +2 -0
  128. package/lib/util/index.d.ts.map +1 -0
  129. package/lib/util/index.js +2 -0
  130. package/lib/util/index.js.map +1 -0
  131. package/lib/util/safe-fetch.d.ts +24 -0
  132. package/lib/util/safe-fetch.d.ts.map +1 -1
  133. package/lib/util/safe-fetch.js +72 -0
  134. package/lib/util/safe-fetch.js.map +1 -1
  135. package/package.json +9 -5
  136. package/src/alchemy.ts +3 -2
  137. package/src/aws/client-props.ts +156 -0
  138. package/src/aws/credentials.ts +165 -4
  139. package/src/aws/ec2/internet-gateway-attachment.ts +59 -4
  140. package/src/aws/ec2/internet-gateway.ts +70 -41
  141. package/src/aws/ec2/nat-gateway.ts +123 -33
  142. package/src/aws/ec2/route-table-association.ts +1 -1
  143. package/src/aws/ec2/route-table.ts +66 -2
  144. package/src/aws/ec2/route.ts +62 -2
  145. package/src/aws/ec2/security-group.ts +98 -4
  146. package/src/aws/ec2/subnet.ts +63 -4
  147. package/src/aws/ec2/utils.ts +73 -7
  148. package/src/aws/ec2/vpc.ts +52 -3
  149. package/src/aws/index.ts +2 -0
  150. package/src/cloudflare/api-response.ts +2 -2
  151. package/src/cloudflare/api.ts +23 -0
  152. package/src/cloudflare/assets.ts +3 -4
  153. package/src/cloudflare/bucket.ts +39 -29
  154. package/src/cloudflare/bundle/plugin-compat-warning.ts +7 -7
  155. package/src/cloudflare/cloudflare-env-proxy.ts +2 -2
  156. package/src/cloudflare/compatibility-date.gen.ts +1 -1
  157. package/src/cloudflare/d1-migrations.ts +4 -5
  158. package/src/cloudflare/index.ts +2 -1
  159. package/src/cloudflare/kv-namespace.ts +26 -27
  160. package/src/cloudflare/miniflare/build-worker-options.ts +16 -3
  161. package/src/cloudflare/miniflare/miniflare-controller.ts +4 -0
  162. package/src/cloudflare/oauth.ts +3 -3
  163. package/src/cloudflare/quick-tunnel.ts +30 -0
  164. package/src/cloudflare/sveltekit/plugin.ts +5 -5
  165. package/src/cloudflare/website.ts +30 -111
  166. package/src/cloudflare/worker-bundle.ts +11 -9
  167. package/src/cloudflare/worker-tail.ts +6 -8
  168. package/src/resource.ts +19 -2
  169. package/src/scope.ts +111 -20
  170. package/src/state/cloudflare-state-store.ts +2 -1
  171. package/src/util/idempotent-spawn.ts +303 -0
  172. package/src/util/index.ts +1 -0
  173. package/src/util/safe-fetch.ts +114 -0
  174. package/templates/rwsdk/package.json +1 -1
@@ -9,12 +9,13 @@ import {
9
9
  type TimeoutConfig,
10
10
  waitForResourceState,
11
11
  } from "../../util/timeout.ts";
12
+ import type { AwsClientProps } from "../client-props.ts";
12
13
  import { callEC2Api, createEC2Client } from "./utils.ts";
13
14
 
14
15
  /**
15
16
  * Properties for creating or updating an Internet Gateway
16
17
  */
17
- export interface InternetGatewayProps {
18
+ export interface InternetGatewayProps extends AwsClientProps {
18
19
  /**
19
20
  * Tags to apply to the Internet Gateway
20
21
  */
@@ -145,12 +146,15 @@ async function waitForInternetGatewayDeleted(
145
146
  * 1. Provide a target in your VPC route tables for internet-routable traffic
146
147
  * 2. Perform network address translation (NAT) for instances with public IPv4 addresses
147
148
  *
149
+ * Supports AWS credential overrides at the resource level, allowing you to deploy Internet Gateways
150
+ * to different AWS accounts or regions than the default scope configuration.
151
+ *
148
152
  * @example
149
153
  * ```typescript
150
154
  * // Create a basic Internet Gateway
151
- * const igw = new InternetGateway({
155
+ * const igw = await InternetGateway("main-igw", {
152
156
  * tags: {
153
- * Name: "my-internet-gateway",
157
+ * Name: "main-internet-gateway",
154
158
  * Environment: "production"
155
159
  * }
156
160
  * });
@@ -158,59 +162,49 @@ async function waitForInternetGatewayDeleted(
158
162
  *
159
163
  * @example
160
164
  * ```typescript
161
- * // Create Internet Gateway with custom timeout configuration
162
- * const igw = new InternetGateway({
163
- * tags: { Name: "custom-igw" },
164
- * timeoutConfig: {
165
- * maxAttempts: 30,
166
- * delayMs: 1000
165
+ * // Create Internet Gateway with AWS credential overrides
166
+ * const crossAccountIgw = await InternetGateway("cross-account-igw", {
167
+ * // Override AWS credentials for this specific resource
168
+ * region: "us-east-1",
169
+ * profile: "production-account",
170
+ * tags: {
171
+ * Name: "cross-account-internet-gateway",
172
+ * Environment: "production"
167
173
  * }
168
174
  * });
169
175
  * ```
170
176
  *
171
177
  * @example
172
178
  * ```typescript
173
- * // Create Internet Gateway and attach to VPC
174
- * const vpc = new VPC({ cidrBlock: "10.0.0.0/16" });
175
- * const igw = new InternetGateway({ tags: { Name: "vpc-igw" } });
176
- * const attachment = new InternetGatewayAttachment({
177
- * internetGatewayId: igw.internetGatewayId,
178
- * vpcId: vpc.vpcId
179
- * });
180
- * ```
181
- *
182
- * @example
183
- * ```typescript
184
- * // Access Internet Gateway properties
185
- * const igw = new InternetGateway({ tags: { Name: "example-igw" } });
186
- * logger.log(`Internet Gateway ID: ${igw.internetGatewayId}`);
187
- * logger.log(`State: ${igw.state}`);
188
- * ```
189
- *
190
- * Creates and manages Internet Gateways that provide internet access to VPCs.
191
- * Note: Use InternetGatewayAttachment to attach the gateway to a VPC.
192
- *
193
- * @example
194
- * // Create a basic Internet Gateway
195
- * const igw = await InternetGateway("main-igw", {
179
+ * // Create Internet Gateway in different region with role assumption
180
+ * const multiRegionIgw = await InternetGateway("multi-region-igw", {
181
+ * region: "eu-west-1",
182
+ * roleArn: "arn:aws:iam::123456789012:role/CrossRegionRole",
183
+ * roleSessionName: "internet-gateway-deployment",
196
184
  * tags: {
197
- * Name: "main-internet-gateway",
198
- * Environment: "production"
185
+ * Name: "eu-internet-gateway",
186
+ * Region: "europe"
199
187
  * }
200
188
  * });
189
+ * ```
201
190
  *
202
191
  * @example
203
- * // Create an Internet Gateway for development environment
204
- * const devIgw = await InternetGateway("dev-igw", {
192
+ * ```typescript
193
+ * // Create Internet Gateway with explicit credentials
194
+ * const explicitCredsIgw = await InternetGateway("explicit-creds-igw", {
195
+ * accessKeyId: alchemy.secret("AKIAIOSFODNN7EXAMPLE"),
196
+ * secretAccessKey: alchemy.secret("wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"),
197
+ * region: "us-west-2",
205
198
  * tags: {
206
- * Name: "dev-internet-gateway",
207
- * Environment: "development",
208
- * Team: "backend"
199
+ * Name: "explicit-credentials-igw",
200
+ * Purpose: "testing"
209
201
  * }
210
202
  * });
203
+ * ```
211
204
  *
212
205
  * @example
213
- * // Create an Internet Gateway with custom timeout configuration
206
+ * ```typescript
207
+ * // Create Internet Gateway with custom timeout configuration
214
208
  * const customIgw = await InternetGateway("custom-igw", {
215
209
  * timeout: {
216
210
  * maxAttempts: 90,
@@ -221,6 +215,40 @@ async function waitForInternetGatewayDeleted(
221
215
  * Purpose: "high-availability"
222
216
  * }
223
217
  * });
218
+ * ```
219
+ *
220
+ * @example
221
+ * ```typescript
222
+ * // Create Internet Gateway and attach to VPC
223
+ * const vpc = await VPC("main-vpc", { cidrBlock: "10.0.0.0/16" });
224
+ * const igw = await InternetGateway("vpc-igw", {
225
+ * tags: { Name: "vpc-internet-gateway" }
226
+ * });
227
+ * const attachment = await InternetGatewayAttachment("igw-attachment", {
228
+ * internetGatewayId: igw.internetGatewayId,
229
+ * vpcId: vpc.vpcId
230
+ * });
231
+ * ```
232
+ *
233
+ * @example
234
+ * ```typescript
235
+ * // Multi-account deployment with scope-level and resource-level overrides
236
+ * await alchemy.run("production", {
237
+ * aws: { region: "us-west-2", profile: "main-account" }
238
+ * }, async () => {
239
+ * // This IGW uses scope credentials (main-account, us-west-2)
240
+ * const mainIgw = await InternetGateway("main-igw", {
241
+ * tags: { Name: "main-account-igw" }
242
+ * });
243
+ *
244
+ * // This IGW overrides to use different account
245
+ * const crossAccountIgw = await InternetGateway("cross-account-igw", {
246
+ * profile: "secondary-account",
247
+ * region: "us-east-1", // Also override region
248
+ * tags: { Name: "secondary-account-igw" }
249
+ * });
250
+ * });
251
+ * ```
224
252
  */
225
253
  export const InternetGateway = Resource(
226
254
  "aws::InternetGateway",
@@ -229,7 +257,8 @@ export const InternetGateway = Resource(
229
257
  _id: string,
230
258
  props: InternetGatewayProps,
231
259
  ): Promise<InternetGateway> {
232
- const client = await createEC2Client();
260
+ // Create EC2 client with credential resolution handled internally
261
+ const client = await createEC2Client(props);
233
262
  const timeoutConfig = mergeTimeoutConfig(
234
263
  INTERNET_GATEWAY_TIMEOUT,
235
264
  props.timeout,
@@ -8,13 +8,14 @@ import {
8
8
  type TimeoutConfig,
9
9
  waitForResourceState,
10
10
  } from "../../util/timeout.ts";
11
+ import type { AwsClientProps } from "../client-props.ts";
11
12
  import type { Subnet } from "./subnet.ts";
12
13
  import { callEC2Api, createEC2Client } from "./utils.ts";
13
14
 
14
15
  /**
15
16
  * Properties for creating or updating a NAT Gateway
16
17
  */
17
- export interface NatGatewayProps {
18
+ export interface NatGatewayProps extends AwsClientProps {
18
19
  /**
19
20
  * The subnet to create the NAT Gateway in (must be a public subnet)
20
21
  */
@@ -99,39 +100,94 @@ export interface NatGateway
99
100
  * if one is not provided. NAT Gateways are slow resources that can take
100
101
  * up to 10 minutes to become available.
101
102
  *
103
+ * Supports AWS credential overrides at the resource level, allowing you to deploy NAT Gateways
104
+ * to different AWS accounts or regions than the default scope configuration.
105
+ *
102
106
  * @example
107
+ * ```typescript
103
108
  * // Create a NAT Gateway with automatic Elastic IP allocation
104
109
  * const natGateway = await NatGateway("main-nat", {
105
- * subnet: publicSubnet,
106
- * tags: {
107
- * Name: "main-nat-gateway",
108
- * Environment: "production"
109
- * }
110
+ * subnet: publicSubnet,
111
+ * tags: {
112
+ * Name: "main-nat-gateway",
113
+ * Environment: "production"
114
+ * }
115
+ * });
116
+ * ```
117
+ *
118
+ * @example
119
+ * ```typescript
120
+ * // Create NAT Gateway with AWS credential overrides
121
+ * const crossAccountNat = await NatGateway("cross-account-nat", {
122
+ * subnet: publicSubnet,
123
+ * // Override AWS credentials for this specific resource
124
+ * region: "us-east-1",
125
+ * profile: "production-account",
126
+ * tags: {
127
+ * Name: "cross-account-nat-gateway",
128
+ * Environment: "production"
129
+ * }
130
+ * });
131
+ * ```
132
+ *
133
+ * @example
134
+ * ```typescript
135
+ * // Create NAT Gateway in different region with role assumption
136
+ * const multiRegionNat = await NatGateway("multi-region-nat", {
137
+ * subnet: euPublicSubnet,
138
+ * region: "eu-west-1",
139
+ * roleArn: "arn:aws:iam::123456789012:role/CrossRegionRole",
140
+ * roleSessionName: "nat-gateway-deployment",
141
+ * tags: {
142
+ * Name: "eu-nat-gateway",
143
+ * Region: "europe"
144
+ * }
110
145
  * });
146
+ * ```
111
147
  *
112
148
  * @example
149
+ * ```typescript
150
+ * // Create NAT Gateway with explicit credentials
151
+ * const explicitCredsNat = await NatGateway("explicit-creds-nat", {
152
+ * subnet: testPublicSubnet,
153
+ * accessKeyId: alchemy.secret("AKIAIOSFODNN7EXAMPLE"),
154
+ * secretAccessKey: alchemy.secret("wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"),
155
+ * region: "us-west-2",
156
+ * tags: {
157
+ * Name: "explicit-credentials-nat",
158
+ * Purpose: "testing"
159
+ * }
160
+ * });
161
+ * ```
162
+ *
163
+ * @example
164
+ * ```typescript
113
165
  * // Create a NAT Gateway with existing Elastic IP
114
166
  * const natGateway = await NatGateway("custom-nat", {
115
- * subnet: "subnet-12345678",
116
- * allocationId: "eipalloc-12345678",
117
- * connectivityType: "public",
118
- * tags: {
119
- * Name: "custom-nat-gateway"
120
- * }
167
+ * subnet: "subnet-12345678",
168
+ * allocationId: "eipalloc-12345678",
169
+ * connectivityType: "public",
170
+ * tags: {
171
+ * Name: "custom-nat-gateway"
172
+ * }
121
173
  * });
174
+ * ```
122
175
  *
123
176
  * @example
177
+ * ```typescript
124
178
  * // Create a private NAT Gateway (for VPC-to-VPC communication)
125
179
  * const privateNat = await NatGateway("private-nat", {
126
- * subnet: privateSubnet,
127
- * connectivityType: "private",
128
- * tags: {
129
- * Name: "private-nat-gateway",
130
- * Type: "internal"
131
- * }
180
+ * subnet: privateSubnet,
181
+ * connectivityType: "private",
182
+ * tags: {
183
+ * Name: "private-nat-gateway",
184
+ * Type: "internal"
185
+ * }
132
186
  * });
187
+ * ```
133
188
  *
134
189
  * @example
190
+ * ```typescript
135
191
  * // Create a NAT Gateway with custom timeout configuration
136
192
  * const slowNat = await NatGateway("slow-nat", {
137
193
  * subnet: publicSubnet,
@@ -143,8 +199,32 @@ export interface NatGateway
143
199
  * Name: "slow-nat-gateway"
144
200
  * }
145
201
  * });
202
+ * ```
146
203
  *
147
204
  * @example
205
+ * ```typescript
206
+ * // Multi-account deployment with scope-level and resource-level overrides
207
+ * await alchemy.run("production", {
208
+ * aws: { region: "us-west-2", profile: "main-account" }
209
+ * }, async () => {
210
+ * // This NAT Gateway uses scope credentials (main-account, us-west-2)
211
+ * const mainNat = await NatGateway("main-nat", {
212
+ * subnet: mainPublicSubnet,
213
+ * tags: { Name: "main-account-nat" }
214
+ * });
215
+ *
216
+ * // This NAT Gateway overrides to use different account
217
+ * const crossAccountNat = await NatGateway("cross-account-nat", {
218
+ * subnet: crossPublicSubnet,
219
+ * profile: "secondary-account",
220
+ * region: "us-east-1", // Also override region
221
+ * tags: { Name: "secondary-account-nat" }
222
+ * });
223
+ * });
224
+ * ```
225
+ *
226
+ * @example
227
+ * ```typescript
148
228
  * // Use NAT Gateway in route table for private subnet internet access
149
229
  * const privateRoute = await Route("private-internet", {
150
230
  * routeTable: privateRouteTable,
@@ -154,6 +234,7 @@ export interface NatGateway
154
234
  * Name: "private-to-internet"
155
235
  * }
156
236
  * });
237
+ * ```
157
238
  */
158
239
  export const NatGateway = Resource(
159
240
  "aws::NatGateway",
@@ -162,6 +243,8 @@ export const NatGateway = Resource(
162
243
  _id: string,
163
244
  props: NatGatewayProps,
164
245
  ): Promise<NatGateway> {
246
+ // Create EC2 client with credential resolution handled internally
247
+ const client = await createEC2Client(props);
165
248
  const subnetId =
166
249
  typeof props.subnet === "string" ? props.subnet : props.subnet.subnetId;
167
250
  const timeoutConfig = mergeTimeoutConfig(
@@ -174,7 +257,6 @@ export const NatGateway = Resource(
174
257
  logger.log(`🗑️ Deleting NAT Gateway: ${this.output.natGatewayId}`);
175
258
  // Delete NAT Gateway if it exists
176
259
  await ignore("InvalidNatGatewayID.NotFound", async () => {
177
- const client = await createEC2Client();
178
260
  await callEC2Api(
179
261
  client,
180
262
  "DeleteNatGateway",
@@ -192,6 +274,7 @@ export const NatGateway = Resource(
192
274
  await waitForNatGatewayFullyDeleted(
193
275
  this.output.natGatewayId,
194
276
  timeoutConfig,
277
+ props,
195
278
  );
196
279
 
197
280
  logger.log(
@@ -204,9 +287,8 @@ export const NatGateway = Resource(
204
287
  await ignore(
205
288
  ["InvalidAllocationID.NotFound", "InvalidAddress.NotFound"],
206
289
  async () => {
207
- const eipClient = await createEC2Client();
208
290
  await callEC2Api(
209
- eipClient,
291
+ client,
210
292
  "ReleaseAddress",
211
293
  parseNatGatewayXmlResponse,
212
294
  convertReleaseAddressParamsToAwsFormat({
@@ -216,7 +298,11 @@ export const NatGateway = Resource(
216
298
  },
217
299
  );
218
300
  // Wait for the EIP to be fully released
219
- await waitForEipReleased(this.output.allocationId, timeoutConfig);
301
+ await waitForEipReleased(
302
+ this.output.allocationId,
303
+ timeoutConfig,
304
+ props,
305
+ );
220
306
  logger.log(
221
307
  ` ✅ Elastic IP ${this.output.allocationId} released successfully`,
222
308
  );
@@ -232,7 +318,6 @@ export const NatGateway = Resource(
232
318
 
233
319
  if (this.phase === "update" && this.output?.natGatewayId) {
234
320
  // Get existing NAT Gateway
235
- const client = await createEC2Client();
236
321
  const response = await callEC2Api<DescribeNatGatewaysResponse>(
237
322
  client,
238
323
  "DescribeNatGateways",
@@ -270,7 +355,6 @@ export const NatGateway = Resource(
270
355
  ];
271
356
  }
272
357
 
273
- const client = await createEC2Client();
274
358
  const eipResponse = await callEC2Api<AllocateAddressResponse>(
275
359
  client,
276
360
  "AllocateAddress",
@@ -287,7 +371,6 @@ export const NatGateway = Resource(
287
371
  createdElasticIp = true;
288
372
  } else {
289
373
  // Get public IP of existing allocation
290
- const client = await createEC2Client();
291
374
  const addressResponse = await callEC2Api<DescribeAddressesResponse>(
292
375
  client,
293
376
  "DescribeAddresses",
@@ -319,9 +402,8 @@ export const NatGateway = Resource(
319
402
  ];
320
403
  }
321
404
 
322
- const natClient = await createEC2Client();
323
405
  const response = await callEC2Api<CreateNatGatewayResponse>(
324
- natClient,
406
+ client,
325
407
  "CreateNatGateway",
326
408
  parseNatGatewayXmlResponse,
327
409
  convertCreateNatGatewayParamsToAwsFormat(createParams),
@@ -334,7 +416,11 @@ export const NatGateway = Resource(
334
416
  natGateway = response.NatGateway;
335
417
 
336
418
  // Wait for NAT Gateway to be available
337
- await waitForNatGatewayAvailable(natGateway.NatGatewayId!, timeoutConfig);
419
+ await waitForNatGatewayAvailable(
420
+ natGateway.NatGatewayId!,
421
+ timeoutConfig,
422
+ props,
423
+ );
338
424
  }
339
425
 
340
426
  const result = this({
@@ -359,9 +445,10 @@ export const NatGateway = Resource(
359
445
  async function waitForNatGatewayAvailable(
360
446
  natGatewayId: string,
361
447
  timeoutConfig: TimeoutConfig,
448
+ credentials?: AwsClientProps,
362
449
  ): Promise<void> {
363
450
  const checkFunction = async () => {
364
- const client = await createEC2Client();
451
+ const client = await createEC2Client(credentials);
365
452
  const response = await callEC2Api<DescribeNatGatewaysResponse>(
366
453
  client,
367
454
  "DescribeNatGateways",
@@ -398,10 +485,11 @@ async function waitForNatGatewayAvailable(
398
485
  async function waitForNatGatewayDeleted(
399
486
  natGatewayId: string,
400
487
  timeoutConfig: TimeoutConfig,
488
+ credentials?: AwsClientProps,
401
489
  ): Promise<void> {
402
490
  const checkFunction = async () => {
403
491
  try {
404
- const client = await createEC2Client();
492
+ const client = await createEC2Client(credentials);
405
493
  const response = await callEC2Api<DescribeNatGatewaysResponse>(
406
494
  client,
407
495
  "DescribeNatGateways",
@@ -481,10 +569,11 @@ function parseDescribeNetworkInterfacesResponse(
481
569
  async function waitForEipReleased(
482
570
  allocationId: string,
483
571
  timeoutConfig: TimeoutConfig,
572
+ credentials?: AwsClientProps,
484
573
  ): Promise<void> {
485
574
  const checkFunction = async () => {
486
575
  try {
487
- const eipClient = await createEC2Client();
576
+ const eipClient = await createEC2Client(credentials);
488
577
  const addressResponse = await callEC2Api<DescribeAddressesResponse>(
489
578
  eipClient,
490
579
  "DescribeAddresses",
@@ -525,14 +614,15 @@ async function waitForEipReleased(
525
614
  async function waitForNatGatewayFullyDeleted(
526
615
  natGatewayId: string,
527
616
  timeoutConfig: TimeoutConfig,
617
+ credentials?: AwsClientProps,
528
618
  ): Promise<void> {
529
619
  // First wait for the NAT Gateway itself to be deleted
530
- await waitForNatGatewayDeleted(natGatewayId, timeoutConfig);
620
+ await waitForNatGatewayDeleted(natGatewayId, timeoutConfig, credentials);
531
621
 
532
622
  // Then wait for network interfaces to be cleaned up
533
623
  const checkNetworkInterfaces = async () => {
534
624
  try {
535
- const client = await createEC2Client();
625
+ const client = await createEC2Client(credentials);
536
626
  const response = await callEC2Api<DescribeNetworkInterfacesResponse>(
537
627
  client,
538
628
  "DescribeNetworkInterfaces",
@@ -236,7 +236,7 @@ async function waitForRouteTableAssociationDeleted(
236
236
  * publicSubnets.map((subnet, index) =>
237
237
  * RouteTableAssociation(`public-association-${index}`, {
238
238
  * routeTable: publicRouteTable,
239
- * subnet
239
+ * subnet: subnet
240
240
  * })
241
241
  * )
242
242
  * );
@@ -9,13 +9,14 @@ import {
9
9
  type TimeoutConfig,
10
10
  waitForResourceState,
11
11
  } from "../../util/timeout.ts";
12
+ import type { AwsClientProps } from "../client-props.ts";
12
13
  import { callEC2Api, createEC2Client } from "./utils.ts";
13
14
  import type { Vpc } from "./vpc.ts";
14
15
 
15
16
  /**
16
17
  * Properties for creating or updating a Route Table
17
18
  */
18
- export interface RouteTableProps {
19
+ export interface RouteTableProps extends AwsClientProps {
19
20
  /**
20
21
  * The VPC to create the route table in
21
22
  */
@@ -58,6 +59,9 @@ export interface RouteTable
58
59
  * traffic is directed. Subnet associations are managed separately using the
59
60
  * RouteTableAssociation resource.
60
61
  *
62
+ * Supports AWS credential overrides at the resource level, allowing you to deploy Route Tables
63
+ * to different AWS accounts or regions than the default scope configuration.
64
+ *
61
65
  * @example
62
66
  * // Create a basic route table
63
67
  * const routeTable = await RouteTable("main-route-table", {
@@ -80,6 +84,45 @@ export interface RouteTable
80
84
  * });
81
85
  *
82
86
  * @example
87
+ * // Create Route Table with AWS credential overrides
88
+ * const crossAccountRouteTable = await RouteTable("cross-account-rt", {
89
+ * vpc: mainVpc,
90
+ * // Override AWS credentials for this specific resource
91
+ * region: "us-east-1",
92
+ * profile: "production-account",
93
+ * tags: {
94
+ * Name: "cross-account-route-table",
95
+ * Environment: "production"
96
+ * }
97
+ * });
98
+ *
99
+ * @example
100
+ * // Create Route Table in different region with role assumption
101
+ * const multiRegionRouteTable = await RouteTable("multi-region-rt", {
102
+ * vpc: euVpc,
103
+ * region: "eu-west-1",
104
+ * roleArn: "arn:aws:iam::123456789012:role/CrossRegionRole",
105
+ * roleSessionName: "route-table-deployment",
106
+ * tags: {
107
+ * Name: "eu-route-table",
108
+ * Region: "europe"
109
+ * }
110
+ * });
111
+ *
112
+ * @example
113
+ * // Create Route Table with explicit credentials
114
+ * const explicitCredsRouteTable = await RouteTable("explicit-creds-rt", {
115
+ * vpc: testVpc,
116
+ * accessKeyId: alchemy.secret("AKIAIOSFODNN7EXAMPLE"),
117
+ * secretAccessKey: alchemy.secret("wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"),
118
+ * region: "us-west-2",
119
+ * tags: {
120
+ * Name: "explicit-credentials-rt",
121
+ * Purpose: "testing"
122
+ * }
123
+ * });
124
+ *
125
+ * @example
83
126
  * // Create a private route table for internal traffic
84
127
  * const privateRouteTable = await RouteTable("private-routes", {
85
128
  * vpc: myVpc,
@@ -102,6 +145,26 @@ export interface RouteTable
102
145
  * Name: "custom-timeout-route-table"
103
146
  * }
104
147
  * });
148
+ *
149
+ * @example
150
+ * // Multi-account deployment with scope-level and resource-level overrides
151
+ * await alchemy.run("production", {
152
+ * aws: { region: "us-west-2", profile: "main-account" }
153
+ * }, async () => {
154
+ * // This Route Table uses scope credentials (main-account, us-west-2)
155
+ * const mainRouteTable = await RouteTable("main-rt", {
156
+ * vpc: mainVpc,
157
+ * tags: { Name: "main-account-rt" }
158
+ * });
159
+ *
160
+ * // This Route Table overrides to use different account
161
+ * const crossAccountRouteTable = await RouteTable("cross-account-rt", {
162
+ * vpc: crossVpc,
163
+ * profile: "secondary-account",
164
+ * region: "us-east-1", // Also override region
165
+ * tags: { Name: "secondary-account-rt" }
166
+ * });
167
+ * });
105
168
  */
106
169
  export const RouteTable = Resource(
107
170
  "aws::RouteTable",
@@ -110,7 +173,8 @@ export const RouteTable = Resource(
110
173
  _id: string,
111
174
  props: RouteTableProps,
112
175
  ): Promise<RouteTable> {
113
- const client = await createEC2Client();
176
+ // Create EC2 client with credential resolution handled internally
177
+ const client = await createEC2Client(props);
114
178
  const timeoutConfig = mergeTimeoutConfig(
115
179
  ROUTE_TABLE_TIMEOUT,
116
180
  props.timeout,