-
Notifications
You must be signed in to change notification settings - Fork 5.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[RFC] [Scaffolder] Have a global environment context that is accessible by all templates #6632
Comments
Some updates: When I wrote the "Risks" section above, I already noticed that I actually don't really like my proposal. So we went with implementing Alternative 1 instead. We created a new More tricky is the idea of wrapping existing field-extensions since the return value of But something like the following would work: import { getComponentData } from '@backstage/core-plugin-api';
import {
createScaffolderFieldExtension,
EntityPickerFieldExtension,
FieldExtensionOptions,
scaffolderPlugin,
} from '@backstage/plugin-scaffolder';
import { FieldProps } from '@rjsf/core';
import { merge } from 'lodash';
import React from 'react';
export const CustomEntityPicker = ({
uiSchema,
...props
}: FieldProps<string>) => {
const componentData = getComponentData(
<EntityPickerFieldExtension />,
'scaffolder.extensions.field.v1',
) as FieldExtensionOptions;
if (componentData?.component) {
return (
<componentData.component
{...merge(
{
uiSchema: {
'ui:options': {
allowedKinds: ['API', 'Template'],
defaultKind: 'API',
},
},
},
props,
)}
/>
);
}
// TODO: some error!
return <></>;
};
export const CustomEntityPickerFieldExtension = scaffolderPlugin.provide(
createScaffolderFieldExtension({
component: CustomEntityPicker,
name: 'CustomEntityPicker',
}),
); Maybe we could think about improving the composability of |
I am not sure how I personally could not have seen this before. But just acknowledging it now, so it doesn't seem unattended to :) |
Let's close this. We are quite happy with our selected approach and don't think extra changes are needed if no one else runs into this particular problem. |
Status: Open for comments
Need
Have a common set of arguments that are provided to every template that is executed in a Backstage installation. These arguments are config driven, i.e. the values could differ between different Backstage installations (Company A, Company B, ...) or deployment stages (dev, staging, prod). This enables
Template
s that behave slightly different in each installation without the need to maintain multiple versions of it.This goes beyond providing a custom action (see Alternative 1) that provides outputs, because it would also be neat to access these properties in the
parameters
so they are part of the input form.Context
We provide Backstage to our company-internal developers. We also provide Backstage as part of a product where we prepare a cloud-based development environment (SCM, CI/CD, Kubernetes, ...) for our customers. Both use the Scaffolder to create new software for the respective (development) environments. In both use cases, we want to reuse the same templates so we ourselves but also our customers always use the most up-to-date and reliable template without too much maintenance overhead. However, while using the same technologies and tools, each environment slightly differs between each other: They have different GitHub organizations, different container registries, might not use all SAST tools, different secret names in the CI/CD environment, ….
Prior to the scaffolder, we started with a set of selectable presets in cookiecutter. But that had its' own organizational problems such as not wanting to share infrastructure details between customers.
A cookiecutter example
Instead, we would like to have the possibility of providing some kind of environment context to the Backstage instance that is available in each template:
A Scaffolder example
The context:
The scaffolder schema:
Proposal
export interface RouterOptions { logger: Logger; config: Config; reader: UrlReader; database: PluginDatabaseManager; catalogClient: CatalogApi; actions?: TemplateAction<any>[]; taskWorkers?: number; containerRunner: ContainerRunner; + templateEnvironmentContext?: Record<string, string>; }
Decide a handlebars variable name such as
{{ ctx.environment.<property-name> }}
.Provide the context as handlebars variable to the parameters schema:
Alternatives
Alternative 1: Custom Action
Skip templating the parameters-schema but provide the context as a custom action:
If an integrator wants to access the context in the UI, one could wrap a frontend field extension that automatically sets certain settings prior to executing the original field extension (example:
SdaOwnerPicker
vs.OwnerPicker
).Or we could write a custom express middleware for our instance, that hooks into the parameters-schema endpoint and post processes it before returning the response.
Alternative 2: New
apiVersion
Do a larger refactoring and move
parameters
into astep
:This could also allow user inputs after some actions have been executed. Examples are: manually trigger a deployment, wait for the merge of a PR, …
Risks
There settings are not part of the template and can't be validated. It is also not possible to document them somewhere. There is the
/actions
route that could show a list of these environment specific settings.Some company might want to use this feature to provide secrets via this new context. However, as they are also accessible in the parameters-schema, there is a risk of (accidentally) spoiling them to the frontend. This would be safer in e.g. Alternative 1 where settings for the frontend must be present as a config prop with
@visibility: frontend
.We would love to hear your thoughts on this topic 😃.
The text was updated successfully, but these errors were encountered: