alchemy-effect 0.2.0 → 0.3.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.
- package/bin/alchemy-effect.js +55038 -8
- package/bin/alchemy-effect.js.map +1 -1
- package/bin/alchemy-effect.ts +266 -10
- package/lib/$.d.ts +5 -0
- package/lib/$.d.ts.map +1 -0
- package/lib/$.js +9 -0
- package/lib/$.js.map +1 -0
- package/lib/app.d.ts +4 -17
- package/lib/app.d.ts.map +1 -1
- package/lib/app.js +0 -20
- package/lib/app.js.map +1 -1
- package/lib/apply.d.ts +14 -74
- package/lib/apply.d.ts.map +1 -1
- package/lib/apply.js +62 -57
- package/lib/apply.js.map +1 -1
- package/lib/assert-never.d.ts +12 -0
- package/lib/assert-never.d.ts.map +1 -0
- package/lib/assert-never.js +11 -0
- package/lib/assert-never.js.map +1 -0
- package/lib/aws/account.d.ts +10 -1
- package/lib/aws/account.d.ts.map +1 -1
- package/lib/aws/account.js +18 -3
- package/lib/aws/account.js.map +1 -1
- package/lib/aws/client.d.ts.map +1 -1
- package/lib/aws/client.js +0 -1
- package/lib/aws/client.js.map +1 -1
- package/lib/aws/config.d.ts +15 -0
- package/lib/aws/config.d.ts.map +1 -0
- package/lib/aws/config.js +1 -0
- package/lib/aws/config.js.map +1 -0
- package/lib/aws/credentials.d.ts +10 -0
- package/lib/aws/credentials.d.ts.map +1 -1
- package/lib/aws/credentials.js +73 -47
- package/lib/aws/credentials.js.map +1 -1
- package/lib/aws/dynamodb/client.d.ts +1 -1
- package/lib/aws/dynamodb/client.d.ts.map +1 -1
- package/lib/aws/dynamodb/index.d.ts +2 -1
- package/lib/aws/dynamodb/index.d.ts.map +1 -1
- package/lib/aws/dynamodb/index.js +1 -2
- package/lib/aws/dynamodb/index.js.map +1 -1
- package/lib/aws/dynamodb/secondary-index.d.ts +5 -4
- package/lib/aws/dynamodb/secondary-index.d.ts.map +1 -1
- package/lib/aws/dynamodb/table.d.ts +23 -20
- package/lib/aws/dynamodb/table.d.ts.map +1 -1
- package/lib/aws/dynamodb/table.get-item.d.ts +8 -6
- package/lib/aws/dynamodb/table.get-item.d.ts.map +1 -1
- package/lib/aws/dynamodb/table.get-item.js +4 -2
- package/lib/aws/dynamodb/table.get-item.js.map +1 -1
- package/lib/aws/dynamodb/table.js.map +1 -1
- package/lib/aws/dynamodb/table.provider.d.ts +3 -4
- package/lib/aws/dynamodb/table.provider.d.ts.map +1 -1
- package/lib/aws/dynamodb/table.provider.js +17 -29
- package/lib/aws/dynamodb/table.provider.js.map +1 -1
- package/lib/aws/ec2/client.d.ts +1 -1
- package/lib/aws/ec2/client.d.ts.map +1 -1
- package/lib/aws/ec2/index.d.ts +3 -0
- package/lib/aws/ec2/index.d.ts.map +1 -1
- package/lib/aws/ec2/index.js +3 -0
- package/lib/aws/ec2/index.js.map +1 -1
- package/lib/aws/ec2/subnet.d.ts +175 -0
- package/lib/aws/ec2/subnet.d.ts.map +1 -0
- package/lib/aws/ec2/subnet.js +4 -0
- package/lib/aws/ec2/subnet.js.map +1 -0
- package/lib/aws/ec2/subnet.provider.d.ts +4 -0
- package/lib/aws/ec2/subnet.provider.d.ts.map +1 -0
- package/lib/aws/ec2/subnet.provider.js +250 -0
- package/lib/aws/ec2/subnet.provider.js.map +1 -0
- package/lib/aws/ec2/vpc.d.ts +12 -8
- package/lib/aws/ec2/vpc.d.ts.map +1 -1
- package/lib/aws/ec2/vpc.js +1 -0
- package/lib/aws/ec2/vpc.js.map +1 -1
- package/lib/aws/ec2/vpc.provider.d.ts +3 -4
- package/lib/aws/ec2/vpc.provider.d.ts.map +1 -1
- package/lib/aws/ec2/vpc.provider.js +11 -26
- package/lib/aws/ec2/vpc.provider.js.map +1 -1
- package/lib/aws/index.d.ts +16 -19
- package/lib/aws/index.d.ts.map +1 -1
- package/lib/aws/index.js +7 -10
- package/lib/aws/index.js.map +1 -1
- package/lib/aws/lambda/consume.d.ts +10 -11
- package/lib/aws/lambda/consume.d.ts.map +1 -1
- package/lib/aws/lambda/consume.js +3 -3
- package/lib/aws/lambda/consume.js.map +1 -1
- package/lib/aws/lambda/function.d.ts +7 -7
- package/lib/aws/lambda/function.d.ts.map +1 -1
- package/lib/aws/lambda/function.handler.d.ts +1 -1
- package/lib/aws/lambda/function.handler.d.ts.map +1 -1
- package/lib/aws/lambda/function.handler.js.map +1 -1
- package/lib/aws/lambda/function.invoke.d.ts +6 -4
- package/lib/aws/lambda/function.invoke.d.ts.map +1 -1
- package/lib/aws/lambda/function.invoke.js +3 -1
- package/lib/aws/lambda/function.invoke.js.map +1 -1
- package/lib/aws/lambda/function.js +1 -1
- package/lib/aws/lambda/function.js.map +1 -1
- package/lib/aws/lambda/function.provider.d.ts +5 -4
- package/lib/aws/lambda/function.provider.d.ts.map +1 -1
- package/lib/aws/lambda/function.provider.js +16 -14
- package/lib/aws/lambda/function.provider.js.map +1 -1
- package/lib/aws/lambda/index.d.ts +1 -0
- package/lib/aws/lambda/index.d.ts.map +1 -1
- package/lib/aws/lambda/index.js +1 -0
- package/lib/aws/lambda/index.js.map +1 -1
- package/lib/aws/lambda/serve.d.ts +2 -4
- package/lib/aws/lambda/serve.d.ts.map +1 -1
- package/lib/aws/profile.d.ts +2 -2
- package/lib/aws/profile.d.ts.map +1 -1
- package/lib/aws/profile.js +1 -1
- package/lib/aws/profile.js.map +1 -1
- package/lib/aws/region.d.ts +14 -2
- package/lib/aws/region.d.ts.map +1 -1
- package/lib/aws/region.js +26 -1
- package/lib/aws/region.js.map +1 -1
- package/lib/aws/sqs/client.d.ts +1 -1
- package/lib/aws/sqs/client.d.ts.map +1 -1
- package/lib/aws/sqs/index.d.ts +1 -0
- package/lib/aws/sqs/index.d.ts.map +1 -1
- package/lib/aws/sqs/index.js +1 -0
- package/lib/aws/sqs/index.js.map +1 -1
- package/lib/aws/sqs/queue.consume.d.ts +1 -1
- package/lib/aws/sqs/queue.consume.d.ts.map +1 -1
- package/lib/aws/sqs/queue.consume.js +0 -1
- package/lib/aws/sqs/queue.consume.js.map +1 -1
- package/lib/aws/sqs/queue.d.ts +6 -4
- package/lib/aws/sqs/queue.d.ts.map +1 -1
- package/lib/aws/sqs/queue.event-source.d.ts +8 -6
- package/lib/aws/sqs/queue.event-source.d.ts.map +1 -1
- package/lib/aws/sqs/queue.event-source.js +26 -44
- package/lib/aws/sqs/queue.event-source.js.map +1 -1
- package/lib/aws/sqs/queue.js +1 -1
- package/lib/aws/sqs/queue.js.map +1 -1
- package/lib/aws/sqs/queue.provider.d.ts +4 -4
- package/lib/aws/sqs/queue.provider.d.ts.map +1 -1
- package/lib/aws/sqs/queue.provider.js +3 -3
- package/lib/aws/sqs/queue.provider.js.map +1 -1
- package/lib/aws/sqs/queue.send-message.d.ts +7 -5
- package/lib/aws/sqs/queue.send-message.d.ts.map +1 -1
- package/lib/aws/sqs/queue.send-message.js +4 -2
- package/lib/aws/sqs/queue.send-message.js.map +1 -1
- package/lib/binding.d.ts +12 -12
- package/lib/binding.d.ts.map +1 -1
- package/lib/binding.js.map +1 -1
- package/lib/cli/components/ApprovePlan.d.ts +2 -2
- package/lib/cli/components/ApprovePlan.d.ts.map +1 -1
- package/lib/cli/components/ApprovePlan.js.map +1 -1
- package/lib/cli/components/Plan.d.ts +2 -2
- package/lib/cli/components/Plan.d.ts.map +1 -1
- package/lib/cli/components/Plan.js.map +1 -1
- package/lib/cli/components/PlanProgress.d.ts +8 -4
- package/lib/cli/components/PlanProgress.d.ts.map +1 -1
- package/lib/cli/components/PlanProgress.js +11 -1
- package/lib/cli/components/PlanProgress.js.map +1 -1
- package/lib/cli/index.d.ts +265 -224
- package/lib/cli/index.d.ts.map +1 -1
- package/lib/cli/index.js +57 -65
- package/lib/cli/index.js.map +1 -1
- package/lib/cli/ink-service.d.ts +4 -0
- package/lib/cli/ink-service.d.ts.map +1 -0
- package/lib/cli/ink-service.js +43 -0
- package/lib/cli/ink-service.js.map +1 -0
- package/lib/cli/service.d.ts +21 -0
- package/lib/cli/service.d.ts.map +1 -0
- package/lib/cli/service.js +5 -0
- package/lib/cli/service.js.map +1 -0
- package/lib/cloudflare/account.d.ts +10 -0
- package/lib/cloudflare/account.d.ts.map +1 -0
- package/lib/cloudflare/account.js +24 -0
- package/lib/cloudflare/account.js.map +1 -0
- package/lib/cloudflare/api.d.ts +7 -7
- package/lib/cloudflare/api.d.ts.map +1 -1
- package/lib/cloudflare/api.js +18 -17
- package/lib/cloudflare/api.js.map +1 -1
- package/lib/cloudflare/config.d.ts +9 -0
- package/lib/cloudflare/config.d.ts.map +1 -0
- package/lib/cloudflare/config.js +1 -0
- package/lib/cloudflare/config.js.map +1 -0
- package/lib/cloudflare/index.d.ts +3 -1
- package/lib/cloudflare/index.d.ts.map +1 -1
- package/lib/cloudflare/index.js +3 -0
- package/lib/cloudflare/index.js.map +1 -1
- package/lib/cloudflare/kv/namespace.binding.d.ts +5 -3
- package/lib/cloudflare/kv/namespace.binding.d.ts.map +1 -1
- package/lib/cloudflare/kv/namespace.binding.js +1 -1
- package/lib/cloudflare/kv/namespace.binding.js.map +1 -1
- package/lib/cloudflare/kv/namespace.d.ts +3 -2
- package/lib/cloudflare/kv/namespace.d.ts.map +1 -1
- package/lib/cloudflare/kv/namespace.js.map +1 -1
- package/lib/cloudflare/kv/namespace.provider.d.ts +3 -2
- package/lib/cloudflare/kv/namespace.provider.d.ts.map +1 -1
- package/lib/cloudflare/kv/namespace.provider.js +8 -7
- package/lib/cloudflare/kv/namespace.provider.js.map +1 -1
- package/lib/cloudflare/live.d.ts +5 -5
- package/lib/cloudflare/live.d.ts.map +1 -1
- package/lib/cloudflare/live.js +5 -8
- package/lib/cloudflare/live.js.map +1 -1
- package/lib/cloudflare/r2/bucket.binding.d.ts +5 -3
- package/lib/cloudflare/r2/bucket.binding.d.ts.map +1 -1
- package/lib/cloudflare/r2/bucket.binding.js +1 -1
- package/lib/cloudflare/r2/bucket.binding.js.map +1 -1
- package/lib/cloudflare/r2/bucket.d.ts +3 -2
- package/lib/cloudflare/r2/bucket.d.ts.map +1 -1
- package/lib/cloudflare/r2/bucket.js.map +1 -1
- package/lib/cloudflare/r2/bucket.provider.d.ts +3 -2
- package/lib/cloudflare/r2/bucket.provider.d.ts.map +1 -1
- package/lib/cloudflare/r2/bucket.provider.js +8 -7
- package/lib/cloudflare/r2/bucket.provider.js.map +1 -1
- package/lib/cloudflare/worker/assets.fetch.d.ts +3 -2
- package/lib/cloudflare/worker/assets.fetch.d.ts.map +1 -1
- package/lib/cloudflare/worker/assets.fetch.js +2 -1
- package/lib/cloudflare/worker/assets.fetch.js.map +1 -1
- package/lib/cloudflare/worker/assets.provider.d.ts +1 -1
- package/lib/cloudflare/worker/assets.provider.d.ts.map +1 -1
- package/lib/cloudflare/worker/index.d.ts +0 -1
- package/lib/cloudflare/worker/index.d.ts.map +1 -1
- package/lib/cloudflare/worker/worker.d.ts +5 -6
- package/lib/cloudflare/worker/worker.d.ts.map +1 -1
- package/lib/cloudflare/worker/worker.handler.d.ts +1 -1
- package/lib/cloudflare/worker/worker.handler.d.ts.map +1 -1
- package/lib/cloudflare/worker/worker.handler.js.map +1 -1
- package/lib/cloudflare/worker/worker.js.map +1 -1
- package/lib/cloudflare/worker/worker.provider.d.ts +3 -2
- package/lib/cloudflare/worker/worker.provider.d.ts.map +1 -1
- package/lib/cloudflare/worker/worker.provider.js +7 -6
- package/lib/cloudflare/worker/worker.provider.js.map +1 -1
- package/lib/cloudflare/worker/worker.serve.d.ts +7 -7
- package/lib/cloudflare/worker/worker.serve.d.ts.map +1 -1
- package/lib/cloudflare/worker/worker.serve.js.map +1 -1
- package/lib/data.d.ts +3 -0
- package/lib/data.d.ts.map +1 -0
- package/lib/data.js +8 -0
- package/lib/data.js.map +1 -0
- package/lib/destroy.d.ts +1 -1
- package/lib/destroy.d.ts.map +1 -1
- package/lib/destroy.js +1 -4
- package/lib/destroy.js.map +1 -1
- package/lib/diff.d.ts +16 -0
- package/lib/diff.d.ts.map +1 -0
- package/lib/diff.js +9 -0
- package/lib/diff.js.map +1 -0
- package/lib/env.d.ts +5 -0
- package/lib/env.d.ts.map +1 -1
- package/lib/env.js +15 -29
- package/lib/env.js.map +1 -1
- package/lib/exports.d.ts +9 -0
- package/lib/exports.d.ts.map +1 -0
- package/lib/exports.js +13 -0
- package/lib/exports.js.map +1 -0
- package/lib/index.d.ts +10 -2
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +10 -5
- package/lib/index.js.map +1 -1
- package/lib/input.d.ts +32 -0
- package/lib/input.d.ts.map +1 -0
- package/lib/input.js +1 -0
- package/lib/input.js.map +1 -0
- package/lib/output.d.ts +143 -0
- package/lib/output.d.ts.map +1 -0
- package/lib/output.js +269 -0
- package/lib/output.js.map +1 -0
- package/lib/plan.d.ts +47 -28
- package/lib/plan.d.ts.map +1 -1
- package/lib/plan.js +257 -151
- package/lib/plan.js.map +1 -1
- package/lib/policy.d.ts +3 -4
- package/lib/policy.d.ts.map +1 -1
- package/lib/policy.js +0 -1
- package/lib/policy.js.map +1 -1
- package/lib/provider.d.ts +14 -16
- package/lib/provider.d.ts.map +1 -1
- package/lib/ref.d.ts +14 -0
- package/lib/ref.d.ts.map +1 -0
- package/lib/ref.js +21 -0
- package/lib/ref.js.map +1 -0
- package/lib/resource.d.ts +11 -6
- package/lib/resource.d.ts.map +1 -1
- package/lib/resource.js.map +1 -1
- package/lib/runtime.d.ts +7 -6
- package/lib/runtime.d.ts.map +1 -1
- package/lib/runtime.js.map +1 -1
- package/lib/service.d.ts +9 -6
- package/lib/service.d.ts.map +1 -1
- package/lib/service.js.map +1 -1
- package/lib/stack.d.ts +60 -0
- package/lib/stack.d.ts.map +1 -0
- package/lib/stack.js +11 -0
- package/lib/stack.js.map +1 -0
- package/lib/stage.d.ts +39 -0
- package/lib/stage.d.ts.map +1 -0
- package/lib/stage.js +32 -0
- package/lib/stage.js.map +1 -0
- package/lib/state.d.ts +51 -10
- package/lib/state.d.ts.map +1 -1
- package/lib/state.js +30 -29
- package/lib/state.js.map +1 -1
- package/lib/test.d.ts +25 -4
- package/lib/test.d.ts.map +1 -1
- package/lib/test.js +54 -14
- package/lib/test.js.map +1 -1
- package/lib/tsconfig.test.tsbuildinfo +1 -1
- package/lib/type.d.ts +3 -0
- package/lib/type.d.ts.map +1 -1
- package/lib/unknown.d.ts +4 -0
- package/lib/unknown.d.ts.map +1 -0
- package/lib/unknown.js +4 -0
- package/lib/unknown.js.map +1 -0
- package/lib/user.d.ts +3 -0
- package/lib/user.d.ts.map +1 -0
- package/lib/user.js +3 -0
- package/lib/user.js.map +1 -0
- package/lib/util.d.ts +6 -0
- package/lib/util.d.ts.map +1 -0
- package/lib/util.js +9 -0
- package/lib/util.js.map +1 -0
- package/package.json +18 -12
- package/src/$.ts +17 -0
- package/src/app.ts +3 -32
- package/src/apply.ts +429 -441
- package/src/assert-never.ts +18 -0
- package/src/aws/account.ts +23 -3
- package/src/aws/client.ts +0 -1
- package/src/aws/config.ts +16 -0
- package/src/aws/credentials.ts +212 -177
- package/src/aws/dynamodb/index.ts +3 -3
- package/src/aws/dynamodb/table.get-item.ts +5 -9
- package/src/aws/dynamodb/table.provider.ts +35 -39
- package/src/aws/dynamodb/table.ts +29 -84
- package/src/aws/ec2/index.ts +4 -0
- package/src/aws/ec2/subnet.provider.ts +358 -0
- package/src/aws/ec2/subnet.ts +213 -0
- package/src/aws/ec2/vpc.provider.ts +20 -36
- package/src/aws/ec2/vpc.ts +19 -8
- package/src/aws/index.ts +46 -40
- package/src/aws/lambda/consume.ts +8 -7
- package/src/aws/lambda/function.handler.ts +1 -1
- package/src/aws/lambda/function.invoke.ts +6 -2
- package/src/aws/lambda/function.provider.ts +28 -21
- package/src/aws/lambda/function.ts +7 -4
- package/src/aws/lambda/index.ts +2 -0
- package/src/aws/profile.ts +1 -4
- package/src/aws/region.ts +42 -3
- package/src/aws/sqs/index.ts +2 -0
- package/src/aws/sqs/queue.consume.ts +1 -1
- package/src/aws/sqs/queue.event-source.ts +29 -55
- package/src/aws/sqs/queue.provider.ts +11 -4
- package/src/aws/sqs/queue.send-message.ts +5 -8
- package/src/aws/sqs/queue.ts +9 -4
- package/src/binding.ts +19 -19
- package/src/cli/components/ApprovePlan.tsx +2 -2
- package/src/cli/components/Plan.tsx +3 -2
- package/src/cli/components/PlanProgress.tsx +32 -14
- package/src/cli/index.ts +2 -6
- package/src/cli/ink-service.tsx +61 -0
- package/src/cli/service.ts +23 -0
- package/src/cloudflare/account.ts +37 -0
- package/src/cloudflare/api.ts +33 -29
- package/src/cloudflare/config.ts +7 -0
- package/src/cloudflare/index.ts +3 -1
- package/src/cloudflare/kv/namespace.binding.ts +3 -1
- package/src/cloudflare/kv/namespace.provider.ts +9 -8
- package/src/cloudflare/kv/namespace.ts +3 -2
- package/src/cloudflare/live.ts +11 -17
- package/src/cloudflare/r2/bucket.binding.ts +3 -1
- package/src/cloudflare/r2/bucket.provider.ts +9 -8
- package/src/cloudflare/r2/bucket.ts +8 -2
- package/src/cloudflare/worker/assets.fetch.ts +3 -1
- package/src/cloudflare/worker/assets.provider.ts +1 -1
- package/src/cloudflare/worker/index.ts +0 -2
- package/src/cloudflare/worker/worker.handler.ts +1 -1
- package/src/cloudflare/worker/worker.provider.ts +16 -13
- package/src/cloudflare/worker/worker.serve.ts +5 -2
- package/src/cloudflare/worker/worker.ts +4 -3
- package/src/data.ts +18 -0
- package/src/destroy.ts +1 -5
- package/src/diff.ts +30 -0
- package/src/env.ts +20 -32
- package/src/exports.ts +21 -0
- package/src/index.ts +10 -5
- package/src/input.ts +81 -0
- package/src/output.ts +518 -0
- package/src/plan.ts +380 -192
- package/src/policy.ts +3 -5
- package/src/provider.ts +25 -23
- package/src/ref.ts +48 -0
- package/src/resource.ts +20 -6
- package/src/runtime.ts +15 -8
- package/src/service.ts +11 -7
- package/src/stack.ts +116 -0
- package/src/stage.ts +85 -0
- package/src/state.ts +138 -60
- package/src/test.ts +117 -16
- package/src/type.ts +4 -0
- package/src/unknown.ts +6 -0
- package/src/user.ts +4 -0
- package/src/util.ts +21 -0
- package/lib/approve.d.ts +0 -15
- package/lib/approve.d.ts.map +0 -1
- package/lib/approve.js +0 -7
- package/lib/approve.js.map +0 -1
- package/lib/cli/approve.d.ts +0 -4
- package/lib/cli/approve.d.ts.map +0 -1
- package/lib/cli/approve.js +0 -18
- package/lib/cli/approve.js.map +0 -1
- package/lib/cli/clack.d.ts +0 -14
- package/lib/cli/clack.d.ts.map +0 -1
- package/lib/cli/clack.js +0 -12
- package/lib/cli/clack.js.map +0 -1
- package/lib/cli/main.d.ts +0 -2
- package/lib/cli/main.d.ts.map +0 -1
- package/lib/cli/main.js +0 -1
- package/lib/cli/main.js.map +0 -1
- package/lib/cli/plan.d.ts +0 -13
- package/lib/cli/plan.d.ts.map +0 -1
- package/lib/cli/plan.js +0 -1
- package/lib/cli/plan.js.map +0 -1
- package/lib/cli/progress.d.ts +0 -7
- package/lib/cli/progress.d.ts.map +0 -1
- package/lib/cli/progress.js +0 -30
- package/lib/cli/progress.js.map +0 -1
- package/lib/cli/spinner.d.ts +0 -2
- package/lib/cli/spinner.d.ts.map +0 -1
- package/lib/cli/spinner.js +0 -13
- package/lib/cli/spinner.js.map +0 -1
- package/src/approve.ts +0 -13
- package/src/cli/approve.tsx +0 -30
- package/src/cli/clack.ts +0 -22
- package/src/cli/main.ts +0 -0
- package/src/cli/plan.ts +0 -16
- package/src/cli/progress.tsx +0 -46
- package/src/cli/spinner.ts +0 -14
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect";
|
|
2
|
+
import * as Schedule from "effect/Schedule";
|
|
3
|
+
|
|
4
|
+
import type { EC2 } from "itty-aws/ec2";
|
|
5
|
+
|
|
6
|
+
import type { ScopedPlanStatusSession } from "../../cli/service.ts";
|
|
7
|
+
import { somePropsAreDifferent } from "../../diff.ts";
|
|
8
|
+
import type { ProviderService } from "../../provider.ts";
|
|
9
|
+
import { createTagger, createTagsList } from "../../tags.ts";
|
|
10
|
+
import { EC2Client } from "./client.ts";
|
|
11
|
+
import {
|
|
12
|
+
Subnet,
|
|
13
|
+
type SubnetAttrs,
|
|
14
|
+
type SubnetProps,
|
|
15
|
+
type SubnetId,
|
|
16
|
+
} from "./subnet.ts";
|
|
17
|
+
|
|
18
|
+
export const subnetProvider = () =>
|
|
19
|
+
Subnet.provider.effect(
|
|
20
|
+
Effect.gen(function* () {
|
|
21
|
+
const ec2 = yield* EC2Client;
|
|
22
|
+
const tagged = yield* createTagger();
|
|
23
|
+
|
|
24
|
+
return {
|
|
25
|
+
diff: Effect.fn(function* ({ news, olds }) {
|
|
26
|
+
if (
|
|
27
|
+
somePropsAreDifferent(olds, news, [
|
|
28
|
+
"vpcId",
|
|
29
|
+
"cidrBlock",
|
|
30
|
+
"availabilityZone",
|
|
31
|
+
"availabilityZoneId",
|
|
32
|
+
"ipv6CidrBlock",
|
|
33
|
+
"ipv4IpamPoolId",
|
|
34
|
+
"ipv6IpamPoolId",
|
|
35
|
+
])
|
|
36
|
+
) {
|
|
37
|
+
return { action: "replace" };
|
|
38
|
+
}
|
|
39
|
+
}),
|
|
40
|
+
|
|
41
|
+
create: Effect.fn(function* ({ id, news, session }) {
|
|
42
|
+
// 1. Get VPC ID from the VPC resource
|
|
43
|
+
// TODO(sam): i need to make it possible to pass Resources as input Props to Resources
|
|
44
|
+
const vpcId = news.vpcId;
|
|
45
|
+
|
|
46
|
+
// 2. Prepare tags
|
|
47
|
+
const alchemyTags = tagged(id);
|
|
48
|
+
const userTags = news.tags ?? {};
|
|
49
|
+
const allTags = { ...alchemyTags, ...userTags };
|
|
50
|
+
|
|
51
|
+
// 3. Call CreateSubnet
|
|
52
|
+
const createResult = yield* ec2
|
|
53
|
+
.createSubnet({
|
|
54
|
+
VpcId: vpcId,
|
|
55
|
+
CidrBlock: news.cidrBlock,
|
|
56
|
+
Ipv6CidrBlock: news.ipv6CidrBlock,
|
|
57
|
+
AvailabilityZone: news.availabilityZone,
|
|
58
|
+
AvailabilityZoneId: news.availabilityZoneId,
|
|
59
|
+
Ipv4IpamPoolId: news.ipv4IpamPoolId,
|
|
60
|
+
Ipv4NetmaskLength: news.ipv4NetmaskLength,
|
|
61
|
+
Ipv6IpamPoolId: news.ipv6IpamPoolId,
|
|
62
|
+
Ipv6NetmaskLength: news.ipv6NetmaskLength,
|
|
63
|
+
Ipv6Native: false, // Explicitly set to false for now
|
|
64
|
+
TagSpecifications: [
|
|
65
|
+
{
|
|
66
|
+
ResourceType: "subnet",
|
|
67
|
+
Tags: createTagsList(allTags),
|
|
68
|
+
},
|
|
69
|
+
],
|
|
70
|
+
DryRun: false,
|
|
71
|
+
})
|
|
72
|
+
.pipe(
|
|
73
|
+
Effect.retry({
|
|
74
|
+
// @ts-expect-error - this is unknown to itty-aws
|
|
75
|
+
while: (e) => e._tag === "InvalidVpcID.NotFound",
|
|
76
|
+
schedule: Schedule.exponential(100),
|
|
77
|
+
}),
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
const subnetId = createResult.Subnet!.SubnetId! as SubnetId;
|
|
81
|
+
yield* session.note(`Subnet created: ${subnetId}`);
|
|
82
|
+
|
|
83
|
+
// 4. Modify subnet attributes if specified
|
|
84
|
+
if (news.mapPublicIpOnLaunch !== undefined) {
|
|
85
|
+
yield* ec2.modifySubnetAttribute({
|
|
86
|
+
SubnetId: subnetId,
|
|
87
|
+
MapPublicIpOnLaunch: { Value: news.mapPublicIpOnLaunch },
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (news.assignIpv6AddressOnCreation !== undefined) {
|
|
92
|
+
yield* ec2.modifySubnetAttribute({
|
|
93
|
+
SubnetId: subnetId,
|
|
94
|
+
AssignIpv6AddressOnCreation: {
|
|
95
|
+
Value: news.assignIpv6AddressOnCreation,
|
|
96
|
+
},
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (news.enableDns64 !== undefined) {
|
|
101
|
+
yield* ec2.modifySubnetAttribute({
|
|
102
|
+
SubnetId: subnetId,
|
|
103
|
+
EnableDns64: { Value: news.enableDns64 },
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (
|
|
108
|
+
news.enableResourceNameDnsARecordOnLaunch !== undefined ||
|
|
109
|
+
news.enableResourceNameDnsAAAARecordOnLaunch !== undefined ||
|
|
110
|
+
news.hostnameType !== undefined
|
|
111
|
+
) {
|
|
112
|
+
yield* ec2.modifySubnetAttribute({
|
|
113
|
+
SubnetId: subnetId,
|
|
114
|
+
PrivateDnsHostnameTypeOnLaunch: news.hostnameType,
|
|
115
|
+
EnableResourceNameDnsARecordOnLaunch:
|
|
116
|
+
news.enableResourceNameDnsARecordOnLaunch !== undefined
|
|
117
|
+
? { Value: news.enableResourceNameDnsARecordOnLaunch }
|
|
118
|
+
: undefined,
|
|
119
|
+
EnableResourceNameDnsAAAARecordOnLaunch:
|
|
120
|
+
news.enableResourceNameDnsAAAARecordOnLaunch !== undefined
|
|
121
|
+
? { Value: news.enableResourceNameDnsAAAARecordOnLaunch }
|
|
122
|
+
: undefined,
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// 5. Wait for subnet to be available
|
|
127
|
+
const subnet = yield* waitForSubnetAvailable(ec2, subnetId, session);
|
|
128
|
+
|
|
129
|
+
// 6. Return attributes
|
|
130
|
+
return {
|
|
131
|
+
subnetId,
|
|
132
|
+
subnetArn:
|
|
133
|
+
subnet.SubnetArn! as SubnetAttrs<SubnetProps>["subnetArn"],
|
|
134
|
+
cidrBlock: subnet.CidrBlock!,
|
|
135
|
+
vpcId: news.vpcId,
|
|
136
|
+
availabilityZone: subnet.AvailabilityZone!,
|
|
137
|
+
availabilityZoneId: subnet.AvailabilityZoneId,
|
|
138
|
+
state: subnet.State!,
|
|
139
|
+
availableIpAddressCount: subnet.AvailableIpAddressCount ?? 0,
|
|
140
|
+
mapPublicIpOnLaunch: subnet.MapPublicIpOnLaunch ?? false,
|
|
141
|
+
assignIpv6AddressOnCreation:
|
|
142
|
+
subnet.AssignIpv6AddressOnCreation ?? false,
|
|
143
|
+
defaultForAz: subnet.DefaultForAz ?? false,
|
|
144
|
+
ownerId: subnet.OwnerId,
|
|
145
|
+
ipv6CidrBlockAssociationSet:
|
|
146
|
+
subnet.Ipv6CidrBlockAssociationSet?.map((assoc) => ({
|
|
147
|
+
associationId: assoc.AssociationId!,
|
|
148
|
+
ipv6CidrBlock: assoc.Ipv6CidrBlock!,
|
|
149
|
+
ipv6CidrBlockState: {
|
|
150
|
+
state: assoc.Ipv6CidrBlockState!.State!,
|
|
151
|
+
statusMessage: assoc.Ipv6CidrBlockState!.StatusMessage,
|
|
152
|
+
},
|
|
153
|
+
})),
|
|
154
|
+
enableDns64: subnet.EnableDns64,
|
|
155
|
+
ipv6Native: subnet.Ipv6Native,
|
|
156
|
+
privateDnsNameOptionsOnLaunch: subnet.PrivateDnsNameOptionsOnLaunch
|
|
157
|
+
? {
|
|
158
|
+
hostnameType:
|
|
159
|
+
subnet.PrivateDnsNameOptionsOnLaunch.HostnameType,
|
|
160
|
+
enableResourceNameDnsARecord:
|
|
161
|
+
subnet.PrivateDnsNameOptionsOnLaunch
|
|
162
|
+
.EnableResourceNameDnsARecord,
|
|
163
|
+
enableResourceNameDnsAAAARecord:
|
|
164
|
+
subnet.PrivateDnsNameOptionsOnLaunch
|
|
165
|
+
.EnableResourceNameDnsAAAARecord,
|
|
166
|
+
}
|
|
167
|
+
: undefined,
|
|
168
|
+
} satisfies SubnetAttrs<SubnetProps>;
|
|
169
|
+
}),
|
|
170
|
+
|
|
171
|
+
update: Effect.fn(function* ({ news, olds, output, session }) {
|
|
172
|
+
const subnetId = output.subnetId;
|
|
173
|
+
|
|
174
|
+
// Update MapPublicIpOnLaunch if changed
|
|
175
|
+
if (news.mapPublicIpOnLaunch !== olds.mapPublicIpOnLaunch) {
|
|
176
|
+
yield* ec2.modifySubnetAttribute({
|
|
177
|
+
SubnetId: subnetId,
|
|
178
|
+
MapPublicIpOnLaunch: { Value: news.mapPublicIpOnLaunch ?? false },
|
|
179
|
+
});
|
|
180
|
+
yield* session.note("Updated map public IP on launch");
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Update AssignIpv6AddressOnCreation if changed
|
|
184
|
+
if (
|
|
185
|
+
news.assignIpv6AddressOnCreation !==
|
|
186
|
+
olds.assignIpv6AddressOnCreation
|
|
187
|
+
) {
|
|
188
|
+
yield* ec2.modifySubnetAttribute({
|
|
189
|
+
SubnetId: subnetId,
|
|
190
|
+
AssignIpv6AddressOnCreation: {
|
|
191
|
+
Value: news.assignIpv6AddressOnCreation ?? false,
|
|
192
|
+
},
|
|
193
|
+
});
|
|
194
|
+
yield* session.note("Updated assign IPv6 address on creation");
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// Update EnableDns64 if changed
|
|
198
|
+
if (news.enableDns64 !== olds.enableDns64) {
|
|
199
|
+
yield* ec2.modifySubnetAttribute({
|
|
200
|
+
SubnetId: subnetId,
|
|
201
|
+
EnableDns64: { Value: news.enableDns64 ?? false },
|
|
202
|
+
});
|
|
203
|
+
yield* session.note("Updated DNS64 setting");
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// Update private DNS hostname settings if changed
|
|
207
|
+
if (
|
|
208
|
+
news.enableResourceNameDnsARecordOnLaunch !==
|
|
209
|
+
olds.enableResourceNameDnsARecordOnLaunch ||
|
|
210
|
+
news.enableResourceNameDnsAAAARecordOnLaunch !==
|
|
211
|
+
olds.enableResourceNameDnsAAAARecordOnLaunch ||
|
|
212
|
+
news.hostnameType !== olds.hostnameType
|
|
213
|
+
) {
|
|
214
|
+
yield* ec2.modifySubnetAttribute({
|
|
215
|
+
SubnetId: subnetId,
|
|
216
|
+
PrivateDnsHostnameTypeOnLaunch: news.hostnameType,
|
|
217
|
+
EnableResourceNameDnsARecordOnLaunch:
|
|
218
|
+
news.enableResourceNameDnsARecordOnLaunch !== undefined
|
|
219
|
+
? { Value: news.enableResourceNameDnsARecordOnLaunch }
|
|
220
|
+
: undefined,
|
|
221
|
+
EnableResourceNameDnsAAAARecordOnLaunch:
|
|
222
|
+
news.enableResourceNameDnsAAAARecordOnLaunch !== undefined
|
|
223
|
+
? { Value: news.enableResourceNameDnsAAAARecordOnLaunch }
|
|
224
|
+
: undefined,
|
|
225
|
+
});
|
|
226
|
+
yield* session.note("Updated private DNS hostname settings");
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// Note: Tag updates would go here if we support user tag changes
|
|
230
|
+
|
|
231
|
+
return output; // Subnet attributes don't change from these updates
|
|
232
|
+
}),
|
|
233
|
+
|
|
234
|
+
delete: Effect.fn(function* ({ output, session }) {
|
|
235
|
+
const subnetId = output.subnetId;
|
|
236
|
+
|
|
237
|
+
yield* session.note(`Deleting subnet: ${subnetId}`);
|
|
238
|
+
|
|
239
|
+
// 1. Attempt to delete subnet
|
|
240
|
+
yield* ec2
|
|
241
|
+
.deleteSubnet({
|
|
242
|
+
SubnetId: subnetId,
|
|
243
|
+
DryRun: false,
|
|
244
|
+
})
|
|
245
|
+
.pipe(
|
|
246
|
+
Effect.tapError(Effect.logDebug),
|
|
247
|
+
Effect.catchTag("InvalidSubnetID.NotFound", () => Effect.void),
|
|
248
|
+
// Retry on dependency violations (resources still being deleted)
|
|
249
|
+
Effect.retry({
|
|
250
|
+
while: (e) => {
|
|
251
|
+
// DependencyViolation means there are still dependent resources
|
|
252
|
+
// This can happen if ENIs/instances are being deleted concurrently
|
|
253
|
+
return (
|
|
254
|
+
e._tag === "ValidationError" &&
|
|
255
|
+
e.message?.includes("DependencyViolation")
|
|
256
|
+
);
|
|
257
|
+
},
|
|
258
|
+
schedule: Schedule.exponential(1000, 1.5).pipe(
|
|
259
|
+
Schedule.intersect(Schedule.recurs(10)), // Try up to 10 times
|
|
260
|
+
Schedule.tapOutput(([, attempt]) =>
|
|
261
|
+
session.note(
|
|
262
|
+
`Waiting for dependencies to clear... (attempt ${attempt + 1})`,
|
|
263
|
+
),
|
|
264
|
+
),
|
|
265
|
+
),
|
|
266
|
+
}),
|
|
267
|
+
);
|
|
268
|
+
|
|
269
|
+
// 2. Wait for subnet to be fully deleted
|
|
270
|
+
yield* waitForSubnetDeleted(ec2, subnetId, session);
|
|
271
|
+
|
|
272
|
+
yield* session.note(`Subnet ${subnetId} deleted successfully`);
|
|
273
|
+
}),
|
|
274
|
+
} satisfies ProviderService<Subnet>;
|
|
275
|
+
}),
|
|
276
|
+
);
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Wait for subnet to be in available state
|
|
280
|
+
*/
|
|
281
|
+
const waitForSubnetAvailable = (
|
|
282
|
+
ec2: EC2,
|
|
283
|
+
subnetId: string,
|
|
284
|
+
session?: ScopedPlanStatusSession,
|
|
285
|
+
) =>
|
|
286
|
+
Effect.retry(
|
|
287
|
+
Effect.gen(function* () {
|
|
288
|
+
const result = yield* ec2
|
|
289
|
+
.describeSubnets({ SubnetIds: [subnetId] })
|
|
290
|
+
.pipe(
|
|
291
|
+
Effect.catchTag("InvalidSubnetID.NotFound", () =>
|
|
292
|
+
Effect.succeed({ Subnets: [] }),
|
|
293
|
+
),
|
|
294
|
+
);
|
|
295
|
+
const subnet = result.Subnets![0];
|
|
296
|
+
|
|
297
|
+
if (subnet.State === "available") {
|
|
298
|
+
return subnet;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// Still pending, fail to trigger retry
|
|
302
|
+
return yield* Effect.fail(new Error("Subnet not yet available"));
|
|
303
|
+
}),
|
|
304
|
+
{
|
|
305
|
+
schedule: Schedule.fixed(2000).pipe(
|
|
306
|
+
// Check every 2 seconds
|
|
307
|
+
Schedule.intersect(Schedule.recurs(30)), // Max 60 seconds
|
|
308
|
+
Schedule.tapOutput(([, attempt]) =>
|
|
309
|
+
session
|
|
310
|
+
? session.note(
|
|
311
|
+
`Waiting for subnet to be available... (${(attempt + 1) * 2}s)`,
|
|
312
|
+
)
|
|
313
|
+
: Effect.void,
|
|
314
|
+
),
|
|
315
|
+
),
|
|
316
|
+
},
|
|
317
|
+
);
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Wait for subnet to be deleted
|
|
321
|
+
*/
|
|
322
|
+
const waitForSubnetDeleted = (
|
|
323
|
+
ec2: EC2,
|
|
324
|
+
subnetId: string,
|
|
325
|
+
session: ScopedPlanStatusSession,
|
|
326
|
+
) =>
|
|
327
|
+
Effect.gen(function* () {
|
|
328
|
+
yield* Effect.retry(
|
|
329
|
+
Effect.gen(function* () {
|
|
330
|
+
const result = yield* ec2
|
|
331
|
+
.describeSubnets({ SubnetIds: [subnetId] })
|
|
332
|
+
.pipe(
|
|
333
|
+
Effect.tapError(Effect.logDebug),
|
|
334
|
+
Effect.catchTag("InvalidSubnetID.NotFound", () =>
|
|
335
|
+
Effect.succeed({ Subnets: [] }),
|
|
336
|
+
),
|
|
337
|
+
);
|
|
338
|
+
|
|
339
|
+
if (!result.Subnets || result.Subnets.length === 0) {
|
|
340
|
+
return; // Successfully deleted
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// Still exists, fail to trigger retry
|
|
344
|
+
return yield* Effect.fail(new Error("Subnet still exists"));
|
|
345
|
+
}),
|
|
346
|
+
{
|
|
347
|
+
schedule: Schedule.fixed(2000).pipe(
|
|
348
|
+
// Check every 2 seconds
|
|
349
|
+
Schedule.intersect(Schedule.recurs(15)), // Max 30 seconds
|
|
350
|
+
Schedule.tapOutput(([, attempt]) =>
|
|
351
|
+
session.note(
|
|
352
|
+
`Waiting for subnet deletion... (${(attempt + 1) * 2}s)`,
|
|
353
|
+
),
|
|
354
|
+
),
|
|
355
|
+
),
|
|
356
|
+
},
|
|
357
|
+
);
|
|
358
|
+
});
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import type * as EC2 from "itty-aws/ec2";
|
|
2
|
+
import type { Input } from "../../input.ts";
|
|
3
|
+
import { Resource } from "../../resource.ts";
|
|
4
|
+
import type { AccountID } from "../account.ts";
|
|
5
|
+
import type { RegionID } from "../region.ts";
|
|
6
|
+
import type { VpcId } from "./vpc.ts";
|
|
7
|
+
|
|
8
|
+
export const Subnet = Resource<{
|
|
9
|
+
<const ID extends string, const Props extends SubnetProps>(
|
|
10
|
+
id: ID,
|
|
11
|
+
props: Props,
|
|
12
|
+
): Subnet<ID, Props>;
|
|
13
|
+
}>("AWS.EC2.Subnet");
|
|
14
|
+
|
|
15
|
+
export interface Subnet<
|
|
16
|
+
ID extends string = string,
|
|
17
|
+
Props extends SubnetProps = SubnetProps,
|
|
18
|
+
> extends Resource<
|
|
19
|
+
"AWS.EC2.Subnet",
|
|
20
|
+
ID,
|
|
21
|
+
Props,
|
|
22
|
+
SubnetAttrs<Input.Resolve<Props>>,
|
|
23
|
+
Subnet
|
|
24
|
+
> {}
|
|
25
|
+
|
|
26
|
+
export interface SubnetProps {
|
|
27
|
+
/**
|
|
28
|
+
* The VPC to create the subnet in.
|
|
29
|
+
*/
|
|
30
|
+
vpcId: Input<VpcId>;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* The IPv4 network range for the subnet, in CIDR notation.
|
|
34
|
+
* Required unless using IPAM.
|
|
35
|
+
* @example "10.0.1.0/24"
|
|
36
|
+
*/
|
|
37
|
+
cidrBlock?: string;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* The IPv6 network range for the subnet, in CIDR notation.
|
|
41
|
+
*/
|
|
42
|
+
ipv6CidrBlock?: string;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* The Availability Zone for the subnet.
|
|
46
|
+
* @example "us-east-1a"
|
|
47
|
+
*/
|
|
48
|
+
availabilityZone?: string;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* The ID of the Availability Zone for the subnet.
|
|
52
|
+
*/
|
|
53
|
+
availabilityZoneId?: string;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* The ID of an IPv4 IPAM pool you want to use for allocating this subnet's CIDR.
|
|
57
|
+
*/
|
|
58
|
+
ipv4IpamPoolId?: string;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* The netmask length of the IPv4 CIDR you want to allocate to this subnet from an IPAM pool.
|
|
62
|
+
*/
|
|
63
|
+
ipv4NetmaskLength?: number;
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* The ID of an IPv6 IPAM pool which will be used to allocate this subnet an IPv6 CIDR.
|
|
67
|
+
*/
|
|
68
|
+
ipv6IpamPoolId?: Input<string>;
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* The netmask length of the IPv6 CIDR you want to allocate to this subnet from an IPAM pool.
|
|
72
|
+
*/
|
|
73
|
+
ipv6NetmaskLength?: number;
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Whether instances launched in the subnet get public IPv4 addresses.
|
|
77
|
+
* @default false
|
|
78
|
+
*/
|
|
79
|
+
mapPublicIpOnLaunch?: boolean;
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Whether instances launched in the subnet get IPv6 addresses.
|
|
83
|
+
* @default false
|
|
84
|
+
*/
|
|
85
|
+
assignIpv6AddressOnCreation?: boolean;
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Whether DNS queries made to the Amazon-provided DNS Resolver in this subnet should return
|
|
89
|
+
* synthetic IPv6 addresses for IPv4-only destinations.
|
|
90
|
+
* @default false
|
|
91
|
+
*/
|
|
92
|
+
enableDns64?: boolean;
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Whether to enable resource name DNS A record on launch.
|
|
96
|
+
* @default false
|
|
97
|
+
*/
|
|
98
|
+
enableResourceNameDnsARecordOnLaunch?: boolean;
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Whether to enable resource name DNS AAAA record on launch.
|
|
102
|
+
* @default false
|
|
103
|
+
*/
|
|
104
|
+
enableResourceNameDnsAAAARecordOnLaunch?: boolean;
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* The hostname type for EC2 instances launched into this subnet.
|
|
108
|
+
*/
|
|
109
|
+
hostnameType?: EC2.HostnameType;
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Tags to assign to the subnet.
|
|
113
|
+
* These will be merged with alchemy auto-tags (alchemy::app, alchemy::stage, alchemy::id).
|
|
114
|
+
*/
|
|
115
|
+
tags?: Record<string, Input<string>>;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export type SubnetId<ID extends string = string> = `subnet-${ID}`;
|
|
119
|
+
export const SubnetId = <ID extends string>(id: ID): ID & SubnetId<ID> =>
|
|
120
|
+
`subnet-${id}` as ID & SubnetId<ID>;
|
|
121
|
+
|
|
122
|
+
export interface SubnetAttrs<Props extends SubnetProps> {
|
|
123
|
+
/**
|
|
124
|
+
* The ID of the VPC the subnet is in.
|
|
125
|
+
*/
|
|
126
|
+
vpcId: Props["vpcId"];
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* The ID of the subnet.
|
|
130
|
+
*/
|
|
131
|
+
subnetId: SubnetId;
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* The Amazon Resource Name (ARN) of the subnet.
|
|
135
|
+
*/
|
|
136
|
+
subnetArn: `arn:aws:ec2:${RegionID}:${AccountID}:subnet/${this["subnetId"]}`;
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* The IPv4 CIDR block for the subnet.
|
|
140
|
+
*/
|
|
141
|
+
cidrBlock: string;
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* The Availability Zone of the subnet.
|
|
145
|
+
*/
|
|
146
|
+
availabilityZone: string;
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* The ID of the Availability Zone of the subnet.
|
|
150
|
+
*/
|
|
151
|
+
availabilityZoneId?: string;
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* The current state of the subnet.
|
|
155
|
+
*/
|
|
156
|
+
state: EC2.SubnetState;
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* The number of available IPv4 addresses in the subnet.
|
|
160
|
+
*/
|
|
161
|
+
availableIpAddressCount: number;
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Whether instances launched in the subnet get public IPv4 addresses.
|
|
165
|
+
*/
|
|
166
|
+
mapPublicIpOnLaunch: boolean;
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Whether instances launched in the subnet get IPv6 addresses.
|
|
170
|
+
*/
|
|
171
|
+
assignIpv6AddressOnCreation: Props["assignIpv6AddressOnCreation"];
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Whether the subnet is the default subnet for the Availability Zone.
|
|
175
|
+
*/
|
|
176
|
+
defaultForAz: boolean;
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* The ID of the AWS account that owns the subnet.
|
|
180
|
+
*/
|
|
181
|
+
ownerId?: string;
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Information about the IPv6 CIDR blocks associated with the subnet.
|
|
185
|
+
*/
|
|
186
|
+
ipv6CidrBlockAssociationSet?: Array<{
|
|
187
|
+
associationId: string;
|
|
188
|
+
ipv6CidrBlock: string;
|
|
189
|
+
ipv6CidrBlockState: {
|
|
190
|
+
state: EC2.SubnetCidrBlockStateCode;
|
|
191
|
+
statusMessage?: string;
|
|
192
|
+
};
|
|
193
|
+
}>;
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Whether DNS64 is enabled for the subnet.
|
|
197
|
+
*/
|
|
198
|
+
enableDns64?: boolean;
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Whether this is an IPv6-only subnet.
|
|
202
|
+
*/
|
|
203
|
+
ipv6Native?: boolean;
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* The private DNS name options on launch.
|
|
207
|
+
*/
|
|
208
|
+
privateDnsNameOptionsOnLaunch?: {
|
|
209
|
+
hostnameType?: EC2.HostnameType;
|
|
210
|
+
enableResourceNameDnsARecord?: boolean;
|
|
211
|
+
enableResourceNameDnsAAAARecord?: boolean;
|
|
212
|
+
};
|
|
213
|
+
}
|
|
@@ -1,54 +1,38 @@
|
|
|
1
1
|
import * as Effect from "effect/Effect";
|
|
2
2
|
import * as Schedule from "effect/Schedule";
|
|
3
3
|
|
|
4
|
-
import {
|
|
5
|
-
|
|
4
|
+
import type { EC2 } from "itty-aws/ec2";
|
|
5
|
+
|
|
6
|
+
import type { VpcId } from "./vpc.ts";
|
|
7
|
+
import type { ScopedPlanStatusSession } from "../../cli/service.ts";
|
|
8
|
+
import { somePropsAreDifferent } from "../../diff.ts";
|
|
9
|
+
import type { ProviderService } from "../../provider.ts";
|
|
6
10
|
import { createTagger, createTagsList } from "../../tags.ts";
|
|
7
|
-
import { Account } from "../account.ts";
|
|
8
|
-
import { Region } from "../region.ts";
|
|
9
11
|
import { EC2Client } from "./client.ts";
|
|
10
12
|
import { Vpc, type VpcAttrs, type VpcProps } from "./vpc.ts";
|
|
11
|
-
|
|
12
|
-
import
|
|
13
|
+
import { Region } from "../region.ts";
|
|
14
|
+
import { Account } from "../account.ts";
|
|
13
15
|
|
|
14
16
|
export const vpcProvider = () =>
|
|
15
17
|
Vpc.provider.effect(
|
|
16
18
|
Effect.gen(function* () {
|
|
17
19
|
const ec2 = yield* EC2Client;
|
|
18
|
-
const app = yield* App;
|
|
19
20
|
const region = yield* Region;
|
|
20
21
|
const accountId = yield* Account;
|
|
21
22
|
const tagged = yield* createTagger();
|
|
22
23
|
|
|
23
24
|
return {
|
|
24
|
-
diff: Effect.fn(function* ({
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
// 3. IPAM pool changes
|
|
36
|
-
if (olds.ipv4IpamPoolId !== news.ipv4IpamPoolId) {
|
|
37
|
-
return { action: "replace" } as const;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
if (olds.ipv6IpamPoolId !== news.ipv6IpamPoolId) {
|
|
41
|
-
return { action: "replace" } as const;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// 4. IPv6 CIDR block changes
|
|
45
|
-
if (olds.ipv6CidrBlock !== news.ipv6CidrBlock) {
|
|
46
|
-
return { action: "replace" } as const;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// 5. IPv6 pool changes
|
|
50
|
-
if (olds.ipv6Pool !== news.ipv6Pool) {
|
|
51
|
-
return { action: "replace" } as const;
|
|
25
|
+
diff: Effect.fn(function* ({ news, olds }) {
|
|
26
|
+
if (
|
|
27
|
+
somePropsAreDifferent(olds, news, [
|
|
28
|
+
"cidrBlock",
|
|
29
|
+
"instanceTenancy",
|
|
30
|
+
"ipv4IpamPoolId",
|
|
31
|
+
"ipv6IpamPoolId",
|
|
32
|
+
"ipv6CidrBlock",
|
|
33
|
+
])
|
|
34
|
+
) {
|
|
35
|
+
return { action: "replace" };
|
|
52
36
|
}
|
|
53
37
|
}),
|
|
54
38
|
|
|
@@ -81,7 +65,7 @@ export const vpcProvider = () =>
|
|
|
81
65
|
DryRun: false,
|
|
82
66
|
});
|
|
83
67
|
|
|
84
|
-
const vpcId = createResult.Vpc!.VpcId
|
|
68
|
+
const vpcId = createResult.Vpc!.VpcId! as VpcId;
|
|
85
69
|
yield* session.note(`VPC created: ${vpcId}`);
|
|
86
70
|
|
|
87
71
|
// 3. Modify DNS attributes if specified (separate API calls)
|