Package: construct-hub
Construct HubThis project maintains aAWS Cloud Development Kitconstruct library
that can be used to deploy instances of the Construct Hub in any AWS Account.This software backs the public instance of theConstructHub, and can be used to deploy a self-hosted
instance with personalized configuration.:question: Getting Started:warning: DisclaimerThepublic instance of ConstructHubis Generally Available.Self-hosted ConstructHub instances are however in active development and
should be consideredexperimental. Breaking changes to the public API of
this package are expected to be released without prior notice, and the
infrastructure and operational posture of ConstructHub instances may also
significantly change.You are welcome to deploy self-hosted instances of ConstructHub for evaluation
purposes, and we welcome any feedback (good or bad) from your experience in
doing so.Quick StartOnce you have installed theconstruct-hublibrary in your project, the
simplest way to get started is to create an instance of theConstructHubconstruct:import{App,Stack}from'@aws-cdk/core';import{ConstructHub}from'construct-hub';//Theusual...youmighthaveused`cdkinitapp`instead!constapp=newApp();conststack=newStack(app,'StackName',{/*...*/});//Nowtobusiness!newConstructHub(stack,'ConstructHub');PersonalizationUsing a custom domain nameIn order to use a custom domain for your ConstructHub instance instead of the
default CloudFront domain name, specify thedomainproperty with the following
elements:AttributeDescriptionzoneA Route53 Hosted Zone, where DNS records will be added.certAn Amazon Certificate Manager certificate, which must be in theus-east-1region.monitorCertificateExpirationSet tofalseif you do not want an alarm to be created when the certificate is close to expiry.Your self-hosted ConstructHub instance will be served from the root of the
providedzone, so the certificate must match this name.Alternate package sourcesBy default, ConstructHub has a single package source configured: the publicnpmjs.comregistry. Self-hosted instances typically should list packages from
alternate sources, either in addition to packages fromnpmjs.com, or instead
of those.ThepackageSourcesproperty can be used to replace the default set of package
sources configured on the instance. ConstructHub providesIPackageSourceimplementations for the publicnpmjs.comregistry as well as for private
CodeArtifact repositories:import*ascodeartifactfrom'@aws-cdk/aws-codeartifact';import{App,Stack}from'@aws-cdk/core';import{sources,ConstructHub}from'construct-hub';//Theusual...youmighthaveused`cdkinitapp`instead!constapp=newApp();conststack=newStack(app,'StackName',{/*...*/});//Nowtobusiness!constregistry=newcodeartifact.CfnRegistry(stack,'Registry',{//....});newConstructHub(stack,'ConstructHub',{packageSources:[newsources.NpmJs(),//RemoveifyoudoNOTwantnpmjs.compackagesnewsources.CodeArtifact({registry}),],});You may also implement a customIPackageSourceif you want to index packages
from alternate locations. In this case, the component you provide will be
responsible for sending notifications to an SQS Queue about newly discovered
packages. You may refer to thesources.NpmJsandsources.CodeArtifactimplementations as a reference for hos this can be done.By default, download counts of NPM packages will be fetched periodically from
NPM's public API by a Lambda. Since this is not desirable if you are using a
private package registry, this is automatically disabled if you specify your own
value forpackageSources. (But this can be re-enabled through thefetchPackageStatsproperty if needed).Package deny listCertain packages may be undesirable to show in your self-hosted ConstructHub
instance. In order to prevent a package from ever being listed in construct hub,
thedenyListproperty can be configured with a set ofDenyListRuleobjects
that specify which package or package versions should never be lested:import{App,Stack}from'@aws-cdk/core';import{ConstructHub}from'construct-hub';//Theusual...youmighthaveused`cdkinitapp`instead!constapp=newApp();conststack=newStack(app,'StackName',{/*...*/});//Nowtobusiness!newConstructHub(stack,'ConstructHub',{denyList:[//Denying_all_versionsofthe"sneaky-hackery"package{packageName:'sneaky-hackery',reason:'Mines bitcoins wherever it gets installed'},//Denying_aspecific_versionofthe"bad-release"package{packageName:'bad-release',version:'1.2.3',reason:'CVE-####-#####'},],});Redirecting from additional domainsYou can add additional domains that will be redirected to your primary Construct
Hub domain:import*asr53from'@aws-cdk/aws-route53';constmyDomainZone=r53.HostedZone.fromHostedZoneAttributes(this,'MyDomainZone',{hostedZoneId:'AZ1234',zoneName:'my.domain.com',});newConstructHub(this,'ConstructHub',{additionalDomains:[{hostedZone:myDomainZone}]});This will set up full domain redirect using Amazon S3 and Amazon CloudFront. All
requests will be redirected to your primary Construct Hub domain.Decrease deployment footprintBy default, ConstructHub executes the documentation rendering process in the
context of isolated subnets. This is a defense-in-depth mechanism to mitigate
the risks associated with downloading aribtrary (un-trusted)npm packagesand
their dependency closures.This layer of security implies the creation of a number of resources that can
increase the operating cost of your self-hosted instance: several VPC endpoints
are created, an internal CodeArtifact repository needs to be provisioned, etc...While we generally recommend leaving these features enabled, if your self-hosted
ConstructHub instance only indexestrustedpackages (as could be the case for
an instance that does not list packages from the publicnpmjs.comregistry),
you may set theisolateLambdassetting tofalse.:gear: Operating a self-hosted instanceApplication Overviewprovides a high-level
description of the components that make a ConstructHub instance. This is a
great starting point for people who consider operating a self-hosted instance
of ConstructHub; and for new operators on-boarding the platform.Operator Runbookis a series of diagnostics and
troubleshooting guides indended for operators to have a quick and easy way to
navigate a ConstructHub instance when they are reacting to an alarm or bug
report.:baby_chick: Deployment CanariesConstruct Hub provides several built-in validation mechanisms to make sure the
deployment of your instance is continuously operating as expected.These mechanisms come in the form of canary testers that are part of the
ConstructHub deployment stack. Each canary runs periodically and performs a
different check, triggering a different CloudWatch alarm in case it detects a
failure.We recommend that you use staged deployments, and block promotions to the
production stage in case any preivous stage triggers an alarm within a specific
timeframe.Discovery CanaryWhen configuring anNpmJspackage source, a package discovery canary can be
enabled using theenableCanaryproperty (and optionally configured using thecanaryPackageandcanarySlaproperties). This feature is activated by
default and monitors availability of releases of theconstruct-hub-probenpm
package in the ConstructHub instance.Probe packages, such asconstruct-hub-probeare published frequently (e.g:
every 3 hours or more frequently), and can be used to ensure the ConstructHub
instance correctly discovers, indexes and represents those packages.If a different package or SLA should be used, you can configure theNpmJspackage source manually like so:import*ascodeartifactfrom'@aws-cdk/aws-codeartifact';import{App,Stack}from'@aws-cdk/core';import{sources,ConstructHub}from'construct-hub';constapp=newApp();conststack=newStack(app,'StackName',{/*...*/});newConstructHub(stack,'ConstructHub',{//...packageSources:[//...newsources.NpmJs({enableCanary:true,//ThisisthedefaultcanaryPackage:'@acme/my-constructhub-probe',canarySla:Duration.minutes(30),}),//...],//...});In case the new package isn't fully available in the predefined SLA, ahigh severityCloudWatch alarm will trigger, which will in turn trigger
the configured action for low severity alarms.SeeMonitoring & AlarmsThe operator runbook containsinstructionson how
to diagnose and mitigate the root cause of the failure.:nail_care: Customizing the frontendThere are a number of customizations available in order to make your private
construct hub better tailored to your organization.Package TagsConfiguring package tags allows you to compute additional labels to be applied
to packages. These can be used to indicate to users which packages are owned by
trusted organizations, or any other arbitrary conditions, and can be referenced
while searching.For example:newConstructHub(this,"ConstructHub",{...myProps,packageTags:[{id:'official',condition:TagCondition.field('name').eq('construct-hub'),keyword:{label:'Official',color:'#00FF00',},highlight:{label:'Vended by AWS',color:'#00FF00',}}]});The above example will result in packages with thenameofconstruct-hubto
receive theOfficialtag, which is colored green and displayed amongst the
list of keywords. Additionally thehighlightkey shows this as a highlighted
item on the package's card.ThesearchFilterkey can also be used to show tags as search filters grouped
together.constauthorsGroup=newPackageTagGroup("authors",{label:"Authors",tooltip:"Information about the authors filter",filterType:FilterType.checkbox(),});constisAws=TagCondition.field('name').eq('construct-hub');newConstructHub(this,"ConstructHub",{...myProps,packageTags:[{id:'AWS',condition:isAws,searchFilter:{group:authorsGroup,display:'AWS',},},{id:'Community',condition:TagCondition.not(isAws),searchFilter:{group:authorsGroup,display:'AWS',},}]});The above will show a list ofAuthorsfilters on the search results page
with a checkbox for eachAWSandCommunitypackages, allowing users to
filter results by the presence of these tags.Combinations of conditions are also supported:newConstructHub(this,"ConstructHub",{...myProps,packageTags:[{label:'Official',color:'#00FF00',condition:TagCondition.or(TagCondition.field('name').eq('construct-hub'),TagCondition.field('name').eq('construct-hub-webapp'),),}]});//ormoresuccintlyifyouhavealonglistcondition:TagCondition.or(...['construct-hub','construct-hub-webapp','...',].map(name=>TagCondition.field('name').eq(name))),You can assert against any value within package json including nested ones.TagCondition.field('constructHub','nested','key').eq('value');//checkspackageJson?.constructHub?.nested?.key===value;You can also assert that a string occurs at least a certain number of times
within the package's README.TagCondition.readme().includes('ECS');TagCondition.readme().includes('fargate',{atLeast:3,caseSensitive:false});Package LinksConfiguring package links allows you to replace theRepository,License,
andRegistrylinks on the package details page with whatever you choose.For example:newConstructHub(this,"ConstructHub",{...myProps,packageLinks:[{linkLabel:'Service Level Agreement',configKey:'SLA',},{linkLabel:'Contact',configKey:'Contact',linkText:'Email Me!',allowedDomains:['me.com'],}]});This would allow publishers to add the following to their package.json:"constructHub":{"packageLinks":{"SLA":"https://support.mypackage.com","Contact":"me.com/contact"}}Then the links on the corresponding package page would show these items as
configured.Home PageThe home page is divided into sections, each with a header and list of packages.
Currently, for a given section you can display either the most recently updated
packages, or a curated list of packages.For example:newConstructHub(this,"ConstructHub",{...myProps,featuredPackages:{sections:[{name:"Recently updated",showLastUpdated:4},{name:"From the AWS CDK",showPackages:[{name:"@aws-cdk/core"},{name:"@aws-cdk/aws-s3",comment:"One of the most popular AWS CDK libraries!"},{name:"@aws-cdk/aws-lambda"},{name:"@aws-cdk/pipelines"comment:"The pipelines L3 construct library abstracts away many of the details of managing software deployment within AWS."}]}]}});Browse CategoriesThe Construct Hub home page includes a section that displays a set of buttons
that represent browsing categories (e.g. "Databases", "Monitoring",
"Serverless", etc).You can use thecategoriesoption to configure these categories. Each category
is defined by atitleand aurl, which will be the link associated with the
button.newConstructHub(this,"ConstructHub",{...myProps,categories:[{title:'Databases',url:'?keywords=databases'},{title:'Monitoring',url:'?q=monitoring'},{title:'Partners',url:'?tags=aws-partner'}]});Feature FlagsFeature flags for the web app can be used to enable or disable experimental
features. These can be customized through thefeatureFlagsproperty - for
more information about the available flags, check the documentation forhttps://github.com/cdklabs/construct-hub-webapp/.:raised_hand: ContributingIf you are looking to contribute to this project, but don't know where to start,
have a look at ourcontributing guide!:cop: SecuritySeeCONTRIBUTINGfor more
information.:balance_scale: LicenseThis project is licensed under the Apache-2.0 License.