Skip to content

addSecurityGroup didn't work for ECS_pattern ALB Fargate #5635

Open
@ptaylor10

Description

@ptaylor10

I was not able to add another security group to the ECS Pattern for ALB Fargate service using Fargate.cluster.connections.addSecurityGroup() method.

Reproduction Steps

ecs-fargate.ts

export class ECSFargateStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // Imports the VPC from the name provided
    const vpc = ec2.Vpc.fromLookup(this, this.stackName+'VPC', {
      vpcName: vpc_name
    })
    
    const laravelAppSecret = new secrets.Secret(this, this.stackName+'_LaravelAppKeySecret',{
      secretName: this.stackName+'-LaravelAppKey',
      generateSecretString: {
        includeSpace: false,
        passwordLength: 32,
        excludeCharacters: '"@/\\'
      }
    })

    // Builds and publishes the container image
    const image = new ecr_assets.DockerImageAsset(this, this.stackName+'_Image', {
      directory: __dirname+'/../docker/'+applicationName,
      buildArgs:{
        'tag':applicationName
      }
    })

    //Creates the ECS Fargate cluster, task, and application load balancer
    const fargateservice = new ecs_patterns.ApplicationLoadBalancedFargateService(this, this.stackName, {
      vpc: vpc,
      publicLoadBalancer: publicLoadBalancer,
      desiredCount: desiredCount,
      taskImageOptions: {
        image: ecs.ContainerImage.fromEcrRepository(image.repository),
        enableLogging: true,
        logDriver: new ecs.AwsLogDriver({ streamPrefix: this.stackName+'-'+this.region }),
        environment:{
          'APP_DEBUG': 'false',
          'DB_USERNAME': cdk.Fn.importValue('DBUser'),
          'DB_DATABASE': cdk.Fn.importValue('DBName'),
          'DB_HOST': cdk.Fn.importValue('DBHost'),
          'DB_PORT': '3306'
        },
        secrets: {
          'DB_PASSWORD': ecs.Secret.fromSecretsManager(secrets.Secret.fromSecretArn(this, this.stackName+'_DBPasswordSecret', cdk.Fn.importValue('DBSecretArn'))),
          'APP_KEY': ecs.Secret.fromSecretsManager(laravelAppSecret)
        },
        containerPort: 80,
        containerName: this.stackName,
      },
      cpu: cpu,
      memoryLimitMiB: memoryLimit
    })
    
    fargateservice.cluster.connections.addSecurityGroup(ec2.SecurityGroup.fromSecurityGroupId(this, this.stackName+'_DBSecurityGroup', cdk.Fn.importValue('DBSecurityGroupId')))
  }
}

db.ts

export class RDSStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // Imports the VPC from the name provided
    const vpc = ec2.Vpc.fromLookup(this, this.stackName+'VPC', {
      vpcName: vpc_name
    })    

    //Creates secrets needed for the stack
    const dbSecret = new secrets.Secret(this, this.stackName+'_DBPasswordSecret',{
      secretName: this.stackName+'-DBPassword',
      generateSecretString: {
        includeSpace: false,
        passwordLength: 32,
        excludeCharacters: '"@/\\'
      }
    })

    //Creates Security Group and adds Ingress rule to open 3306 to everyone
    const sg =  new ec2.SecurityGroup(this, this.stackName+'_SecurityGroup', {
      securityGroupName: this.stackName+'_SecurityGroup',
      vpc: vpc,
      allowAllOutbound: allOutbound,
      description: 'Security Group to access '+this.stackName+' database'
    })
    sg.connections.allowInternally(ec2.Port.tcp(3306))

    const dbSubnetGroup = new rds.CfnDBSubnetGroup(this, this.stackName+'_DBSubnetGroup',{
      subnetIds: vpc.privateSubnets.map(subnet => subnet.subnetId),
      dbSubnetGroupDescription: 'Aurora Subnet Group'
    })
    const db = new rds.CfnDBCluster(this, this.stackName+'-AuroraRDSCluster', {
      engine: 'aurora',
      engineMode: 'serverless',
      engineVersion: '5.6',
      masterUsername: dbUsername,
      masterUserPassword: dbSecret.secretValue.toString(),
      dbSubnetGroupName: dbSubnetGroup.ref,
      availabilityZones: vpc.availabilityZones,
      databaseName: dbName,
      deletionProtection: dbdelectionprotection,
      backupRetentionPeriod: 30,
      scalingConfiguration:{
        minCapacity: dbMin,
        maxCapacity: dbMax,
        autoPause: dbAutoPause,
        secondsUntilAutoPause: dbAutoPauseSeconds
      },
      vpcSecurityGroupIds: [sg.securityGroupId],
    })

    //Creates Outputs that can be used by other templates in the same account
    new cdk.CfnOutput(this, this.stackName+'DBUser', {
      value: db.masterUsername as string, 
      exportName: 'DBUser'
    })
    new cdk.CfnOutput(this, this.stackName+'DBName', {
      value: db.databaseName as string,
      exportName: 'DBName'
    })
    new cdk.CfnOutput(this, this.stackName+'DBHost', {
      value: db.attrEndpointAddress,
      exportName: 'DBHost'
    })
    new cdk.CfnOutput(this, this.stackName+'DBPort', {
      value: db.attrEndpointPort,
      exportName: 'DBPort'
    })
    new cdk.CfnOutput(this, this.stackName+'DBSecretArn',{
      value: dbSecret.secretArn,
      exportName: 'DBSecretArn'
    })
    new cdk.CfnOutput(this, this.stackName+'DBSecurityGroupId',{
      value: sg.securityGroupId,
      exportName: 'DBSecurityGroupId'
    })
  }
}

Error Log

No real error messages just don't see the security group in the cloud formation json nor will the application connect to the database.

Environment

  • **CLI Version : 1.19
  • **Framework Version: 1.19
  • **OS : Mac OSX
  • **Language : typescript

Other

I am currently using this as a workaround as it has a similar effect:

ec2.SecurityGroup.fromSecurityGroupId(this, this.stackName+'_DBSecurityGroup', cdk.Fn.importValue('DBSecurityGroupId')).connections.allowFrom(fargateservice.service.connections, ec2.Port.tcp(3306))


This is 🐛 Bug Report

Metadata

Metadata

Assignees

No one assigned

    Labels

    @aws-cdk/aws-ecs-patternsRelated to ecs-patterns librarybugThis issue is a bug.effort/mediumMedium work item – several days of effortp2

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions