[FIXED] CodeBuild in privaten Subnetzen hat Verbindungsprobleme mit S3

Ausgabe

Ich habe CodeBuild in den privaten Subnetzen meiner VPC hinzugefügt, weil ich ihm Zugriff auf den RDS-Cluster in den privaten Subnetzen gewähren möchte.

Ich habe jedoch den folgenden Fehler im CodeBuild erhalten:

CLIENT_ERROR: RequestError: send request failed caused by: Get "https://abcdatabase-schema-abcdatabaseschemap-jatjfe01aqps.s3.amazonaws.com/abcDatabase-Sc/Artifact_S/LrJBqSR.zip": dial tcp 52.217.128.121:443: i/o timeout for primary source and source version arn:aws:s3:::abcdatabase-schema-abcdatabaseschemap-jatjfe01aqps/abcDatabase-Sc/Artifact_S/LrJBqSR.zip

Es ist ein TCP 443-Timeout.

Es sieht so aus, als ob CodeBuild versucht, das Pipeline-Artefakt aus dem S3-Bucket herunterzuladen, aber es gibt eine Verbindungszeitüberschreitung, was bedeutet, dass es ein Netzwerkverbindungsproblem zwischen meinem CodeBuild und S3 gibt. Ich habe jedoch einen S3-VPC-Endpunkt in meiner VPC hinzugefügt, der die Netzwerkverbindung bereitstellen soll. https://docs.aws.amazon.com/codebuild/latest/userguide/use-vpc-endpoints-with-codebuild.html .

Laut CodeBuild kann ein S3-Objekt trotz Administratorzugriff nicht abgerufen werden , solange ich einen s3-VPC-Endpunkt eingerichtet habe, benötige ich kein NAT.

Sie können den folgenden Code sehen, um zu sehen, wie ich den S3-VPC-Endpunkt hinzugefügt habe.

Code

VPC-Stapel

  private readonly coreVpc: EC2.Vpc;
  constructor(scope: CDK.App, id: string, props?: VpcStackStackProps) {
    super(scope, id, props);

    const vpcName: string = "CoreVpc";

    // Create VPC
    this.coreVpc = new EC2.Vpc(this, "CoreVpc", {
      vpcName: vpcName,
      cidr: "10.0.0.0/16",
      enableDnsHostnames: true,
      enableDnsSupport: true,
      maxAzs: 3, // 3 availability zones
      // Each zone will have one public subnet and one private subnet.
      subnetConfiguration: [
        {
          cidrMask: 19,
          name: "PublicSubnet",
          subnetType: EC2.SubnetType.PUBLIC,
        },
        {
          cidrMask: 19,
          name: "PrivateSubnet",
          subnetType: EC2.SubnetType.PRIVATE_ISOLATED,
        },
      ],
    });

    // Create security group for the VPC
    const vpcEndpointSecurityGroup = new EC2.SecurityGroup(
      this,
      `${vpcName}-VPCEndpointSecurityGroup`,
      {
        securityGroupName: `${vpcName}-VPCEndpointSecurityGroup`,
        vpc: this.coreVpc,
        description: "Security group for granting AWS services access to the CoreVpc",
        allowAllOutbound: false,
      }
    );
    vpcEndpointSecurityGroup.addIngressRule(
      EC2.Peer.ipv4(this.coreVpc.vpcCidrBlock),
      EC2.Port.tcp(443),
      "Allow HTTPS ingress traffic"
    );

    vpcEndpointSecurityGroup.addEgressRule(
      EC2.Peer.ipv4(this.coreVpc.vpcCidrBlock),
      EC2.Port.tcp(443),
      "Allow HTTPS egress traffic"
    );

    const privateSubnets = this.coreVpc.selectSubnets(
      {
        subnetType: EC2.SubnetType.PRIVATE_ISOLATED
      }
    );

    // Grant AWS CodeBuild service access to the VPC's private subnets.
    new EC2.InterfaceVpcEndpoint(
      this, 'CodeBuildInterfaceVpcEndpoint', {
        service: EC2.InterfaceVpcEndpointAwsService.CODEBUILD,
        vpc: this.coreVpc,
        privateDnsEnabled: true,
        securityGroups: [vpcEndpointSecurityGroup],
        subnets: privateSubnets
      }
    );

    // Grant VPC access to S3 service.
    new EC2.GatewayVpcEndpoint(
      this, 'S3InterfaceVpcEndpoint', {
        service: EC2.GatewayVpcEndpointAwsService.S3,
        vpc: this.coreVpc,
      }
    );
  }
}

CodeBuild-Stack

export class CodeBuildStack extends CDK.Stack {
  constructor(scope: Construct, id: string, props: CodeBuildStackProps) {
    super(scope, id, props);

    const buildspecFile = FS.readFileSync("./config/buildspec.yml", "utf-8");
    const buildspecFileYaml = YAML.parse(buildspecFile, {
      prettyErrors: true,
    });

    // Grant write permissions to the DeploymentRole to the artifact S3 bucket.
    const deploymentRoleArn: string = `arn:aws:iam::${props.env?.account}:role/${props.pipelineName}-DeploymentRole`;
    const deploymentRole = IAM.Role.fromRoleArn(
      this,
      `CodeBuild${props.pipelineStageInfo.stageName}DeploymentRoleConstructID`,
      deploymentRoleArn,
      {
        mutable: false,
        // Causes CDK to update the resource policy where required, instead of the Role
        addGrantsToResources: true,
      }
    );

    const coreVpc: EC2.IVpc = EC2.Vpc.fromLookup(
      this,
      `${props.pipelineStageInfo.stageName}VpcLookupId`,
      {
        vpcName: "CoreVpc",
      }
    );
    
    const securityGroupForVpc: EC2.ISecurityGroup =
      EC2.SecurityGroup.fromLookupByName(
        this,
        "SecurityGroupLookupForVpcEndpoint",
        "CoreVpc-VPCEndpointSecurityGroup",
        coreVpc
      );

    new CodeBuild.Project(
      this,
      `${props.pipelineName}-${props.pipelineStageInfo.stageName}-ColdBuild`,
      {
        projectName: `${props.pipelineName}-${props.pipelineStageInfo.stageName}-ColdBuild`,
        environment: {
          buildImage: CodeBuild.LinuxBuildImage.STANDARD_5_0,
        },
        buildSpec: CodeBuild.BuildSpec.fromObjectToYaml(buildspecFileYaml),
        vpc: coreVpc,
        securityGroups: [securityGroupForVpc],
        role: deploymentRole,
      }
    );
  }
}

Lösung

Das Problem in meinem Code ist dieser Teil. Die Sicherheitsgruppe fügt eine Eingangsregel hinzu, die besagt, dass ausgehender TCP-Datenverkehr vom CIDR-Block meiner VPC zugelassen wird. Aber CodeBuild wird nicht im CIDR-Block meiner VPC ausgeführt.

vpcEndpointSecurityGroup.addEgressRule(
      EC2.Peer.ipv4(this.coreVpc.vpcCidrBlock),
      EC2.Port.tcp(443),
      "Allow TCP egress traffic"
    );

Es funktioniert, indem Sie zu ändern:

vpcEndpointSecurityGroup.addEgressRule(
      EC2.Peer.anyIpv4(),
      EC2.Port.allTcp(),
      "Allow TCP egress traffic"
    );

Es gibt andere Möglichkeiten, damit es funktioniert:

Alternative 1:

Geändert basierend auf den Kommentaren von @gshpychka funktioniert auch.

Alternative 2:

allowAllOutboundWahr machen . Auf diese Weise müssen Sie keine Ausgangsregel mehr angeben.

Wenn dies auf „true“ gesetzt ist, gibt es nur eine einzige Egress-Regel, die den gesamten ausgehenden Datenverkehr zulässt. Wenn dies auf “false” gesetzt ist, wird standardmäßig kein ausgehender Datenverkehr zugelassen und der gesamte ausgehende Datenverkehr muss explizit autorisiert werden.

    const vpcEndpointSecurityGroup = new EC2.SecurityGroup(
      this,
      `${vpcName}-VPCEndpointSecurityGroup`,
      {
        securityGroupName: `${vpcName}-VPCEndpointSecurityGroup`,
        vpc: this.coreVpc,
        description: "Security group for granting AWS services access to the CoreVpc",
        allowAllOutbound: true,
      }
    );


Beantwortet von –
Yang Liu


Antwort geprüft von –
Katrina (FixError Volunteer)

0 Shares:
Leave a Reply

Your email address will not be published. Required fields are marked *

You May Also Like