-
Notifications
You must be signed in to change notification settings - Fork 3.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Get default security group from VPC #1606
Comments
The simplest way would be to use a The resource is called https://github.com/awslabs/aws-cdk/blob/master/packages/%40aws-cdk/aws-ec2/lib/vpc.ts#L312 Can you tell us a little about what you're trying to achieve though, and why the existing SecurityGroup mechanisms aren't sufficient? |
Can you elaborate on what you mean with the existing security group mechanisms? My understanding is, and forgive me if I am wrong, that you cannot specify the security group when you are creating your VPC. Because of that I have to work around the fact that the security group is created automatically when the VPC is created. Regarding the reason as to why I need the exported output, please let me check my code tomorrow at work, and I will update you with information. |
It's not that the existing security group mechanisms are insufficient, they are not. However, we expected the default security group to be readily available since it is created automatically and there is no way to prohibit it to be created (as far as I know). |
My issue #1995 seems to be a dup of this. I tried the "escape hatch" workaround suggested by @rix0rrr :
but this doesn't seem to work either as I get a runtime error: Just to be specific on the use case: when I'm creating an EFS file system mountpoint it requires I specify the security group ID associated with the subnet. |
Still relevant, but not easy. The default security group is not created as part of CDK. |
I misunderstood the question originally: someone wanting to do this can get the Closing this, feel free to reopen if someone has a compelling use case. |
Just about to (I think) bump into this. One use case I can see is that the CIS security benchmark for AWS dictates that all default security groups should restrict all traffic (control 4.3 - https://docs.aws.amazon.com/securityhub/latest/userguide/securityhub-cis-controls.html#cis-4.3-remediation). To comply with that, it would be nice to configure the default security group as part of the CDK template. I'll do some reading and find out whether (a) this is already possible as @rix0rr says, or (b) needs to be added. Had to do something similar to retrieve the default IGW id, so hopefully isn't too dissimilar. |
Did you find out if this was possible in a standard way? As the above is my exact use case |
Sorry @AaronFinn95, read this on email and then forgot to reply! I think in the end I didn't chase this down any further. IIRC, I either manually changed the default VPC once I'd built it (since it wasn't getting torn down and recreated very much), or used the "escape hatch" method to get the group ID... If I get time I'll have to revisit this and try to raise a PR, doing the same thing for the IGW wasn't too taxing. |
@shearn89 & @AaronFinn95: FYI- I ran into this issue yesterday because of the same use case and solved it by wrapping the import { Stack } from 'aws-cdk-lib';
import { CfnVPC, Vpc, VpcProps } from 'aws-cdk-lib/aws-ec2';
import {
AwsCustomResource, AwsCustomResourcePolicy, PhysicalResourceId
} from 'aws-cdk-lib/custom-resources';
import { Construct } from 'constructs';
export class BaseVpc extends Vpc {
constructor(
scope: Construct,
id: string,
props: VpcProps) {
super(
scope,
id,
props);
// Configure default security group according to "CIS AWS Foundations Benchmark controls",
// section "4.3 – Ensure the default security group of every VPC restricts all traffic".
// See https://docs.aws.amazon.com/securityhub/latest/userguide/securityhub-cis-controls.html#securityhub-cis-controls-4.3
const cfnVpc = this.node.defaultChild as CfnVPC;
const stack = Stack.of(this);
const ingressParameters = {
GroupId: cfnVpc.attrDefaultSecurityGroup,
IpPermissions: [
{
IpProtocol: '-1',
UserIdGroupPairs: [
{
GroupId: cfnVpc.attrDefaultSecurityGroup,
},
],
},
],
};
new AwsCustomResource(
this,
'RestrictSecurityGroupIngress',
{
onCreate: {
service: 'EC2',
action: 'revokeSecurityGroupIngress',
parameters: ingressParameters,
physicalResourceId: PhysicalResourceId.of(`restrict-ingress-${this.vpcId}-${cfnVpc.attrDefaultSecurityGroup}`),
},
onDelete: {
service: 'EC2',
action: 'authorizeSecurityGroupIngress',
parameters: ingressParameters,
},
policy: AwsCustomResourcePolicy.fromSdkCalls({
resources: [`arn:aws:ec2:${stack.region}:${stack.account}:security-group/${cfnVpc.attrDefaultSecurityGroup}`],
}),
});
const egressParameters = {
GroupId: cfnVpc.attrDefaultSecurityGroup,
IpPermissions: [
{
IpProtocol: '-1',
IpRanges: [
{
CidrIp: '0.0.0.0/0',
},
],
},
],
};
new AwsCustomResource(
this,
'RestrictSecurityGroupEgress',
{
onCreate: {
service: 'EC2',
action: 'revokeSecurityGroupEgress',
parameters: egressParameters,
physicalResourceId: PhysicalResourceId.of(`restrict-egress-${this.vpcId}-${cfnVpc.attrDefaultSecurityGroup}`),
},
onDelete: {
service: 'EC2',
action: 'authorizeSecurityGroupEgress',
parameters: egressParameters,
},
policy: AwsCustomResourcePolicy.fromSdkCalls({
resources: [`arn:aws:ec2:${stack.region}:${stack.account}:security-group/${cfnVpc.attrDefaultSecurityGroup}`],
}),
});
}
} |
Following @basverweij-pp reply, I had the same problem and translated his code to Python. from aws_cdk import aws_iam
from aws_cdk.aws_ec2 import CfnVPC, Vpc
from aws_cdk.core import Stack, Construct
from aws_cdk.custom_resources import AwsCustomResource, AwsCustomResourcePolicy, PhysicalResourceId, AwsSdkCall
class BaseVpc(Vpc):
def __init__(self, scope: Construct, id: str, **kwargs):
super().__init__(scope, id, **kwargs)
# Configure default security group according to "CIS AWS Foundations Benchmark controls",
# section "4.3 – Ensure the default security group of every VPC restricts all traffic".
# See https://docs.aws.amazon.com/securityhub/latest/userguide/securityhub-cis-controls.html#securityhub-cis-controls-4.3
cfn_vpc: CfnVPC = self.node.default_child
stack: Stack = Stack.of(self)
ingress_parameters = {
'GroupId': cfn_vpc.attr_default_security_group,
'IpPermissions': [
{
'IpProtocol': '-1',
'UserIdGroupPairs': [
{
'GroupId': cfn_vpc.attr_default_security_group,
},
],
},
],
}
AwsCustomResource(
self,
'RestrictSecurityGroupIngress',
on_create=AwsSdkCall(service='EC2',
action='revokeSecurityGroupIngress',
parameters=ingress_parameters,
physical_resource_id=PhysicalResourceId.of(
f'restrict-ingress-${self.vpc_id}-${cfn_vpc.attr_default_security_group}')),
on_delete=AwsSdkCall(service='EC2', action='authorizeSecurityGroupIngress',
parameters=ingress_parameters),
policy=AwsCustomResourcePolicy.from_statements(statements=[
aws_iam.PolicyStatement(
effect=aws_iam.Effect.ALLOW,
actions=['ec2:revokeSecurityGroupIngress'],
resources=[
f'arn:aws:ec2:{stack.region}:{stack.account}:security-group/{cfn_vpc.attr_default_security_group}']
)])
)
egress_parameters = {
'GroupId': cfn_vpc.attr_default_security_group,
'IpPermissions': [
{
'IpProtocol': '-1',
'IpRanges': [
{
'CidrIp': '0.0.0.0/0',
},
],
},
],
}
AwsCustomResource(
self, 'RestrictSecurityGroupEgress',
on_create=AwsSdkCall(service='EC2',
action='revokeSecurityGroupEgress',
parameters=egress_parameters,
physical_resource_id=PhysicalResourceId.of(
f'restrict-egress-${self.vpc_id}-${cfn_vpc.attr_default_security_group}')),
on_delete=AwsSdkCall(service='EC2', action='authorizeSecurityGroupEgress',
parameters=egress_parameters),
policy=AwsCustomResourcePolicy.from_statements(statements=[
aws_iam.PolicyStatement(
effect=aws_iam.Effect.ALLOW,
actions=['ec2:revokeSecurityGroupEgress'],
resources=[
f'arn:aws:ec2:{stack.region}:{stack.account}:security-group/{cfn_vpc.attr_default_security_group}']
)])) |
@basverweij-pp could you explain why you have to define an |
@basverweij-pp is it really necessary to define a |
@qoomon It's been a while since I created this 🙂, but I think the problem was that if you don't restore the ingress and egress settings, deploying the stack a second time (e.g. after it failed deploying and rolled back because of a problem with another construct) causes an error because the specific ingress and egress rules that we are trying to delete do not exist anymore. |
@qoomon I would say that there are two reasons: 1) it improves readability of your resources in CloudFormation; and 2) it prevents replacements due to a changed physical resource id which would not work in this scenario (as the replacement tries to create the new resource first - which would try to revoke the ingress & egress again, and hence failing; and even if it would succeed, it would then authorize the original ingress & egress when the resource with the 'old' physical resource id is deleted). Hope this helps! |
@basverweij-pp thanks a lot for your explanation. |
I would like to export the default security group id from a VPC I create. In CloudFormation I would reference the VPC return value of
DefaultSecurityGroup
, but how would I accomplish the same using the CDK?The text was updated successfully, but these errors were encountered: