aws-cdk-lib#Resource TypeScript Examples

The following examples show how to use aws-cdk-lib#Resource. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: network.ts    From aws-cdk-microservice with Apache License 2.0 5 votes vote down vote up
export class BalancerEntry extends Resource {
  constructor(scope: Construct, id: string, props: LoadBalancerProps) {
    super(scope, id);
    const listeners = this.getLoadBalancerListener(props.lbArn, props.sslEnabled, props.appName);
    if (props.sslEnabled) {
      new CfnListenerRule(this, props.appName + '-https-rule', {
        listenerArn: listeners[0],
        actions: [
          {
            type: 'forward',
            targetGroupArn: props.targetGroupArn,
          },
        ],
        conditions: [
          {
            field: 'host-header',
            hostHeaderConfig: {
              values: [props.hostHeader],
            },
          },
        ],
        priority: Math.floor(Math.random() * (1000 - 200 + 1)) + 200, // this line is a flipping leap of faith
      });
    } else {
      new CfnListenerRule(this, props.appName + '-http-rule', {
        listenerArn: listeners[0],
        actions: [
          {
            type: 'forward',
            targetGroupArn: props.targetGroupArn,
          },
        ],
        conditions: [
          {
            field: 'host-header',
            hostHeaderConfig: {
              values: [props.hostHeader],
            },
          },
        ],
        priority: Math.floor(Math.random() * (1000 - 200 + 1)) + 200, // this line is a flipping leap of faith
      });
    }
    this.createRoute53Entry(props);
  }

  private getLoadBalancerListener(loadBalancerArn: string, sslEnabled: boolean, appName: string) {
    const listeners = [];

    if (!sslEnabled) {
      listeners.push(ApplicationListener.fromLookup(this, appName + '-listener-http', {
        loadBalancerArn: loadBalancerArn,
        listenerProtocol: ApplicationProtocol.HTTP,
      }).listenerArn);
    }

    if (sslEnabled) {
      listeners.push(ApplicationListener.fromLookup(this, appName + '-listener-https', {
        loadBalancerArn: loadBalancerArn,
        listenerProtocol: ApplicationProtocol.HTTPS,
      }).listenerArn);
    }
    return listeners;
  }

  private createRoute53Entry(props: LoadBalancerProps) {
    const lb = ApplicationLoadBalancer.fromLookup(this, 'lb-' + props.lbArn, {
      loadBalancerArn: props.lbArn,
    });
    new ARecord(this, 'record-' + props.hostHeader.split('.')[-2], {
      target: RecordTarget.fromAlias(new LoadBalancerTarget(lb)),
      zone: HostedZone.fromHostedZoneAttributes(this, props.hostHeader + '-zone', {
        hostedZoneId: props.zoneId,
        zoneName: props.zoneName,
      }),
    });
  }
}
Example #2
Source File: dns-validated-domain-identity.ts    From aws-cdk-ses-domain-identity with MIT License 4 votes vote down vote up
/**
 * A domain identity managed by AWS SES.  Will be automatically
 * validated using DNS validation against the specified Route 53 hosted zone.
 */
export class DnsValidatedDomainIdentity extends Resource {
  public readonly domainName: string;
  public readonly dkim: boolean;
  public readonly identityArn: string;

  private readonly hostedZoneId: string;
  private readonly normalizedZoneName: string;

  public constructor(scope: Construct, id: string, props: DnsValidatedDomainIdentityProps) {
    super(scope, id);

    const stack = Stack.of(this);

    const region = props.region ?? stack.region;
    const accountId = stack.account;

    this.domainName = props.domainName;
    this.dkim = props.dkim ?? false;
    this.identityArn = `arn:aws:ses:${region}:${accountId}:identity/${this.domainName}`;
    this.normalizedZoneName = props.hostedZone.zoneName;
    // Remove trailing `.` from zone name
    if (this.normalizedZoneName.endsWith(".")) {
      this.normalizedZoneName = this.normalizedZoneName.substring(0, this.normalizedZoneName.length - 1);
    }

    // Remove any `/hostedzone/` prefix from the Hosted Zone ID
    this.hostedZoneId = props.hostedZone.hostedZoneId.replace(/^\/hostedzone\//, "");

    const requestorFunction = new lambda.Function(this, "DomainIdentityRequestorFunction", {
      code: lambda.Code.fromAsset(path.resolve(__dirname, "..", "lambda-packages", "dns-validated-domain-identity-handler", "dist")),
      handler: "index.identityRequestHandler",
      runtime: lambda.Runtime.NODEJS_14_X,
      memorySize: 128,
      timeout: Duration.minutes(15),
      role: props.customResourceRole,
    });
    requestorFunction.addToRolePolicy(new iam.PolicyStatement({
      actions: [
        "ses:GetIdentityVerificationAttributes",
        "ses:GetIdentityDkimAttributes",
        "ses:SetIdentityDkimEnabled",
        "ses:VerifyDomainIdentity",
        "ses:VerifyDomainDkim",
        "ses:ListIdentities",
        "ses:DeleteIdentity",
      ],
      resources: ["*"],
    }));
    requestorFunction.addToRolePolicy(new iam.PolicyStatement({
      actions: ["route53:GetChange"],
      resources: ["*"],
    }));
    requestorFunction.addToRolePolicy(new iam.PolicyStatement({
      actions: [
          "route53:changeResourceRecordSets",
          "route53:ListResourceRecordSets",
      ],
      resources: [`arn:${Stack.of(requestorFunction).partition}:route53:::hostedzone/${this.hostedZoneId}`],
    }));

    const identity = new CustomResource(this, "IdentityRequestorResource", {
      serviceToken: requestorFunction.functionArn,
      properties: {
        DomainName: this.domainName,
        HostedZoneId: this.hostedZoneId,
        Region: region,
        DKIM: props.dkim,
      },
    });

    this.node.addValidation({
      validate: (): string[] => {
        const errors: string[] = [];
        // Ensure the zone name is a parent zone of the certificate domain name
        if (!Token.isUnresolved(this.normalizedZoneName) &&
          this.domainName !== this.normalizedZoneName &&
          !this.domainName.endsWith("." + this.normalizedZoneName)) {
          errors.push(`DNS zone ${this.normalizedZoneName} is not authoritative for SES identity domain name ${this.domainName}`);
        }

        return errors;
      },
    });
  }
}
Example #3
Source File: autoScalingGroup.ts    From aws-cdk-microservice with Apache License 2.0 4 votes vote down vote up
export class AutoScaler extends Resource {
  public readonly loadBalancerProperties?: LoadBalancerProps[];
  constructor(scope: Construct, id: string, props: AutoScalerProps) {
    super(scope, id);

    const launchTemplate = this.getLT(props.templateProps, props.asgName);
    this.loadBalancerProperties = this.getTG(props.networkProps, props.templateProps.vpc.vpcName, props.appName);

    new CfnAutoScalingGroup(this, props.asgName, {
      maxSize: props.maxSize,
      minSize: props.minSize,
      autoScalingGroupName: props.asgName,
      launchTemplate: {
        version: launchTemplate.versionNumber,
        launchTemplateId: launchTemplate.launchTemplateId,
        launchTemplateName: launchTemplate.launchTemplateName,
      },
      targetGroupArns: this.loadBalancerProperties.map( (lb) => { return lb.targetGroupArn; } ),
      tags: props.tags,
      availabilityZones: props.availabilityZones,
      vpcZoneIdentifier: props.subnets,
      healthCheckGracePeriod: 300,
    });
  }

  private getVPC(props: InternalVPC) {
    const stackVPC = Vpc.fromLookup(this, props.vpcName, {
      isDefault: false,
      vpcId: props.vpcName,
    });
    return stackVPC;
  }

  private getRole(props: InternalRole, asgName: string) {
    if (props.type == 'existing') {
      const role = Role.fromRoleArn(this, asgName + '-stackRole', props.roleArn!);
      return role;
    } else {
      const role = new Role(this, asgName + '-stackRole', {
        assumedBy: new ServicePrincipal('ec2.amazonaws.com'),
        roleName: asgName + '-role',
      });

      role.addManagedPolicy({
        managedPolicyArn: 'arn:aws:iam::aws:policy/service-role/AmazonEC2SpotFleetTaggingRole',
      });


      role.addManagedPolicy({
        managedPolicyArn: 'arn:aws:iam::aws:policy/ReadOnlyAccess',
      });

      role.addManagedPolicy({
        managedPolicyArn: 'arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforSSM',
      });

      role.addManagedPolicy({
        managedPolicyArn: 'arn:aws:iam::aws:policy/AmazonEC2FullAccess',
      });

      role.addToPolicy(
        new PolicyStatement({
          effect: Effect.ALLOW,
          resources: ['*'],
          actions: [
            'iam:ListUsers',
            'iam:GetGroup',
          ],
        }),
      );

      role.addToPolicy(
        new PolicyStatement({
          effect: Effect.ALLOW,
          resources: ['*'],
          actions: [
            'ec2:DescribeTags',
          ],
        }),
      );

      role.addToPolicy(
        new PolicyStatement({
          effect: Effect.ALLOW,
          resources: ['*'],
          actions: [
            'iam:ListUsers',
            'iam:GetGroup',
          ],
          sid: 'VisualEditor0',
        }),
      );

      props.additionalPolicies?.forEach(policyDoc => {
        role.addToPolicy(
          PolicyStatement.fromJson(
            policyDoc,
          ),
        );
      });

      return role;
    }
  }

  private getSG(props: InternalSG, vpc: IVpc, asgName: string) {
    if (props.type == 'existing') {
      const securityGroup = SecurityGroup.fromSecurityGroupId(this, 'stack-sg', props.sgGroupId!);
      return securityGroup;
    } else {
      const sgProps: SecurityGroupProps = {
        securityGroupName: props.securityGroupName ?? 'stack-sg-group',
        vpc: vpc!,
        allowAllOutbound: props.allowAllOutbound ?? true,
        disableInlineRules: props.disableInlineRules ?? false,
      };
      const securityGroup = new SecurityGroup(this, asgName + '-stack-sg', sgProps);
      props.ingressRules!.forEach(ingress => {
        const ingressSG = SecurityGroup.fromSecurityGroupId(this, ingress.sourceSG + ingress.port.toString(), ingress.sourceSG);
        securityGroup.connections.allowFrom(ingressSG, Port.tcp(ingress.port), ingress.description ?? 'Application port');
      });
      return securityGroup;
    }
  }

  private getBD(props: InternalBD) {
    const bd: BlockDevice = {
      deviceName: props.name,
      volume: BlockDeviceVolume.ebs(props.size, {
        volumeType: props.type,
        deleteOnTermination: true,
      }),
    };
    return bd;
  }

  private getLT(props: InternalLaunchTemplateProps, asgName: string) {
    if (props.type == 'existing') {
      const launchTemplate = LaunchTemplate.fromLaunchTemplateAttributes(this, props.templateName, props.existingAttributes!);
      return launchTemplate;

    } else {

      const launchTemplate = new LaunchTemplate(this, props.templateName, {
        launchTemplateName: props.templateName,
        instanceType: new InstanceType(props.instanceType),
        machineImage: MachineImage.lookup({
          name: props.amiImageId,
        }),
        securityGroup: this.getSG(props.securityGroup, this.getVPC(props.vpc), asgName),
        role: this.getRole(props.role, asgName),
        detailedMonitoring: false,
        blockDevices: [this.getBD(props.blockDevice)],
        keyName: props.sshKey,
      });

      return launchTemplate;

    }
  }

  private getTG(props: NetworkProps[], vpcId: string, appName: string) {
    let lbProps: LoadBalancerProps[] = [];
    props.forEach(t => {
      const tg = new CfnTargetGroup(this, appName + t.port.toString(), {
        name: appName + t.port?.toString(),
        healthCheckEnabled: true,
        healthCheckPath: t.healthCheckPath!,
        ...((t.protocol == 'GRPC') ? { protocol: 'HTTP' } : { protocol: t.protocol }),
        ...((t.protocol == 'GRPC') ? { protocolVersion: 'GRPC' } : {}),
        healthCheckTimeoutSeconds: 5,
        healthCheckPort: String(t.port!),
        port: t.port!,
        vpcId: vpcId,
      });

      lbProps.push({
        appName: appName,
        hostHeader: t.host,
        lbArn: t.lbArn,
        sslEnabled: t.sslEnabled,
        targetGroupArn: tg.ref,
        zoneId: t.zoneId,
        zoneName: t.zoneName,
      });

    });

    return lbProps;
  }
}