Expand description
Provides a security group resource.
NOTE: Avoid using the
ingress
andegress
arguments of theaws.ec2.SecurityGroup
resource to configure in-line rules, as they struggle with managing multiple CIDR blocks, and, due to the historical lack of unique IDs, tags and descriptions. To avoid these problems, use the current best practice of theaws.vpc.SecurityGroupEgressRule
andaws.vpc.SecurityGroupIngressRule
resources with one CIDR block per rule.
!> WARNING: You should not use the aws.ec2.SecurityGroup
resource with in-line rules (using the ingress
and egress
arguments of aws.ec2.SecurityGroup
) in conjunction with the aws.vpc.SecurityGroupEgressRule
and aws.vpc.SecurityGroupIngressRule
resources or the aws.ec2.SecurityGroupRule
resource. Doing so may cause rule conflicts, perpetual differences, and result in rules being overwritten.
NOTE: Referencing Security Groups across VPC peering has certain restrictions. More information is available in the VPC Peering User Guide.
NOTE: Due to AWS Lambda improved VPC networking changes that began deploying in September 2019, security groups associated with Lambda Functions can take up to 45 minutes to successfully delete. To allow for successful deletion, the provider will wait for at least 45 minutes even if a shorter delete timeout is specified.
NOTE: The
cidr_blocks
andipv6_cidr_blocks
parameters are optional in theingress
andegress
blocks. If nothing is specified, traffic will be blocked as described in NOTE on Egress rules later.
§Example Usage
§Basic Usage
resources:
allowTls:
type: aws:ec2:SecurityGroup
name: allow_tls
properties:
name: allow_tls
description: Allow TLS inbound traffic and all outbound traffic
vpcId: ${main.id}
tags:
Name: allow_tls
allowTlsIpv4:
type: aws:vpc:SecurityGroupIngressRule
name: allow_tls_ipv4
properties:
securityGroupId: ${allowTls.id}
cidrIpv4: ${main.cidrBlock}
fromPort: 443
ipProtocol: tcp
toPort: 443
allowTlsIpv6:
type: aws:vpc:SecurityGroupIngressRule
name: allow_tls_ipv6
properties:
securityGroupId: ${allowTls.id}
cidrIpv6: ${main.ipv6CidrBlock}
fromPort: 443
ipProtocol: tcp
toPort: 443
allowAllTrafficIpv4:
type: aws:vpc:SecurityGroupEgressRule
name: allow_all_traffic_ipv4
properties:
securityGroupId: ${allowTls.id}
cidrIpv4: 0.0.0.0/0
ipProtocol: '-1'
allowAllTrafficIpv6:
type: aws:vpc:SecurityGroupEgressRule
name: allow_all_traffic_ipv6
properties:
securityGroupId: ${allowTls.id}
cidrIpv6: ::/0
ipProtocol: '-1'
NOTE on Egress rules: By default, AWS creates an
ALLOW ALL
egress rule when creating a new Security Group inside of a VPC. When creating a new Security Group inside a VPC, this provider will remove this default rule, and require you specifically re-create it if you desire that rule. We feel this leads to fewer surprises in terms of controlling your egress rules. If you desire this rule to be in place, you can use thisegress
block:
use pulumi_wasm_rust::Output;
use pulumi_wasm_rust::{add_export, pulumi_main};
#[pulumi_main]
fn test_main() -> Result<(), Error> {
let example = security_group::create(
"example",
SecurityGroupArgs::builder()
.egress(
vec![
SecurityGroupEgress::builder().cidrBlocks(vec!["0.0.0.0/0",])
.fromPort(0).ipv6CidrBlocks(vec!["::/0",]).protocol("-1").toPort(0)
.build_struct(),
],
)
.build_struct(),
);
}
§Usage With Prefix List IDs
Prefix Lists are either managed by AWS internally, or created by the customer using a Prefix List resource. Prefix Lists provided by AWS are associated with a prefix list name, or service name, that is linked to a specific region. Prefix list IDs are exported on VPC Endpoints, so you can use this format:
use pulumi_wasm_rust::Output;
use pulumi_wasm_rust::{add_export, pulumi_main};
#[pulumi_main]
fn test_main() -> Result<(), Error> {
let example = security_group::create(
"example",
SecurityGroupArgs::builder()
.egress(
vec![
SecurityGroupEgress::builder().fromPort(0)
.prefixListIds(vec!["${myEndpoint.prefixListId}",]).protocol("-1")
.toPort(0).build_struct(),
],
)
.build_struct(),
);
let myEndpoint = vpc_endpoint::create(
"myEndpoint",
VpcEndpointArgs::builder().build_struct(),
);
}
You can also find a specific Prefix List using the aws.ec2.getPrefixList
data source.
§Removing All Ingress and Egress Rules
The ingress
and egress
arguments are processed in attributes-as-blocks mode. Due to this, removing these arguments from the configuration will not cause the provider to destroy the managed rules. To subsequently remove all managed ingress and egress rules:
use pulumi_wasm_rust::Output;
use pulumi_wasm_rust::{add_export, pulumi_main};
#[pulumi_main]
fn test_main() -> Result<(), Error> {
let example = security_group::create(
"example",
SecurityGroupArgs::builder()
.egress(vec![])
.ingress(vec![])
.name("sg")
.vpc_id("${exampleAwsVpc.id}")
.build_struct(),
);
}
§Recreating a Security Group
A simple security group name
change “forces new” the security group–the provider destroys the security group and creates a new one. (Likewise, description
, name_prefix
, or vpc_id
cannot be changed.) Attempting to recreate the security group leads to a variety of complications depending on how it is used.
Security groups are generally associated with other resources–more than 100 AWS Provider resources reference security groups. Referencing a resource from another resource creates a one-way dependency. For example, if you create an EC2 aws.ec2.Instance
that has a vpc_security_group_ids
argument that refers to an aws.ec2.SecurityGroup
resource, the aws.ec2.SecurityGroup
is a dependent of the aws.ec2.Instance
. Because of this, the provider will create the security group first so that it can then be associated with the EC2 instance.
However, the dependency relationship actually goes both directions causing the Security Group Deletion Problem. AWS does not allow you to delete the security group associated with another resource (e.g., the aws.ec2.Instance
).
The provider does not model bi-directional dependencies like this, but, even if it did, simply knowing the dependency situation would not be enough to solve it. For example, some resources must always have an associated security group while others don’t need to. In addition, when the aws.ec2.SecurityGroup
resource attempts to recreate, it receives a dependent object error, which does not provide information on whether the dependent object is a security group rule or, for example, an associated EC2 instance. Within the provider, the associated resource (e.g., aws.ec2.Instance
) does not receive an error when the aws.ec2.SecurityGroup
is trying to recreate even though that is where changes to the associated resource would need to take place (e.g., removing the security group association).
Despite these sticky problems, below are some ways to improve your experience when you find it necessary to recreate a security group.
§Shorter timeout
(This example is one approach to recreating security groups. For more information on the challenges and the Security Group Deletion Problem, see the section above.)
If destroying a security group takes a long time, it may be because the provider cannot distinguish between a dependent object (e.g., a security group rule or EC2 instance) that is in the process of being deleted and one that is not. In other words, it may be waiting for a train that isn’t scheduled to arrive. To fail faster, shorten the delete
timeout from the default timeout:
use pulumi_wasm_rust::Output;
use pulumi_wasm_rust::{add_export, pulumi_main};
#[pulumi_main]
fn test_main() -> Result<(), Error> {
let example = security_group::create(
"example",
SecurityGroupArgs::builder().name("izizavle").build_struct(),
);
}
§Provisioners
(This example is one approach to recreating security groups. For more information on the challenges and the Security Group Deletion Problem, see the section above.)
DISCLAIMER: We HIGHLY recommend using one of the above approaches and NOT using local provisioners. Provisioners, like the one shown below, should be considered a last resort since they are not readable, require skills outside standard configuration, are error prone and difficult to maintain, are not compatible with cloud environments and upgrade tools, require AWS CLI installation, and are subject to changes outside the AWS Provider.
resources:
example:
type: aws:ec2:SecurityGroup
properties:
name: sg
tags:
workaround1: tagged-name
workaround2: ${default.id}
exampleProvisioner0:
type: command:local:Command
properties:
create: 'true'
update: 'true'
delete: |2
ENDPOINT_ID=`aws ec2 describe-vpc-endpoints --filters "Name=tag:Name,Values=${tags.workaround1}" --query "VpcEndpoints[0].VpcEndpointId" --output text` &&
aws ec2 modify-vpc-endpoint --vpc-endpoint-id $${ENDPOINT_ID} --add-security-group-ids ${tags.workaround2} --remove-security-group-ids ${id}
options:
dependsOn:
- ${example}
exampleResource:
type: null:Resource
name: example
properties:
triggers:
rerun_upon_change_of:
fn::invoke:
function: std:join
arguments:
separator: ','
input: ${exampleAwsVpcEndpoint.securityGroupIds}
return: result
exampleResourceProvisioner0:
type: command:local:Command
properties:
create: |2
aws ec2 modify-vpc-endpoint --vpc-endpoint-id ${exampleAwsVpcEndpoint.id} --remove-security-group-ids ${default.id}
options:
dependsOn:
- ${exampleResource}
variables:
default:
fn::invoke:
function: aws:ec2:getSecurityGroup
arguments:
name: default
§Import
Using pulumi import
, import Security Groups using the security group id
. For example:
$ pulumi import aws:ec2/securityGroup:SecurityGroup elb_sg sg-903004f8
Structs§
- Use builder syntax to set the inputs and finish with
build_struct()
.
Functions§
- Registers a new resource with the given unique name and arguments