Skip to content
This repository has been archived by the owner on May 17, 2023. It is now read-only.

Commit

Permalink
feat: deploy with internal ALB not exposing the Nexus OSS to internet
Browse files Browse the repository at this point in the history
  • Loading branch information
zxkane committed Dec 23, 2020
1 parent acd8b5e commit 34f0882
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 38 deletions.
13 changes: 9 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ npm run init
```

### Deployment
#### Deploy with mandatory parameters
#### Deploy with custom domain
```
npm run deploy -- --parameters NexusAdminInitPassword=<init admin password of nexus3> --parameters DomainName=<the hostname of nexus3 deployment>
```
Expand All @@ -39,13 +39,18 @@ npm run deploy -- --parameters NexusAdminInitPassword=<init admin password of ne

#### Deploy to a new created VPC
```
npm run deploy -- <mandatory options> -c createNewVpc=true
npm run deploy -- <other options> -c createNewVpc=true
```

#### Deploy with internal load balancer
```
npm run deploy -- -c internalALB=true
```

#### Deploy to China regions
Due to AWS load balancer has different policy requirement for partitions, you need speicfy the target region info via context `region` to pick the corresponding IAM policies.
```
npm run deploy -- <mandatory options> -c region=cn-north-1
npm run deploy -- <other options> -c region=cn-north-1
```

### Init admin password
Expand All @@ -57,7 +62,7 @@ You must specify the default init admin password when deploying this solution. T
### Auto configuration
Nexus3 supports using [script][nexus3-script] to configure the Nexus3 service, for example, BlobStores, Repositories and so on. The script feature is disabled by default since Nexus3 3.21.2. You can opt-in auto configuration feature of this solution like below that will enable script feature of Nexus.
```
npm run deploy -- <mandatory options> -c enableAutoConfigured=true
npm run deploy -- <other options> -c enableAutoConfigured=true
```
It would automatically configure the fresh provisioning Nexus3 with below changes,

Expand Down
77 changes: 43 additions & 34 deletions lib/sonatype-nexus3-stack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,6 @@ export class SonatypeNexus3Stack extends cdk.Stack {
}
});

const domainNameParameter = new cdk.CfnParameter(this, 'DomainName', {
type: 'String',
allowedPattern: '(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z0-9][a-z0-9-]{0,61}[a-z0-9]',
description: 'The domain name of Nexus OSS deployment, such as mydomain.com.',
constraintDescription: 'validate domain name without protocol',
});
const domainName = domainNameParameter.valueAsString;

const constraintDescription = '- at least 8 characters\n- must contain at least 1 uppercase letter, 1 lowercase letter, and 1 number\n- Can contain special characters';
const adminInitPassword = new cdk.CfnParameter(this, 'NexusAdminInitPassword', {
type: 'String',
Expand All @@ -53,31 +45,44 @@ export class SonatypeNexus3Stack extends cdk.Stack {
constraintDescription,
noEcho: true,
});

var hostedZone = null;
var certificate: certmgr.Certificate | undefined;
const r53Domain = this.node.tryGetContext('r53Domain');
if (r53Domain) {
hostedZone = route53.HostedZone.fromLookup(this, 'R53HostedZone', {
domainName: r53Domain,
privateZone: false,
});
assert.ok(hostedZone != null, 'Can not find your hosted zone.');
certificate = new certmgr.Certificate(this, `SSLCertificate`, {
domainName: domainName,
validation: certmgr.CertificateValidation.fromDns(hostedZone),
});
} else if ((/true/i).test(this.node.tryGetContext('enableR53HostedZone'))) {
const r53HostedZoneIdParameter = new cdk.CfnParameter(this, 'R53HostedZoneId', {
type: targetRegion.startsWith('cn-') ? 'String' : 'AWS::Route53::HostedZone::Id',
description: 'The hosted zone ID of given domain name in Route 53.',
});
hostedZone = route53.HostedZone.fromHostedZoneId(this, 'ImportedHostedZone', r53HostedZoneIdParameter.valueAsString);
certificate = new certmgr.Certificate(this, `SSLCertificate`, {
domainName: domainName,
validation: certmgr.CertificateValidation.fromDns(hostedZone),
var domainName: string | undefined;

const internalALB = (/true/i).test(this.node.tryGetContext('internalALB'));
const r53Domain = internalALB ? undefined : this.node.tryGetContext('r53Domain');

if (!internalALB) {
const domainNameParameter = new cdk.CfnParameter(this, 'DomainName', {
type: 'String',
allowedPattern: '(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z0-9][a-z0-9-]{0,61}[a-z0-9]',
description: 'The domain name of Nexus OSS deployment, such as mydomain.com.',
constraintDescription: 'validate domain name without protocol',
});
domainName = domainNameParameter.valueAsString;
if (r53Domain) {
hostedZone = route53.HostedZone.fromLookup(this, 'R53HostedZone', {
domainName: r53Domain,
privateZone: false,
});
assert.ok(hostedZone != null, 'Can not find your hosted zone.');
certificate = new certmgr.Certificate(this, `SSLCertificate`, {
domainName: domainName,
validation: certmgr.CertificateValidation.fromDns(hostedZone),
});
} else if ((/true/i).test(this.node.tryGetContext('enableR53HostedZone'))) {
const r53HostedZoneIdParameter = new cdk.CfnParameter(this, 'R53HostedZoneId', {
type: targetRegion.startsWith('cn-') ? 'String' : 'AWS::Route53::HostedZone::Id',
description: 'The hosted zone ID of given domain name in Route 53.',
});
hostedZone = route53.HostedZone.fromHostedZoneId(this, 'ImportedHostedZone', r53HostedZoneIdParameter.valueAsString);
certificate = new certmgr.Certificate(this, `SSLCertificate`, {
domainName: domainName,
validation: certmgr.CertificateValidation.fromDns(hostedZone),
});
}
}

let vpc!: ec2.IVpc;
const createNewVpc: boolean = this.node.tryGetContext('createNewVpc') ?? false;
if (createNewVpc) {
Expand Down Expand Up @@ -287,8 +292,8 @@ export class SonatypeNexus3Stack extends cdk.Stack {
'alb.ingress.kubernetes.io/healthcheck-path': healthcheckPath,
'alb.ingress.kubernetes.io/healthcheck-port': nexusPort,
'alb.ingress.kubernetes.io/listen-ports': '[{"HTTP": 80}]',
'alb.ingress.kubernetes.io/scheme': 'internet-facing',
'alb.ingress.kubernetes.io/inbound-cidrs': '0.0.0.0/0',
'alb.ingress.kubernetes.io/scheme': internalALB ? 'internal' : 'internet-facing',
'alb.ingress.kubernetes.io/inbound-cidrs': internalALB ? vpc.vpcCidrBlock : '0.0.0.0/0',
'alb.ingress.kubernetes.io/auth-type': 'none',
'alb.ingress.kubernetes.io/target-type': 'ip',
'kubernetes.io/ingress.class': 'alb',
Expand Down Expand Up @@ -561,12 +566,16 @@ export class SonatypeNexus3Stack extends cdk.Stack {
}
}

new cdk.CfnOutput(this, 'nexus3-s3-bucket-blobstore', {
new cdk.CfnOutput(this, 'nexus-oss-s3-bucket-blobstore', {
value: `${nexusBlobBucket.bucketName}`,
description: 'S3 Bucket created for Nexus3 S3 Blobstore'
description: 'S3 Bucket created for Nexus OSS Blobstore'
});
new cdk.CfnOutput(this, 'nexus-oss-alb-domain', {
value: `${albAddress.value}`,
description: 'load balancer domain of Nexus OSS'
});

this.templateOptions.description = `(SO8020) - Sonatype Nexus OSS on AWS. Template version ${pjson.version}`;
this.templateOptions.description = `(SO8020) - Sonatype Nexus Repository OSS on AWS. Template version ${pjson.version}`;
}

/**
Expand Down
36 changes: 36 additions & 0 deletions test/sonatype-nexus3.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,42 @@ describe('Nexus OSS stack', () => {
});
});

test('deploy alb as interal.', () => {
const context = {
internalALB: true,
enableR53HostedZone: true,
};
({ app, stack } = initializeStackWithContextsAndEnvs(app, stack, context));

expect(stack).toCountResources('AWS::CertificateManager::Certificate', 0);

expect(stack).toHaveResourceLike('Custom::AWSCDK-EKS-HelmChart', {
"Release": "nexus3",
"Values": {
"Fn::Join": [
"",
[
"{\"statefulset\":{\"enabled\":true},\"initAdminPassword\":{\"enabled\":true,\"password\":\"",
{
"Ref": "NexusAdminInitPassword"
},
"\"},\"nexus\":{\"imageName\":\"",
{
"Fn::FindInMap": [
"PartitionMapping",
{
"Ref": "AWS::Partition"
},
"nexus"
]
},
"\",\"resources\":{\"requests\":{\"memory\":\"4800Mi\"}},\"livenessProbe\":{\"path\":\"/\"},\"nodeSelector\":{\"usage\":\"nexus3\"}},\"nexusProxy\":{\"enabled\":false},\"persistence\":{\"enabled\":true,\"storageClass\":\"efs-sc\",\"accessMode\":\"ReadWriteMany\"},\"nexusBackup\":{\"enabled\":false,\"persistence\":{\"enabled\":false}},\"nexusCloudiam\":{\"enabled\":false,\"persistence\":{\"enabled\":false}},\"ingress\":{\"enabled\":true,\"path\":\"/*\",\"annotations\":{\"alb.ingress.kubernetes.io/backend-protocol\":\"HTTP\",\"alb.ingress.kubernetes.io/healthcheck-path\":\"/\",\"alb.ingress.kubernetes.io/healthcheck-port\":8081,\"alb.ingress.kubernetes.io/listen-ports\":\"[{\\\"HTTP\\\": 80}]\",\"alb.ingress.kubernetes.io/scheme\":\"internal\",\"alb.ingress.kubernetes.io/inbound-cidrs\":\"10.58.0.0/16\",\"alb.ingress.kubernetes.io/auth-type\":\"none\",\"alb.ingress.kubernetes.io/target-type\":\"ip\",\"kubernetes.io/ingress.class\":\"alb\",\"alb.ingress.kubernetes.io/tags\":\"app=nexus3\",\"alb.ingress.kubernetes.io/subnets\":\"subnet-000f2b20b0ebaef37,subnet-0b2cce92f08506a9a,subnet-0571b340c9f28375c\"},\"tls\":{\"enabled\":false},\"rules\":[{\"http\":{\"paths\":[{\"path\":\"/*\",\"backend\":{\"serviceName\":\"nexus3-sonatype-nexus\",\"servicePort\":8081}}]}}]},\"serviceAccount\":{\"create\":false}}"
]
]
},
});
});

});

function initializeStackWithContextsAndEnvs(app: cdk.App, stack: cdk.Stack,
Expand Down

0 comments on commit 34f0882

Please sign in to comment.