diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..5b5bd99 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,3 @@ +{ + "proseWrap": "always" +} diff --git a/README.md b/README.md index a254bdb..96b22d3 100644 --- a/README.md +++ b/README.md @@ -3,28 +3,54 @@ [![Build Status][azure-devops-build-status]][azure-devops-build-link] [![Go Report Card][go-report-card-badge]][go-report-card] -Fabrikate helps make operating Kubernetes clusters with a [GitOps](https://www.weave.works/blog/gitops-operations-by-pull-request) workflow more productive. It allows you to write [DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself) resource definitions and configuration for multiple environments while leveraging the broad [Helm chart ecosystem](https://github.com/helm/charts), capture higher level definitions into abstracted and shareable components, and enable a [GitOps](https://www.weave.works/blog/gitops-operations-by-pull-request) deployment workflow that both simplifies and makes deployments more auditable. +Fabrikate helps make operating Kubernetes clusters with a +[GitOps](https://www.weave.works/blog/gitops-operations-by-pull-request) +workflow more productive. It allows you to write +[DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself) resource +definitions and configuration for multiple environments while leveraging the +broad [Helm chart ecosystem](https://github.com/helm/charts), capture higher +level definitions into abstracted and shareable components, and enable a +[GitOps](https://www.weave.works/blog/gitops-operations-by-pull-request) +deployment workflow that both simplifies and makes deployments more auditable. -In particular, Fabrikate simplifies the frontend of the GitOps workflow: it takes a high level description of your deployment, a target environment configuration (eg. `qa` or `prod`), and renders the Kubernetes resource manifests for that deployment utilizing templating tools like [Helm](https://helm.sh). It is intended to run as part of a CI/CD pipeline such that with every commit to your Fabrikate deployment definition triggers the generation of Kubernetes resource manifests that an in-cluster GitOps pod like [Weaveworks' Flux](https://github.com/weaveworks/flux) watches and reconciles with the current set of applied resource manifests in your Kubernetes cluster. +In particular, Fabrikate simplifies the frontend of the GitOps workflow: it +takes a high level description of your deployment, a target environment +configuration (eg. `qa` or `prod`), and renders the Kubernetes resource +manifests for that deployment utilizing templating tools like +[Helm](https://helm.sh). It is intended to run as part of a CI/CD pipeline such +that with every commit to your Fabrikate deployment definition triggers the +generation of Kubernetes resource manifests that an in-cluster GitOps pod like +[Weaveworks' Flux](https://github.com/weaveworks/flux) watches and reconciles +with the current set of applied resource manifests in your Kubernetes cluster. ## Getting Started -First, install the latest `fab` cli on your local machine from [our releases](https://github.com/microsoft/fabrikate/releases), unzipping the appropriate binary and placing `fab` in your path. The `fab` cli tool, `helm`, and `git` are the only tools you need to have installed. +First, install the latest `fab` cli on your local machine from +[our releases](https://github.com/microsoft/fabrikate/releases), unzipping the +appropriate binary and placing `fab` in your path. The `fab` cli tool, `helm`, +and `git` are the only tools you need to have installed. -Let's walk through building an example Fabrikate definition to see how it works in practice. First off, let's create a directory for our cluster definition: +Let's walk through building an example Fabrikate definition to see how it works +in practice. First off, let's create a directory for our cluster definition: ```sh $ mkdir mycluster $ cd mycluster ``` -The first thing I want to do is pull in a common set of observability and service mesh platforms so I can operate this cluster. My organization has settled on a [cloud-native](https://github.com/microsoft/fabrikate-definitions/tree/master/definitions/fabrikate-cloud-native) stack, and Fabrikate makes it easy to leverage reusable stacks of infrastructure like this: +The first thing I want to do is pull in a common set of observability and +service mesh platforms so I can operate this cluster. My organization has +settled on a +[cloud-native](https://github.com/microsoft/fabrikate-definitions/tree/master/definitions/fabrikate-cloud-native) +stack, and Fabrikate makes it easy to leverage reusable stacks of infrastructure +like this: ```sh $ fab add cloud-native --source https://github.com/microsoft/fabrikate-definitions --path definitions/fabrikate-cloud-native ``` -Since our directory was empty, this creates a component.yaml file in this directory: +Since our directory was empty, this creates a component.yaml file in this +directory: ```yaml name: mycluster @@ -37,11 +63,18 @@ subcomponents: branch: master ``` -A Fabrikate definition, like this one, always contains a `component.yaml` file in its root that defines how to generate the Kubernetes resource manifests for its directory tree scope. +A Fabrikate definition, like this one, always contains a `component.yaml` file +in its root that defines how to generate the Kubernetes resource manifests for +its directory tree scope. -The `cloud-native` component we added is a remote component backed by a git repo [fabrikate-cloud-native](https://github.com/microsoft/fabrikate-definitions/tree/master/definitions/fabrikate-cloud-native). Fabrikate definitions use remote definitions like this one to enable multiple deployments to reuse common components (like this cloud-native infrastructure stack) from a centrally updated location. +The `cloud-native` component we added is a remote component backed by a git repo +[fabrikate-cloud-native](https://github.com/microsoft/fabrikate-definitions/tree/master/definitions/fabrikate-cloud-native). +Fabrikate definitions use remote definitions like this one to enable multiple +deployments to reuse common components (like this cloud-native infrastructure +stack) from a centrally updated location. -Looking inside this component at its own root `component.yaml` definition, you can see that it itself uses a set of remote components: +Looking inside this component at its own root `component.yaml` definition, you +can see that it itself uses a set of remote components: ```yaml name: "cloud-native" @@ -58,9 +91,14 @@ subcomponents: source: "../fabrikate-kured" ``` -Fabrikate recursively iterates component definitions, so as it processes this lower level component definition, it will in turn iterate the remote component definitions used in its implementation. Being able to mix in remote components like this makes Fabrikate deployments composable and reusable across deployments. +Fabrikate recursively iterates component definitions, so as it processes this +lower level component definition, it will in turn iterate the remote component +definitions used in its implementation. Being able to mix in remote components +like this makes Fabrikate deployments composable and reusable across +deployments. -Let's look at the component definition for the [elasticsearch-fluentd-kibana component](https://github.com/microsoft/fabrikate-definitions/tree/master/definitions/fabrikate-elasticsearch-fluentd-kibana): +Let's look at the component definition for the +[elasticsearch-fluentd-kibana component](https://github.com/microsoft/fabrikate-definitions/tree/master/definitions/fabrikate-elasticsearch-fluentd-kibana): ```json { @@ -100,11 +138,21 @@ Let's look at the component definition for the [elasticsearch-fluentd-kibana com } ``` -First, we see that components can be defined in JSON as well as YAML (as you prefer). +First, we see that components can be defined in JSON as well as YAML (as you +prefer). -Secondly, we see that that this component generates resource definitions. In particular, it will emit a set of static manifests from the path `./manifests`, and generate the set of resource manifests specified by the inlined [Helm templates](https://helm.sh/) definitions as it it iterates your deployment definitions. +Secondly, we see that that this component generates resource definitions. In +particular, it will emit a set of static manifests from the path `./manifests`, +and generate the set of resource manifests specified by the inlined +[Helm templates](https://helm.sh/) definitions as it it iterates your deployment +definitions. -With generalized helm charts like the ones used here, its often necessary to provide them with configuration values that vary by environment. This component provides a reasonable set of defaults for its subcomponents in `config/common.yaml`. Since this component is providing these four logging subsystems together as a "stack", or preconfigured whole, we can provide configuration to higher level parts based on this knowledge: +With generalized helm charts like the ones used here, its often necessary to +provide them with configuration values that vary by environment. This component +provides a reasonable set of defaults for its subcomponents in +`config/common.yaml`. Since this component is providing these four logging +subsystems together as a "stack", or preconfigured whole, we can provide +configuration to higher level parts based on this knowledge: ```yaml config: @@ -146,7 +194,12 @@ subcomponents: elasticsearch.url: "http://elasticsearch-client.elasticsearch.svc.cluster.local:9200" ``` -This `common` configuration, which applies to all environments, can be mixed with more specific configuration. For example, let's say that we were deploying this in Azure and wanted to utilize its `managed-premium` SSD storage class for Elasticsearch, but only in `azure` deployments. We can build an `azure` configuration that allows us to do exactly that, and Fabrikate has a convenience function called `set` that enables to do exactly that: +This `common` configuration, which applies to all environments, can be mixed +with more specific configuration. For example, let's say that we were deploying +this in Azure and wanted to utilize its `managed-premium` SSD storage class for +Elasticsearch, but only in `azure` deployments. We can build an `azure` +configuration that allows us to do exactly that, and Fabrikate has a convenience +function called `set` that enables to do exactly that: ``` $ fab set --environment azure --subcomponent cloud-native.elasticsearch data.persistence.storageClass="managed-premium" master.persistence.storageClass="managed-premium" @@ -168,15 +221,23 @@ subcomponents: storageClass: managed-premium ``` -Naturally, an observability stack is just the base infrastructure we need, and our real goal is to deploy a set of microservices. Furthermore, let's assume that we want to be able to split the incoming traffic for these services between `canary` and `stable` tiers with [Istio](https://istio.io) so that we can more safely launch new versions of the service. +Naturally, an observability stack is just the base infrastructure we need, and +our real goal is to deploy a set of microservices. Furthermore, let's assume +that we want to be able to split the incoming traffic for these services between +`canary` and `stable` tiers with [Istio](https://istio.io) so that we can more +safely launch new versions of the service. -There is a Fabrikate component for that as well called [fabrikate-istio-service](https://github.com/microsoft/fabrikate-definitions/tree/master/definitions/fabrikate-istio) that we'll leverage to add this service, so let's do just that: +There is a Fabrikate component for that as well called +[fabrikate-istio-service](https://github.com/microsoft/fabrikate-definitions/tree/master/definitions/fabrikate-istio) +that we'll leverage to add this service, so let's do just that: ``` $ fab add simple-service --source https://github.com/microsoft/fabrikate-definitions --path definitions/fabrikate-istio ``` -This component creates these traffic split services using the config applied to it. Let's create a `prod` config that does this for a `prod` cluster by creating `config/prod.yaml` and placing the following in it: +This component creates these traffic split services using the config applied to +it. Let's create a `prod` config that does this for a `prod` cluster by creating +`config/prod.yaml` and placing the following in it: ```yaml subcomponents: @@ -218,11 +279,20 @@ subcomponents: memory: "512Mi" ``` -This defines a service that is exposed on the cluster via a particular gateway and dns name and port. It also defines a traffic split between two backend tiers: `canary` (10%) and `stable` (90%). Within these tiers, we also define the number of replicas and the resources they are allowed to use, along with the container that is deployed in them. Finally, it also defines a ConfigMap for the service, which passes along an environmental variable to our app called `PORT`. +This defines a service that is exposed on the cluster via a particular gateway +and dns name and port. It also defines a traffic split between two backend +tiers: `canary` (10%) and `stable` (90%). Within these tiers, we also define the +number of replicas and the resources they are allowed to use, along with the +container that is deployed in them. Finally, it also defines a ConfigMap for the +service, which passes along an environmental variable to our app called `PORT`. -From here we could add definitions for all of our microservices in a similar manner, but in the interest of keeping this short, we'll just do one of the services here. +From here we could add definitions for all of our microservices in a similar +manner, but in the interest of keeping this short, we'll just do one of the +services here. -With this, we have a functionally complete Fabrikate definition for our deployment. Let's now see how we can use Fabrikate to generate resource manifests for it. +With this, we have a functionally complete Fabrikate definition for our +deployment. Let's now see how we can use Fabrikate to generate resource +manifests for it. First, let's install the remote components and helm charts: @@ -230,26 +300,39 @@ First, let's install the remote components and helm charts: $ fab install ``` -This installs all of the required components and charts locally and we can now generate the manifests for our deployment with: +This installs all of the required components and charts locally and we can now +generate the manifests for our deployment with: ```sh $ fab generate prod azure ``` -This will iterate through our deployment definition, collect configuration values from `azure`, `prod`, and `common` (in that priority order) and generate manifests as it descends breadth first. You can see the generated manifests in `./generated/prod-azure`, which has the same logical directory structure as your deployment definition. +This will iterate through our deployment definition, collect configuration +values from `azure`, `prod`, and `common` (in that priority order) and generate +manifests as it descends breadth first. You can see the generated manifests in +`./generated/prod-azure`, which has the same logical directory structure as your +deployment definition. -Fabrikate is meant to used as part of a CI / CD pipeline that commits the generated manifests checked into a repo so that they can be applied from a pod within the cluster like [Flux](https://github.com/weaveworks/flux), but if you have a Kubernetes cluster up and running you can also apply them directly with: +Fabrikate is meant to used as part of a CI / CD pipeline that commits the +generated manifests checked into a repo so that they can be applied from a pod +within the cluster like [Flux](https://github.com/weaveworks/flux), but if you +have a Kubernetes cluster up and running you can also apply them directly with: ```sh $ cd generated/prod-azure $ kubectl apply --recursive -f . ``` -This will cause a very large number of containers to spin up (which will take time to start completely as Kubernetes provisions persistent storage and downloads the containers themselves), but after three or four minutes, you should see the full observability stack and Microservices running in your cluster. +This will cause a very large number of containers to spin up (which will take +time to start completely as Kubernetes provisions persistent storage and +downloads the containers themselves), but after three or four minutes, you +should see the full observability stack and Microservices running in your +cluster. ## Documentation -We have complete details about how to use and contribute to Fabrikate in these documentation items: +We have complete details about how to use and contribute to Fabrikate in these +documentation items: - [Component Definitions](./docs/component.md) - [Config Definitions](./docs/config.md) @@ -259,15 +342,26 @@ We have complete details about how to use and contribute to Fabrikate in these d ## Community -[Please join us on Slack](https://join.slack.com/t/bedrockco/shared_invite/enQtNjIwNzg3NTU0MDgzLTdiZGY4ZTM5OTM4MWEyM2FlZDA5MmE0MmNhNTQ2MGMxYTY2NGYxMTVlZWFmODVmODJlOWU0Y2U2YmM1YTE0NGI) for discussion and/or questions. +[Please join us on Slack](https://join.slack.com/t/bedrockco/shared_invite/enQtNjIwNzg3NTU0MDgzLTdiZGY4ZTM5OTM4MWEyM2FlZDA5MmE0MmNhNTQ2MGMxYTY2NGYxMTVlZWFmODVmODJlOWU0Y2U2YmM1YTE0NGI) +for discussion and/or questions. ## Bedrock -We maintain a sister project called [Bedrock](https://github.com/microsoft/bedrock). Bedrock provides automata that make operationalizing Kubernetes clusters with a GitOps deployment workflow easier, automating a [GitOps](https://www.weave.works/blog/gitops-operations-by-pull-request) deployment model leveraging [Flux](https://github.com/weaveworks/flux), and provides automation for building a CI/CD pipeline that automatically builds resource manifests from Fabrikate defintions. +We maintain a sister project called +[Bedrock](https://github.com/microsoft/bedrock). Bedrock provides automata that +make operationalizing Kubernetes clusters with a GitOps deployment workflow +easier, automating a +[GitOps](https://www.weave.works/blog/gitops-operations-by-pull-request) +deployment model leveraging [Flux](https://github.com/weaveworks/flux), and +provides automation for building a CI/CD pipeline that automatically builds +resource manifests from Fabrikate defintions. -[azure-devops-build-status]: https://tpark.visualstudio.com/fabrikate/_apis/build/status/microsoft.fabrikate?branchName=master -[azure-devops-build-link]: https://tpark.visualstudio.com/fabrikate/_build/latest?definitionId=35&branchName=master +[azure-devops-build-status]: + https://tpark.visualstudio.com/fabrikate/_apis/build/status/microsoft.fabrikate?branchName=master +[azure-devops-build-link]: + https://tpark.visualstudio.com/fabrikate/_build/latest?definitionId=35&branchName=master [go-report-card]: https://goreportcard.com/report/github.com/microsoft/fabrikate -[go-report-card-badge]: https://goreportcard.com/badge/github.com/microsoft/fabrikate +[go-report-card-badge]: + https://goreportcard.com/badge/github.com/microsoft/fabrikate diff --git a/docs/auth.md b/docs/auth.md index bf05718..59c1caf 100644 --- a/docs/auth.md +++ b/docs/auth.md @@ -63,4 +63,5 @@ run `fab install` and look at the warning logs to see which components are asking for which variables and tokens (missing env vars will be logged as warnings during install). -[tokens]: https://help.github.com/en/articles/creating-a-personal-access-token-for-the-command-line +[tokens]: + https://help.github.com/en/articles/creating-a-personal-access-token-for-the-command-line diff --git a/docs/commands.md b/docs/commands.md index a77e7df..b1de38e 100644 --- a/docs/commands.md +++ b/docs/commands.md @@ -2,7 +2,8 @@ ## add -Adds a subcomponent to the current component (or the component specified by the passed path). +Adds a subcomponent to the current component (or the component specified by the +passed path). ### Usage @@ -12,10 +13,14 @@ $ fab add --source [--type component] [--met Where: -- `source` specifies where the component lives (either a local path or remote http(s) endpoint) -- `type` specifies the type of component (`component` (default), `helm`, or `static`) -- `method` specifies the method that should be used to fetch the component (`git` (default)) -- `path` specifies the path to the component that this subcomponent should be added to. +- `source` specifies where the component lives (either a local path or remote + http(s) endpoint) +- `type` specifies the type of component (`component` (default), `helm`, or + `static`) +- `method` specifies the method that should be used to fetch the component + (`git` (default)) +- `path` specifies the path to the component that this subcomponent should be + added to. ### Example @@ -25,7 +30,8 @@ $ fab add cloud-native --source https://github.com/timfpark/fabrikate-cloud-nati ## generate -Generates Kubernetes resource definitions from deployment definition in the current subtree. +Generates Kubernetes resource definitions from deployment definition in the +current subtree. ### Usage @@ -33,11 +39,13 @@ Generates Kubernetes resource definitions from deployment definition in the curr $ fab generate ... ``` -Where the generate command takes a list of the configurations that should be used to generate the resource -definitions for the deployment. These configurations should be specified in priority order. For example, -if you specified `prod azure east`, `prod`'s config would be applied first, and `azure`'s config -would only be applied if they did not conflict with `prod`. Likewise, `east`'s config would only be applied -if it did not conflict with `prod` or `azure`. +Where the generate command takes a list of the configurations that should be +used to generate the resource definitions for the deployment. These +configurations should be specified in priority order. For example, if you +specified `prod azure east`, `prod`'s config would be applied first, and +`azure`'s config would only be applied if they did not conflict with `prod`. +Likewise, `east`'s config would only be applied if it did not conflict with +`prod` or `azure`. ### Example @@ -47,9 +55,10 @@ $ fab generate prod azure east ## install -Installs all of the remote components specified in the current deployment tree locally, iterating the -component subtree from the current directory to do so. Required to be executed before generate (if needed), such -that Fabrikate has all of the dependencies locally to use to generate the resource manifests. +Installs all of the remote components specified in the current deployment tree +locally, iterating the component subtree from the current directory to do so. +Required to be executed before generate (if needed), such that Fabrikate has all +of the dependencies locally to use to generate the resource manifests. #### Example @@ -75,7 +84,8 @@ $ fab remove cloud-native ## set -Sets a config value for a component for a particular config environment in the Fabrikate definition. +Sets a config value for a component for a particular config environment in the +Fabrikate definition. ### Usage @@ -89,19 +99,24 @@ $ fab set --environment [--subcomponent ] [--file `. - - if `method: helm`: Tells fabrikate to `helm fetch ` from the `source` helm repo. - - if `method: local`: Tells fabrikate to use the host filesystem as a means to find the component. + - if `method: helm`: Tells fabrikate to `helm fetch ` from the `source` + helm repo. + - if `method: local`: Tells fabrikate to use the host filesystem as a means to + find the component. - `source`: The source for this component. - - if `method: git`: A URL for a Git repository (the url you would call `git clone` on). - - if `method: helm`: A URL to a helm repository (the url you would call `helm repo add` on). + - if `method: git`: A URL for a Git repository (the url you would call + `git clone` on). + - if `method: helm`: A URL to a helm repository (the url you would call + `helm repo add` on). - if `method: local`: A local path to specify a local filesystem component. -- `path`: For some components, like ones generated with `helm`, the desired target of the component might not be located at the root of the repo. Path enables you to specify the relative `path` to this target from the root of the `source`. +- `path`: For some components, like ones generated with `helm`, the desired + target of the component might not be located at the root of the repo. Path + enables you to specify the relative `path` to this target from the root of the + `source`. - - if `method: git`: the subdirectory of the component in the git repo specified in `source`. - - if `method: helm`: the name of the chart to install the repo specified in `source`. - - if `method: local`: the subdirectory on host filesystem where the component is located. + - if `method: git`: the subdirectory of the component in the git repo + specified in `source`. + - if `method: helm`: the name of the chart to install the repo specified in + `source`. + - if `method: local`: the subdirectory on host filesystem where the component + is located. -- `version`: For git `method` components, this specifies a specific commit SHA hash that the component should be locked to, enabling you to lock the component to a consistent version. +- `version`: For git `method` components, this specifies a specific commit SHA + hash that the component should be locked to, enabling you to lock the + component to a consistent version. - if `method: git`: a specific commit to checkout from the repository. - if `method: helm`: noop - if `method: local`: noop -- `branch`: For git `method` components, this specifies the branch that should be checked out after the git `source` is cloned. +- `branch`: For git `method` components, this specifies the branch that should + be checked out after the git `source` is cloned. - if `method: git`: a specific branch to checkout from the repository. - if `method: helm`: noop - if `method: local`: noop -- `hooks`: Hooks enable you to execute one or more shell commands before or after the following component lifecycle events: `before-install`, `before-generate`, `after-install`, `after-generate`. +- `hooks`: Hooks enable you to execute one or more shell commands before or + after the following component lifecycle events: `before-install`, + `before-generate`, `after-install`, `after-generate`. -- `subcomponents`: Zero or more subcomponents that define how to build the resource manifests that make up this component. These subcomponents are components themselves and have exactly the same schema as above. +- `subcomponents`: Zero or more subcomponents that define how to build the + resource manifests that make up this component. These subcomponents are + components themselves and have exactly the same schema as above. ## Examples @@ -79,7 +105,9 @@ subcomponents: ### Istio -This [component specification](https://github.com/evanlouie/fabrikate-istio) utilizes hooks to download and unpack an Istio release and then reference it with a local path. +This [component specification](https://github.com/evanlouie/fabrikate-istio) +utilizes hooks to download and unpack an Istio release and then reference it +with a local path. ```yaml name: istio @@ -87,7 +115,9 @@ generator: helm path: "./tmp/istio-1.1.2/install/kubernetes/helm/istio" hooks: before-install: - - curl -Lv https://github.com/istio/istio/releases/download/1.1.2/istio-1.1.2-linux.tar.gz -o istio.tar.gz + - curl -Lv + https://github.com/istio/istio/releases/download/1.1.2/istio-1.1.2-linux.tar.gz + -o istio.tar.gz - mkdir -p tmp - tar xvf istio.tar.gz -C tmp after-install: @@ -103,7 +133,9 @@ subcomponents: ### Jaeger -This [component specification](https://github.com/bnookala/fabrikate-jaeger) is specified in JSON and utilizes the `method: helm` feature to `helm fetch` the jaeger chart from the incubator helm repo. +This [component specification](https://github.com/bnookala/fabrikate-jaeger) is +specified in JSON and utilizes the `method: helm` feature to `helm fetch` the +jaeger chart from the incubator helm repo. ```json { diff --git a/docs/config.md b/docs/config.md index 24e32eb..f7ed814 100644 --- a/docs/config.md +++ b/docs/config.md @@ -1,25 +1,58 @@ # Config Definitions -Configuration files in Fabrikate allow you to define the structure of your deployment once via [components](./component.md) while enabling elements of it to vary across different environments like QA, staging, and production or across on-prem and a public cloud -- or both. +Configuration files in Fabrikate allow you to define the structure of your +deployment once via [components](./component.md) while enabling elements of it +to vary across different environments like QA, staging, and production or across +on-prem and a public cloud -- or both. -By convention, configuration is placed into a directory called `config` with the name of the environment that it applies to. Also by convention, if a `common.yaml` (or `common.json`) config definition exists, it is applied globally as config. +By convention, configuration is placed into a directory called `config` with the +name of the environment that it applies to. Also by convention, if a +`common.yaml` (or `common.json`) config definition exists, it is applied +globally as config. The schema for these config definitions is fairly simple: -- `config`: A set of configuration values for the component in the parent directory that is intended to be used in conjunction with a generator. For example, with a Helm generator, these configuration values will be applied through a `values.yaml` file to the helm template specified. +- `config`: A set of configuration values for the component in the parent + directory that is intended to be used in conjunction with a generator. For + example, with a Helm generator, these configuration values will be applied + through a `values.yaml` file to the helm template specified. - `namespace`: The namespace that should be applied for this component. -- `injectNamespace`: Directs Fabrikate to inject the specified namespace into every resource manifest generated for this component. This is intended for generators that don't support applying namespaces or where the template for the generator doesn't parameterize the namespace such that it is user accessible. -- `subcomponents`: A set of key/value pairs for the subcomponents of this component that specify the configuration for those components. Each of the values of these keys is a config definition in its own right and has the same schema as this config definition. +- `injectNamespace`: Directs Fabrikate to inject the specified namespace into + every resource manifest generated for this component. This is intended for + generators that don't support applying namespaces or where the template for + the generator doesn't parameterize the namespace such that it is user + accessible. +- `subcomponents`: A set of key/value pairs for the subcomponents of this + component that specify the configuration for those components. Each of the + values of these keys is a config definition in its own right and has the same + schema as this config definition. -Configuration in Fabrikate is collected from the top of the hierarchy down, meaning if a config definition lower in the hierarchy specifies a value for a key of configuration that has been already collected, the configuration provided higher in the hierarchy wins out. The reasoning behind this is because configuration higher in the hierarchy has a higher level of context over how the portions of the deployment definition should work with each other. +Configuration in Fabrikate is collected from the top of the hierarchy down, +meaning if a config definition lower in the hierarchy specifies a value for a +key of configuration that has been already collected, the configuration provided +higher in the hierarchy wins out. The reasoning behind this is because +configuration higher in the hierarchy has a higher level of context over how the +portions of the deployment definition should work with each other. -Configuration can (and is encouraged to be) factored out into its individual concerns. For example, to compose a set of resource manifests for a Production environment in East US in Azure, you might factor your configuration into `prod`, `east`, and `azure` configuration files such that when you need to build a Production environment in West US, you can simply swap out the `east` config for a `west` config. +Configuration can (and is encouraged to be) factored out into its individual +concerns. For example, to compose a set of resource manifests for a Production +environment in East US in Azure, you might factor your configuration into +`prod`, `east`, and `azure` configuration files such that when you need to build +a Production environment in West US, you can simply swap out the `east` config +for a `west` config. ## Examples ### Jaeger -In this [config definition](https://github.com/bnookala/fabrikate-jaeger/blob/master/config/common.yaml), configuration is applied to the subcomponent `jaeger` for `collector.annotations.sidecar.istio.io/inject` with the value `false` which will be passed to the helm `values.yaml` file that is applied to this helm chart. The namespace `jaeger` is also injected into the namespace for every resource manifest generated as the helm chart templates written for Jaeger were not parameterized to inject a namespace. +In this +[config definition](https://github.com/bnookala/fabrikate-jaeger/blob/master/config/common.yaml), +configuration is applied to the subcomponent `jaeger` for +`collector.annotations.sidecar.istio.io/inject` with the value `false` which +will be passed to the helm `values.yaml` file that is applied to this helm +chart. The namespace `jaeger` is also injected into the namespace for every +resource manifest generated as the helm chart templates written for Jaeger were +not parameterized to inject a namespace. ```yaml config: @@ -35,7 +68,12 @@ subcomponents: ### Istio -In this [config definition](https://github.com/evanlouie/fabrikate-istio/blob/master/config/common.yaml) we are applying the namespace `istio-system` and also applying the config `global.k8sIngress.enable`: `true` in the `values.yaml` file that is applied to the helm chart. It also applies the namespace `istio-system` to the subcomponent `istio-crd`. +In this +[config definition](https://github.com/evanlouie/fabrikate-istio/blob/master/config/common.yaml) +we are applying the namespace `istio-system` and also applying the config +`global.k8sIngress.enable`: `true` in the `values.yaml` file that is applied to +the helm chart. It also applies the namespace `istio-system` to the subcomponent +`istio-crd`. ```yaml namespace: istio-system diff --git a/docs/contributing.md b/docs/contributing.md index bd2f3e2..0423d08 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -1,38 +1,62 @@ # Contibuting to Fabrikate -We do not claim to have all the answers and would gratefully appreciate contributions. This document covers everything you need to know to contribute to Fabrikate. +We do not claim to have all the answers and would gratefully appreciate +contributions. This document covers everything you need to know to contribute to +Fabrikate. ## Issues and Feature Requests -This project tracks issues exclusively via our project on Github: please [file issues](https://github.com/microsoft/fabrikate/issues/new/choose) there. +This project tracks issues exclusively via our project on Github: please +[file issues](https://github.com/microsoft/fabrikate/issues/new/choose) there. -Please do not ask questions via Github issues. Instead, please [join us on Slack](https://publicslack.com/slacks/https-bedrockco-slack-com/invites/new) and ask there. +Please do not ask questions via Github issues. Instead, please +[join us on Slack](https://publicslack.com/slacks/https-bedrockco-slack-com/invites/new) +and ask there. -For issues and feature requests, please follow the general format suggested by the template. Our core team working on Fabrikate utilizes agile development and would appreciate feature requests phrased in the form of a [user story](https://www.mountaingoatsoftware.com/agile/user-stories), as this helps us understand better the context of how the feature would be utilized. +For issues and feature requests, please follow the general format suggested by +the template. Our core team working on Fabrikate utilizes agile development and +would appreciate feature requests phrased in the form of a +[user story](https://www.mountaingoatsoftware.com/agile/user-stories), as this +helps us understand better the context of how the feature would be utilized. ## Pull Requests -Every pull request should be matched with a Github issue. If the pull request is substantial enough to include newly designed elements, this issue should describe the proposed design in enough detail that we can come to an agreement before effort is applied to build the feature. Feel free to start conversations on our Slack #fabrikate channel to get feedback on a design. +Every pull request should be matched with a Github issue. If the pull request is +substantial enough to include newly designed elements, this issue should +describe the proposed design in enough detail that we can come to an agreement +before effort is applied to build the feature. Feel free to start conversations +on our Slack #fabrikate channel to get feedback on a design. -When submitting a pull request, please reference the issue the pull request is intended to solve via "Closes #xyz" where is the issue number that is addressed. +When submitting a pull request, please reference the issue the pull request is +intended to solve via "Closes #xyz" where is the issue number that is addressed. ## Cloning Fabrikate -Fabrikate is written in [golang](https://golang.org/) so the first step is to make sure you have a fully functioning go development enviroment. +Fabrikate is written in [golang](https://golang.org/) so the first step is to +make sure you have a fully functioning go development enviroment. -If you intend to make contributions to Fabrikate (versus just build it), the first step is to [fork Fabrikate on Github](https://github.com/microsoft/fabrikate) into your own account. +If you intend to make contributions to Fabrikate (versus just build it), the +first step is to +[fork Fabrikate on Github](https://github.com/microsoft/fabrikate) into your own +account. -Next, clone Fabrikate into your GOPATH (which defaults to \$HOME/go) with `go get` (substitute your GitHub username for `microsoft` below if you forked the repo): +Next, clone Fabrikate into your GOPATH (which defaults to \$HOME/go) with +`go get` (substitute your GitHub username for `microsoft` below if you forked +the repo): ```sh $ go get github.com/microsoft/fabrikate ``` -If you forked Fabrikate, this will clone your fork into `$GOPATH//fabrikate`. You will want to move to \$GOPATH/microsoft/fabrikate such that the imports in the project work correctly. +If you forked Fabrikate, this will clone your fork into +`$GOPATH//fabrikate`. You will want to move to +\$GOPATH/microsoft/fabrikate such that the imports in the project work +correctly. ### Configuring git -Under `$GOPATH/microsoft/fabrikate` set up git so that you can push changes to the fork: +Under `$GOPATH/microsoft/fabrikate` set up git so that you can push changes to +the fork: ```sh $ git remote add @@ -52,13 +76,15 @@ $ git push myremote mycurrentbranch ## Building Fabrikate -From the root of the project (which if you followed the instructions above should be `$GOPATH/microsoft/fabrikate`), first fetch project dependencies with: +From the root of the project (which if you followed the instructions above +should be `$GOPATH/microsoft/fabrikate`), first fetch project dependencies with: ```sh $ scripts/build get-deps ``` -Note: to run tests, you will need to run `scripts/build get-deps` to install test dependencies. +Note: to run tests, you will need to run `scripts/build get-deps` to install +test dependencies. You can then build a Fabrikate executable with: @@ -66,7 +92,8 @@ You can then build a Fabrikate executable with: $ scripts/build build fab ``` -To build a complete set of release binaries across supported architectures, use our build script, specifying a version number of the release: +To build a complete set of release binaries across supported architectures, use +our build script, specifying a version number of the release: ```sh $ scripts/build build release 0.5.0 @@ -74,7 +101,10 @@ $ scripts/build build release 0.5.0 ## Testing Fabrikate -Fabrikate utilizes test driven development to maintain quality across commits. Every code contribution requires covering tests to be accepted by the project and every pull request is built by CI/CD to ensure that the tests pass and that the code is lint free. +Fabrikate utilizes test driven development to maintain quality across commits. +Every code contribution requires covering tests to be accepted by the project +and every pull request is built by CI/CD to ensure that the tests pass and that +the code is lint free. You can run project tests by executing the following commands: @@ -90,10 +120,19 @@ $ golangci-lint run ## Contributing -This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.microsoft.com. +This project welcomes contributions and suggestions. Most contributions require +you to agree to a Contributor License Agreement (CLA) declaring that you have +the right to, and actually do, grant us the rights to use your contribution. For +details, visit https://cla.microsoft.com. -When you submit a pull request, a CLA-bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA. +When you submit a pull request, a CLA-bot will automatically determine whether +you need to provide a CLA and decorate the PR appropriately (e.g., label, +comment). Simply follow the instructions provided by the bot. You will only need +to do this once across all repos using our CLA. -This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). -For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or -contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. +This project has adopted the +[Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). +For more information see the +[Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or +contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any +additional questions or comments.