import * as Provider from "../../Provider.ts"; import { Resource } from "../../Resource.ts"; import type { AccountID } from "../Environment.ts"; import { AWSEnvironment } from "../Environment.ts"; import type { Providers } from "../Providers.ts"; import type { RegionID } from "../Region.ts"; import type { VpcId } from "./Vpc.ts"; export type SecurityGroupId = `sg-${ID}`; export declare const SecurityGroupId: (id: ID) => ID & SecurityGroupId; export type SecurityGroupArn = `arn:aws:ec2:${RegionID}:${AccountID}:security-group/${GroupId}`; /** * Ingress or egress rule for a security group. */ export interface SecurityGroupRuleData { /** * The IP protocol name or number. * Use -1 to specify all protocols. */ ipProtocol: string; /** * The start of the port range. * For ICMP, use the ICMP type number. */ fromPort?: number; /** * The end of the port range. * For ICMP, use the ICMP code. */ toPort?: number; /** * IPv4 CIDR ranges to allow. */ cidrIpv4?: string; /** * IPv6 CIDR ranges to allow. */ cidrIpv6?: string; /** * ID of a security group to allow traffic from/to. */ referencedGroupId?: SecurityGroupId; /** * ID of a prefix list. */ prefixListId?: string; /** * Description for the rule. */ description?: string; } export interface SecurityGroupProps { /** * The VPC to create the security group in. */ vpcId: VpcId; /** * The name of the security group. * If not provided, a name will be generated. */ groupName?: string; /** * A description for the security group. * @default "Managed by Alchemy" */ description?: string; /** * Inbound rules for the security group. */ ingress?: SecurityGroupRuleData[]; /** * Outbound rules for the security group. * If not specified, allows all outbound traffic by default. */ egress?: SecurityGroupRuleData[]; /** * Tags to assign to the security group. */ tags?: Record; } export interface SecurityGroup extends Resource<"AWS.EC2.SecurityGroup", SecurityGroupProps, { /** * The ID of the security group. */ groupId: SecurityGroupId; /** * The Amazon Resource Name (ARN) of the security group. */ groupArn: SecurityGroupArn; /** * The name of the security group. */ groupName: string; /** * The description of the security group. */ description: string; /** * The ID of the VPC for the security group. */ vpcId: VpcId; /** * The ID of the AWS account that owns the security group. */ ownerId: string; /** * The inbound rules associated with the security group. */ ingressRules?: Array<{ securityGroupRuleId: string; ipProtocol: string; fromPort?: number; toPort?: number; cidrIpv4?: string; cidrIpv6?: string; referencedGroupId?: string; prefixListId?: string; description?: string; isEgress: false; }>; /** * The outbound rules associated with the security group. */ egressRules?: Array<{ securityGroupRuleId: string; ipProtocol: string; fromPort?: number; toPort?: number; cidrIpv4?: string; cidrIpv6?: string; referencedGroupId?: string; prefixListId?: string; description?: string; isEgress: true; }>; }, never, Providers> { } /** * An EC2 security group — a stateful virtual firewall that controls inbound * (`ingress`) and outbound (`egress`) traffic for resources in a VPC. Rules can * allow traffic from CIDR ranges, IPv6 ranges, managed prefix lists, or other * security groups. Because it is stateful, return traffic for an allowed * connection is permitted automatically regardless of the opposite-direction * rules. * * If no `egress` rules are specified, all outbound traffic is allowed by * default. Changing the `vpcId` or `groupName` replaces the security group. * * ### Creating a Security Group * Every security group belongs to a VPC. `groupName` and `description` are * optional — alchemy generates a deterministic name and a default description * when they are omitted. Both the VPC and the name are immutable, so changing * either replaces the group. * * **Example:** Empty Security Group * ```typescript * const sg = yield* AWS.EC2.SecurityGroup("AppSg", { * vpcId: vpc.vpcId, * }); * ``` * * With no rules, this group denies all inbound traffic and (since no `egress` is * given) allows all outbound. It's a useful starting point you attach rules to * later, or a target other groups can reference. * * **Example:** Named group with a description * ```typescript * const sg = yield* AWS.EC2.SecurityGroup("AppSg", { * vpcId: vpc.vpcId, * groupName: "app-tier", * description: "Application tier security group", * }); * ``` * * Set an explicit `groupName` when you need a stable, human-readable identifier * (for example to reference the group by name elsewhere). The `description` is * shown in the EC2 console and cannot be changed after creation. * * ### Ingress Rules * Inbound rules are declared inline via `ingress`. Each rule specifies an * `ipProtocol` (`tcp`, `udp`, `icmp`, or `-1` for all), an optional port range * (`fromPort`/`toPort`), and a source — most commonly an IPv4 `cidrIpv4`. * * **Example:** Allow HTTP and HTTPS from anywhere * ```typescript * const webSg = yield* AWS.EC2.SecurityGroup("WebSecurityGroup", { * vpcId: vpc.vpcId, * description: "Web tier security group", * ingress: [ * { * ipProtocol: "tcp", * fromPort: 80, * toPort: 80, * cidrIpv4: "0.0.0.0/0", * description: "Allow HTTP", * }, * { * ipProtocol: "tcp", * fromPort: 443, * toPort: 443, * cidrIpv4: "0.0.0.0/0", * description: "Allow HTTPS", * }, * ], * tags: { Name: "web-sg" }, * }); * ``` * * Two rules open the standard web ports to the whole internet (`0.0.0.0/0`). * Setting `fromPort` equal to `toPort` opens a single port; widen the range to * open a contiguous span. * * ### Egress Rules * Outbound traffic is governed by `egress`. If you omit it entirely, the group * keeps AWS's default "allow all outbound" rule. Supplying `egress` replaces * that default with exactly the rules you list — so you must re-add an * allow-all rule if you still want unrestricted outbound. * * **Example:** Restrict outbound to HTTPS only * ```typescript * const lockedSg = yield* AWS.EC2.SecurityGroup("LockedSg", { * vpcId: vpc.vpcId, * description: "Outbound restricted to HTTPS", * egress: [ * { * ipProtocol: "tcp", * fromPort: 443, * toPort: 443, * cidrIpv4: "0.0.0.0/0", * description: "Allow outbound HTTPS", * }, * ], * }); * ``` * * This locks egress down to port 443 only — useful for instances that should * only call out to HTTPS APIs. Any other outbound traffic (DNS, NTP, etc.) would * need explicit rules added here. * * ### Referencing Other Groups * Instead of a CIDR, a rule's source can be another security group via * `referencedGroupId`. This is the idiomatic way to express tier-to-tier trust * ("the database accepts connections from anything in the app tier") without * pinning IP addresses. * * **Example:** Database tier allowing traffic from the web tier * ```typescript * const dbSg = yield* AWS.EC2.SecurityGroup("DbSecurityGroup", { * vpcId: vpc.vpcId, * description: "Database tier security group", * ingress: [ * { * ipProtocol: "tcp", * fromPort: 5432, * toPort: 5432, * referencedGroupId: webSg.groupId, * description: "Allow PostgreSQL from web tier", * }, * ], * tags: { Name: "db-sg" }, * }); * ``` * * Only instances in `webSg` can reach PostgreSQL on this group, regardless of * their IPs. As the web tier scales up and down, the rule keeps working without * any change. * * ### IPv6, Prefix Lists & ICMP * Beyond IPv4 CIDRs, a rule source can be an IPv6 range (`cidrIpv6`) or a managed * prefix list (`prefixListId`). For ICMP, set `ipProtocol: "icmp"` and use * `fromPort`/`toPort` as the ICMP type and code (`-1` for all). * * **Example:** Mixed IPv6, prefix-list, and ICMP rules * ```typescript * const sg = yield* AWS.EC2.SecurityGroup("EdgeSg", { * vpcId: vpc.vpcId, * description: "Edge security group", * ingress: [ * { * ipProtocol: "tcp", * fromPort: 443, * toPort: 443, * cidrIpv6: "::/0", * description: "Allow HTTPS over IPv6", * }, * { * ipProtocol: "tcp", * fromPort: 22, * toPort: 22, * prefixListId: "pl-0123456789abcdef0", * description: "Allow SSH from corporate prefix list", * }, * { * ipProtocol: "icmp", * fromPort: -1, * toPort: -1, * cidrIpv4: "10.0.0.0/16", * description: "Allow all ICMP from within the VPC", * }, * ], * }); * ``` * * Prefix lists let you reference a centrally-maintained set of CIDRs (e.g. your * corporate egress IPs) by ID, so the rule updates automatically as the list * changes. The ICMP rule with type/code `-1` permits ping and other ICMP within * the VPC. * * @resource */ export declare const SecurityGroup: import("../../Resource.ts").ResourceClass; export declare const SecurityGroupProvider: () => import("effect/Layer").Layer, never, AWSEnvironment | import("@distilled.cloud/aws/Credentials").Credentials | import("effect/unstable/http/HttpClient").HttpClient | import("../../Stack.ts").Stack | import("../../Stage.ts").Stage>; //# sourceMappingURL=SecurityGroup.d.ts.map