skip to Main Content

Amazon recently killed a rails production server of mine because they stopped supporting ruby 2.3 on their elastic beanstalk platform. I have been trying (desperately) to get new infrastructure setup using the CDK.

I was able to aws execute-command into my task and see that 1) it has database connectivity, and 2) I can curl to localhost:3000 and get responses, so everything in the container is working.

I am certain the problem has to do with my lack of understanding of security groups…

I have a database stack which creates a security group and opens up port 5432 to itself– not sure if this is the right thing to do?

    const securityGroup = new ec2.SecurityGroup(this, 'RdsSecurityGroup', {
      vpc,
      securityGroupName: SECURITY_GROUP_NAME,
    });
    securityGroup.addIngressRule(securityGroup, ec2.Port.tcp(5432));

    this.database = new rds.DatabaseInstanceFromSnapshot(this, 'RdsDatabaseInstance', {
      credentials: rds.SnapshotCredentials.fromSecret(rdsCredentials),
      enablePerformanceInsights: true,
      engine: rds.DatabaseInstanceEngine.postgres({ version: rds.PostgresEngineVersion.VER_12_14 }),
      instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.MICRO),
      multiAz: true,
      publiclyAccessible: false,
      snapshotIdentifier: DATABASE_SNAPSHOT,
      securityGroups: [securityGroup],
      vpc,
      vpcSubnets: {
        subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS,
      }
    });
  }
}

Then my cluster stack looks up that security group and adds it to the service that creates the load balanced cluster:

    const rdsSsecurityGroup = ec2.SecurityGroup.fromLookupByName(this, 'RdsSecurityGroup', SECURITY_GROUP_NAME, vpc);

    const app = taskDefinition.addContainer('TaskDefinition', {
      environment: {
        'RDS_HOSTNAME': database.dbInstanceEndpointAddress,
        'RDS_PORT': database.dbInstanceEndpointPort,
        'RAILS_SERVE_STATIC_FILES': 'true',
      },
      image: ecs.ContainerImage.fromDockerImageAsset(dockerImageAsset),
      logging: ecs.LogDriver.awsLogs({ streamPrefix: 'noteblaster-server' }),
    });

    app.addPortMappings({
      containerPort: 3000,
      protocol: ecs.Protocol.TCP,
    });

    const service = new ecs_patterns.ApplicationLoadBalancedFargateService(this, 'FargateService', {
      cluster: cluster,
      cpu: 1,
      desiredCount: 1,
      domainName: DOMAIN_NAME,
      domainZone: hostedZone,
      enableExecuteCommand: true,
      memoryLimitMiB: 1024,
      protocol: ApplicationProtocol.HTTPS,
      publicLoadBalancer: true,
      redirectHTTP: true,
      securityGroups: [
        rdsSsecurityGroup,
      ],
      taskDefinition: taskDefinition,
    });
  }

My load balancer shows it has inbound rules for 80 and 443, and one outbound rule going to 3000, but it showed the destination being my rds security group– which seems totally wrong.

2

Answers


  1. Chosen as BEST ANSWER

    The problem was not security groups.. It was rails server binding to localhost which is inaccessible. I needed to rails s -b 0.0.0.0 and then everything worked.


  2. Create 3 security groups and use security group chaining technique, example:

        // ################## ALB-SG ######################
        const albSG = new SecurityGroup(this, 'AlbSg', {
          vpc,
          allowAllOutbound: true,  // just an example
        })
        albSG.addIngressRule(Peer.anyIpv4(), Port.tcp(443))
        albSG.addIngressRule(Peer.anyIpv4(), Port.tcp(80))
    
        // ################## APP-SG ######################
        const appSG = new SecurityGroup(this, 'AppSg', {
          vpc,
        })
        appSG.addIngressRule(Peer.securityGroupId(albSG.securityGroupId), Port.tcp(3000))
    
        // ################## DB-SG ######################
        const dbGg = new SecurityGroup(this, 'DbSg', {
          vpc,
        })
        dbGg.addIngressRule(Peer.securityGroupId(appSG.securityGroupId), Port.tcp(5432))
        appSG.addEgressRule(Peer.securityGroupId(dbGg.securityGroupId), Port.tcp(5432))
    

    I hope it’s enough to get the idea.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search