Merge master

This commit is contained in:
Lorenzo Caggioni 2022-01-28 17:06:36 +01:00
parent 41ccdebffe
commit 1f8ad06b8d
13 changed files with 0 additions and 326 deletions

View File

@ -9,13 +9,9 @@ The code is intentionally simple, as it's intended to provide a generic initial
The following diagram is a high level reference of the resources created and managed here:
<<<<<<< HEAD
![Resource-management diagram](diagram.png)
=======
<p align="center">
<img src="diagram.svg" alt="Resource-management diagram">
</p>
>>>>>>> master
## Design overview and choices
@ -142,13 +138,7 @@ IAM roles can be easily edited in the relevant `branch-xxx.tf` file, following t
Due to its simplicity, this stage lends itself easily to customizations: adding a new top-level branch (e.g. for shared GKE clusters) is as easy as cloning one of the `branch-xxx.tf` files, and changing names.
<<<<<<< HEAD
=======
<!-- TFDOC OPTS files:1 show_extra:1 -->
>>>>>>> master
<!-- BEGIN TFDOC -->
## Files
@ -156,10 +146,6 @@ Due to its simplicity, this stage lends itself easily to customizations: adding
| name | description | modules | resources |
|---|---|---|---|
| [billing.tf](./billing.tf) | Billing resources for external billing use cases. | <code>organization</code> | <code>google_billing_account_iam_member</code> |
<<<<<<< HEAD
| [branch-gke.tf](./branch-gke.tf) | GKE stage resources. | <code>folder</code> · <code>gcs</code> · <code>iam-service-account</code> | |
=======
>>>>>>> master
| [branch-networking.tf](./branch-networking.tf) | Networking stage resources. | <code>folder</code> · <code>gcs</code> · <code>iam-service-account</code> | |
| [branch-sandbox.tf](./branch-sandbox.tf) | Sandbox stage resources. | <code>folder</code> · <code>gcs</code> · <code>iam-service-account</code> | |
| [branch-security.tf](./branch-security.tf) | Security stage resources. | <code>folder</code> · <code>gcs</code> · <code>iam-service-account</code> | |
@ -173,17 +159,6 @@ Due to its simplicity, this stage lends itself easily to customizations: adding
| name | description | type | required | default | producer |
|---|---|:---:|:---:|:---:|:---:|
<<<<<<< HEAD
| automation_project_id | Project id for the automation project created by the bootstrap stage. | <code>string</code> | ✓ | | <code>00-bootstrap</code> |
| billing_account | Billing account id and organization id ('nnnnnnnn' or null). | <code title="object&#40;&#123;&#10; id &#61; string&#10; organization_id &#61; number&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | | <code>00-bootstrap</code> |
| organization | Organization details. | <code title="object&#40;&#123;&#10; domain &#61; string&#10; id &#61; number&#10; customer_id &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | | <code>00-bootstrap</code> |
| prefix | Prefix used for resources that need unique names. | <code>string</code> | ✓ | | <code>00-bootstrap</code> |
| custom_roles | Custom roles defined at the org level, in key => id format. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> | <code>00-bootstrap</code> |
| groups | Group names to grant organization-level permissions. | <code>map&#40;string&#41;</code> | | <code title="&#123;&#10; gcp-billing-admins &#61; &#34;gcp-billing-admins&#34;,&#10; gcp-devops &#61; &#34;gcp-devops&#34;,&#10; gcp-network-admins &#61; &#34;gcp-network-admins&#34;&#10; gcp-organization-admins &#61; &#34;gcp-organization-admins&#34;&#10; gcp-security-admins &#61; &#34;gcp-security-admins&#34;&#10; gcp-support &#61; &#34;gcp-support&#34;&#10;&#125;">&#123;&#8230;&#125;</code> | <code>00-bootstrap</code> |
| organization_policy_configs | Organization policies customization. | <code title="object&#40;&#123;&#10; allowed_policy_member_domains &#61; list&#40;string&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> | |
| outputs_location | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | <code>string</code> | | <code>null</code> | |
| team_folders | Team folders to be created. Format is described in a code comment. | <code title="map&#40;object&#40;&#123;&#10; descriptive_name &#61; string&#10; group_iam &#61; map&#40;list&#40;string&#41;&#41;&#10; impersonation_groups &#61; list&#40;string&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>null</code> | |
=======
| [automation_project_id](variables.tf#L29) | Project id for the automation project created by the bootstrap stage. | <code>string</code> | ✓ | | <code>00-bootstrap</code> |
| [billing_account](variables.tf#L20) | Billing account id and organization id ('nnnnnnnn' or null). | <code title="object&#40;&#123;&#10; id &#61; string&#10; organization_id &#61; number&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | | <code>00-bootstrap</code> |
| [organization](variables.tf#L57) | Organization details. | <code title="object&#40;&#123;&#10; domain &#61; string&#10; id &#61; number&#10; customer_id &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | | <code>00-bootstrap</code> |
@ -193,31 +168,11 @@ Due to its simplicity, this stage lends itself easily to customizations: adding
| [organization_policy_configs](variables.tf#L67) | Organization policies customization. | <code title="object&#40;&#123;&#10; allowed_policy_member_domains &#61; list&#40;string&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> | |
| [outputs_location](variables.tf#L75) | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | <code>string</code> | | <code>null</code> | |
| [team_folders](variables.tf#L87) | Team folders to be created. Format is described in a code comment. | <code title="map&#40;object&#40;&#123;&#10; descriptive_name &#61; string&#10; group_iam &#61; map&#40;list&#40;string&#41;&#41;&#10; impersonation_groups &#61; list&#40;string&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>null</code> | |
>>>>>>> master
## Outputs
| name | description | sensitive | consumers |
|---|---|:---:|---|
<<<<<<< HEAD
| networking | Data for the networking stage. | | <code>02-networking</code> |
| project_factories | Data for the project factories stage. | | <code>xx-teams</code> |
| providers | Terraform provider files for this stage and dependent stages. | ✓ | <code>02-networking</code> · <code>02-security</code> · <code>xx-sandbox</code> · <code>xx-teams</code> |
| sandbox | Data for the sandbox stage. | | <code>xx-sandbox</code> |
| security | Data for the networking stage. | | <code>02-security</code> |
| teams | Data for the teams stage. | | |
| tfvars | Terraform variable files for the following stages. | ✓ | |
<!-- END TFDOC -->
=======
| [networking](outputs.tf#L79) | Data for the networking stage. | | <code>02-networking</code> |
| [project_factories](outputs.tf#L89) | Data for the project factories stage. | | <code>xx-teams</code> |
| [providers](outputs.tf#L106) | Terraform provider files for this stage and dependent stages. | ✓ | <code>02-networking</code> · <code>02-security</code> · <code>xx-sandbox</code> · <code>xx-teams</code> |
@ -227,4 +182,3 @@ Due to its simplicity, this stage lends itself easily to customizations: adding
| [tfvars](outputs.tf#L146) | Terraform variable files for the following stages. | ✓ | |
<!-- END TFDOC -->
>>>>>>> master

View File

@ -1,9 +1,5 @@
# skip boilerplate check
region: europe-west1
<<<<<<< HEAD
ip_cidr_range: 10.144.0.0/24
=======
ip_cidr_range: 10.128.16.0/24
>>>>>>> master
description: Default subnet for dev

View File

@ -1,9 +1,5 @@
# skip boilerplate check
region: europe-west1
<<<<<<< HEAD
ip_cidr_range: 10.136.0.0/24
=======
ip_cidr_range: 10.128.128.0/24
>>>>>>> master
description: Default subnet for prod

View File

@ -1,13 +1,6 @@
# Project factory
<<<<<<< HEAD
The Project Factory (or PF) builds on top of your foundations to create and setup projects (and related resources) to be used for your workloads.
It is organized in folders representing enviroments (e.g. "dev", "prod"), each implemented by a stand-alone terraform [resource factory](https://medium.com/google-cloud/resource-factories-a-descriptive-approach-to-terraform-581b3ebb59c).
This directory contains a single project factory ([`prod/`](./prod/)) as an example - in order to implement multiple environments (e.g. "prod" and "dev") you'll need to copy the `prod` folder into one folder per environment, then customize each one following the instructions found in [`prod/README.md`](./prod/README.md).
=======
The Project Factory (PF) builds on top of your foundations to create and set up projects (and related resources) to be used for your workloads.
It is organized in folders representing environments (e.g. "dev", "prod"), each implemented by a stand-alone terraform [resource factory](https://medium.com/google-cloud/resource-factories-a-descriptive-approach-to-terraform-581b3ebb59c).
This directory contains a single project factory ([`prod/`](./prod/)) as an example - to implement multiple environments (e.g. "prod" and "dev") you'll need to copy the `prod` folder into one folder per environment, then customize each one following the instructions found in [`prod/README.md`](./prod/README.md).
>>>>>>> master

View File

@ -1,17 +1,6 @@
# Project factory
The Project Factory (or PF) builds on top of your foundations to create and set up projects (and related resources) to be used for your workloads.
<<<<<<< HEAD
It is organized in folders representing environments (e.g. "dev", "prod"), each implemented by a stand-alone terraform [resource factory](https://medium.com/google-cloud/resource-factories-a-descriptive-approach-to-terraform-581b3ebb59c).
## Design overview and choices
![Diagram](diagram.png)
A single factory creates projects in a well-defined context, according to your resource management structure. In the diagram above, each Team is structured to have specific folders projects for a given environment, such as Production and Development, per the resource management structure configured in stage `01-resman`.
Projects for each environment across different teams are created by dedicated service accounts, as exemplified in the diagram above. While there's no intrinsic limitation regarding where the project factory can create a given project, the IAM bindings for the service account effectively enforce boundaries (e.g. the production service account shouldn't be able to create or have any access to the development projects, and vice versa).
=======
It is organized in folders representing environments (e.g., "dev", "prod"), each implemented by a stand-alone terraform [resource factory](https://medium.com/google-cloud/resource-factories-a-descriptive-approach-to-terraform-581b3ebb59c).
## Design overview and choices
@ -23,7 +12,6 @@ It is organized in folders representing environments (e.g., "dev", "prod"), each
A single factory creates projects in a well-defined context, according to your resource management structure. For example, in the diagram above, each Team is structured to have specific folders projects for a given environment, such as Production and Development, per the resource management structure configured in stage `01-resman`.
Projects for each environment across different teams are created by dedicated service accounts, as exemplified in the diagram above. While there's no intrinsic limitation regarding where the project factory can create a projects, the IAM bindings for the service account effectively enforce boundaries (e.g., the production service account shouldn't be able to create or have any access to the development projects, and vice versa).
>>>>>>> master
The project factory takes care of the following activities:
@ -41,15 +29,9 @@ The project factory takes care of the following activities:
## How to run this stage
<<<<<<< HEAD
This stage is meant to be executed after "foundational stages" (i.e. stages [`00-bootstrap`](../../00-bootstrap), [`01-resman`](../../01-resman), [`02-networking`](../../02-networking) and [`02-security`](../../02-security)) have been run.
It's of course possible to run this stage in isolation, by making sure the architectural prerequisites are satisfied (e.g. networking), and that the Service Account running the stage is granted the roles/permissions below:
=======
This stage is meant to be executed after "foundational stages" (i.e., stages [`00-bootstrap`](../../00-bootstrap), [`01-resman`](../../01-resman), [`02-networking`](../../02-networking) and [`02-security`](../../02-security)) have been run.
It's of course possible to run this stage in isolation, by making sure the architectural prerequisites are satisfied (e.g., networking), and that the Service Account running the stage is granted the roles/permissions below:
>>>>>>> master
* One service account per environment, each with appropriate permissions
* at the organization level a custom role for networking operations including the following permissions
@ -58,11 +40,7 @@ It's of course possible to run this stage in isolation, by making sure the archi
* `"compute.subnetworks.setIamPolicy"`,
* `"dns.networks.bindPrivateDNSZone"`
* and role `"roles/orgpolicy.policyAdmin"`
<<<<<<< HEAD
* on each folder where projects will be created
=======
* on each folder where projects are created
>>>>>>> master
* `"roles/logging.admin"`
* `"roles/owner"`
* `"roles/resourcemanager.folderAdmin"`
@ -71,21 +49,12 @@ It's of course possible to run this stage in isolation, by making sure the archi
* `"roles/browser"`
* `"roles/compute.viewer"`
* `"roles/dns.admin"`
<<<<<<< HEAD
* If networking is to be used (e.g. for VMs, GKE Clusters or AppEngine flex), VPC Host projects and their subnets should exist when creating projects
* If per-environment DNS sub-zones are required, one "root" zone per environment should exist when creating projects (e.g. prod.gcp.example.com.)
### Providers configuration
If you're running this on top of FAST, you should run the following commands to create the provider file, and populate the required variables from the previous stage.
=======
* If networking is used (e.g., for VMs, GKE Clusters or AppEngine flex), VPC Host projects and their subnets should exist when creating projects
* If per-environment DNS sub-zones are required, one "root" zone per environment should exist when creating projects (e.g., prod.gcp.example.com.)
### Providers configuration
If you're running this on top of Fast, you should run the following commands to create the providers file, and populate the required variables from the previous stage.
>>>>>>> master
```bash
# Variable `outputs_location` is set to `../../configs/example` in stage 01-resman
@ -110,19 +79,6 @@ ln -s ../../../configs/example/03-project-factory-prod/terraform-bootstrap.auto.
ln -s ../../../configs/example/03-project-factory-prod/terraform-networking.auto.tfvars.json
```
<<<<<<< HEAD
If you're not running on top of fast, refer to the [Variables](#variables) table at the bottom of this document for a full list of variables, their origin (e.g. a stage or specific to this one), and descriptions explaining their meaning.
Besides the values above, a project factory takes 2 additional inputs:
* `data/defaults.yaml`, manually configured by adapting the [`prod/data/defaults.yaml.sample`](./prod/data/defaults.yaml.sample), which defines per-environment default values e.g. for billing alerts and labels.
* `data/projects/*.yaml`, one file per project (optionally grouped in folders), which configures each project. A [`prod/data/projects/project.yaml.sample`](./prod/data/projects/project.yaml.sample) is provided as reference and documentation for the schema. Projects will be named after the filename, e.g. `fast-prod-lab0.yaml` will generate project `fast-prod-lab0`.
Once the configuration is complete, the project factory can be run with the usual
=======
If you're not using Fast, refer to the [Variables](#variables) table at the bottom of this document for a full list of variables, their origin (e.g., a stage or specific to this one), and descriptions explaining their meaning.
Besides the values above, a project factory takes 2 additional inputs:
@ -132,73 +88,38 @@ Besides the values above, a project factory takes 2 additional inputs:
* `data/projects/*.yaml`, one file per project (optionally grouped in folders), which configures each project. A [`prod/data/projects/project.yaml.sample`](./prod/data/projects/project.yaml.sample) is provided as reference and documentation for the schema. Projects will be named after the filename, e.g., `fast-prod-lab0.yaml` will create project `fast-prod-lab0`.
Once the configuration is complete, run the project factory by running
>>>>>>> master
```bash
terraform init
terraform apply
```
<<<<<<< HEAD
=======
<!-- TFDOC OPTS files:1 show_extra:1 -->
>>>>>>> master
<!-- BEGIN TFDOC -->
## Files
<<<<<<< HEAD
| name | description | modules | resources |
|---|---|---|---|
| [main.tf](./main.tf) | Project factory. | <code>project-factory</code> | |
| [outputs.tf](./outputs.tf) | Module outputs. | | |
| [variables.tf](./variables.tf) | Module variables. | | |
=======
| name | description | modules |
|---|---|---|
| [main.tf](./main.tf) | Project factory. | <code>project-factory</code> |
| [outputs.tf](./outputs.tf) | Module outputs. | |
| [variables.tf](./variables.tf) | Module variables. | |
>>>>>>> master
## Variables
| name | description | type | required | default | producer |
|---|---|:---:|:---:|:---:|:---:|
<<<<<<< HEAD
| billing_account_id | Billing account id. | <code>string</code> | ✓ | | <code>00-bootstrap</code> |
| shared_vpc_self_link | Self link for the shared VPC. | <code>string</code> | ✓ | | <code>02-networking</code> |
| vpc_host_project | Host project for the shared VPC. | <code>string</code> | ✓ | | <code>02-networking</code> |
| data_dir | Relative path for the folder storing configuration data. | <code>string</code> | | <code>&#34;data&#47;projects&#34;</code> | |
| defaults_file | Relative path for the file storing the project factory configuration. | <code>string</code> | | <code>&#34;data&#47;defaults.yaml&#34;</code> | |
| environment_dns_zone | DNS zone suffix for environment. | <code>string</code> | | <code>null</code> | <code>02-networking</code> |
=======
| [billing_account_id](variables.tf#L19) | Billing account id. | <code>string</code> | ✓ | | <code>00-bootstrap</code> |
| [shared_vpc_self_link](variables.tf#L44) | Self link for the shared VPC. | <code>string</code> | ✓ | | <code>02-networking</code> |
| [vpc_host_project](variables.tf#L50) | Host project for the shared VPC. | <code>string</code> | ✓ | | <code>02-networking</code> |
| [data_dir](variables.tf#L25) | Relative path for the folder storing configuration data. | <code>string</code> | | <code>&#34;data&#47;projects&#34;</code> | |
| [defaults_file](variables.tf#L38) | Relative path for the file storing the project factory configuration. | <code>string</code> | | <code>&#34;data&#47;defaults.yaml&#34;</code> | |
| [environment_dns_zone](variables.tf#L31) | DNS zone suffix for environment. | <code>string</code> | | <code>null</code> | <code>02-networking</code> |
>>>>>>> master
## Outputs
| name | description | sensitive | consumers |
|---|---|:---:|---|
<<<<<<< HEAD
| projects | Created projects and service accounts. | | |
<!-- END TFDOC -->
=======
| [projects](outputs.tf#L17) | Created projects and service accounts. | | |
<!-- END TFDOC -->
>>>>>>> master

View File

@ -1,22 +0,0 @@
billing_account_id: 012345-67890A-BCDEF0
# [opt] Setup for billing alerts
billing_alert:
amount: 1000
thresholds:
current: [0.5, 0.8]
forecasted: [0.5, 0.8]
credit_treatment: INCLUDE_ALL_CREDITS
# [opt] Contacts for billing alerts and important notifications
essential_contacts: ["team-contacts@example.com"]
# [opt] Labels set for all projects
labels:
environment: prod
department: accounting
application: example-app
foo: bar
# [opt] Additional notification channels for billing
notification_channels: []

View File

@ -1,99 +0,0 @@
# [opt] Billing account id - overrides default if set
billing_account_id: 012345-67890A-BCDEF0
# [opt] Billing alerts config - overrides default if set
billing_alert:
amount: 10
thresholds:
current:
- 0.5
- 0.8
forecasted: []
# [opt] DNS zones to be created as children of the environment_dns_zone defined in defaults
dns_zones:
- lorem
- ipsum
# [opt] Contacts for billing alerts and important notifications
essential_contacts:
- team-a-contacts@example.com
# Folder the project will be created as children of
folder_id: folders/012345678901
# [opt] Authoritative IAM bindings in group => [roles] format
group_iam:
test-team-foobar@fast-lab-0.gcp-pso-italy.net:
- roles/compute.admin
# [opt] Authoritative IAM bindings in role => [principals] format
# Generally used to grant roles to service accounts external to the project
iam:
roles/compute.admin:
- serviceAccount:service-account
# [opt] Service robots and keys they will be assigned as cryptoKeyEncrypterDecrypter
# in service => [keys] format
kms_service_agents:
compute: [key1, key2]
storage: [key1, key2]
# [opt] Labels for the project - merged with the ones defined in defaults
labels:
environment: prod
# [opt] Org policy overrides defined at project level
org_policies:
policy_boolean:
constraints/compute.disableGuestAttributesAccess: true
policy_list:
constraints/compute.trustedImageProjects:
inherit_from_parent: null
status: true
suggested_value: null
values:
- projects/fast-prod-iac-core-0
# [opt] Service account to create for the project and their roles on the project
# in name => [roles] format
service_accounts:
another-service-account:
- roles/compute.admin
my-service-account:
- roles/compute.admin
# [opt] APIs to enable on the project.
services:
- storage.googleapis.com
- stackdriver.googleapis.com
- compute.googleapis.com
# [opt] Roles to assign to the robots service accounts in robot => [roles] format
services_iam:
compute:
- roles/storage.objectViewer
# [opt] VPC setup.
# If set enables the `compute.googleapis.com` service and configures
# service project attachment
vpc:
# [opt] If set, enables the container API
gke_setup:
# Grants "roles/container.hostServiceAgentUser" to the container robot if set
enable_host_service_agent: false
# Grants "roles/compute.securityAdmin" to the container robot if set
enable_security_admin: true
# Host project the project will be service project of
host_project: fast-prod-net-spoke-0
# [opt] Subnets in the host project where principals will be granted networkUser
# in region/subnet-name => [principals]
subnets_iam:
europe-west1/prod-default-ew1:
- user:foobar@example.com
- serviceAccount:service-account1

View File

@ -1,34 +0,0 @@
# Fabric FAST
Setting up a production-ready GCP organization is often a time-consuming process. Fabric FAST aims to speed up this process via two complementary goals. On the one hand, FAST provides a design of a GCP organization that includes the typical elements required by enterprise customers. Secondly, we provide a reference implementation of the FAST design using Terraform.
Note that while our implementation is necessarily influenced (and constrained) by the way Terraform works, the design we put forward only refers to GCP constructs and features. In other words, while we use Terraform for our reference implementation, in theory, the FAST design can be implemented using any other tool (e.g., Pulumi, bash scripts, or even calling the relevant APIs directly).
Fabric FAST comes from engineers in Google Cloud's Professional Services Organization, with a combined experience of decades solving the typical technical problems faced by GCP customers. While every GCP user has specific requirements, many common issues arise repeatedly. Solving those issues correctly from the beginning is key to a robust and scalable GCP setup. It's those common issues and their solutions that Fabric FAST aims to collect and present coherently.
Fabric FAST was initially conceived to help enterprises quickly set up a GCP organization following battle-tested and widely-used patterns. Despite its origin in enterprise environments, FAST includes many customization points making it an ideal blueprint for organizations of all sizes, ranging from startups to the largest companies.
## Guiding principles
### Contracts and stages
FAST uses the concept of stages, which individually perform precise tasks but, taken together, build a functional, ready-to-use GCP organization. More importantly, stages are modeled around the security boundaries that typically appear in mature organizations. This arrangement allows delegating ownership of each stage to the team responsible for the types of resources it manages. For example, as its name suggests, the networking stage sets up all the networking elements and is usually the responsibility of a dedicated networking team within the organization.
From the perspective of FAST's overall design, stages also work as contacts or interfaces, defining a set of pre-requisites and inputs required to perform their designed task and generating outputs needed by other stages lower in the chain.
### Security-first design
Security was, from the beginning, one of the most critical elements in the design of Fabric FAST. Many of FAST's design decisions aim to build the foundations of a secure organization. In fact, the first two stages deal mainly with the organization-wide security setup.
FAST also aims to minimize the number of permissions granted to principals according to the security-first approach previously mentioned. We achieve this through the meticulous use of groups, service accounts, custom roles, and [Cloud IAM Conditions](https://cloud.google.com/iam/docs/conditions-overview), among other things.
### Extensive use of factories
A resource factory consumes a simple representation of a resource (e.g., in YAML) and deploys it (e.g., using Terraform). Used correctly, factories can help decrease the management overhead of large-scale infrastructure deployments. See "[Resource Factories: A descriptive approach to Terraform](https://medium.com/google-cloud/resource-factories-a-descriptive-approach-to-terraform-581b3ebb59c)" for more details and the rationale behind factories.
FAST uses YAML-based factories to deploy subnets and firewall rules and, as its name suggests, in the [project factory](./stages/03-project-factory/) stage.
## High level design
TBD
## Implementation
TBD

View File

@ -26,15 +26,8 @@
# }
<<<<<<< HEAD
def test_counts(e2e_plan_runner):
"Test stage."
# TODO: to re-enable per-module resource count check print _, then test
num_modules, num_resources, _ = e2e_plan_runner()
=======
def test_counts(fast_e2e_plan_runner):
"Test stage."
# TODO: to re-enable per-module resource count check print _, then test
num_modules, num_resources, _ = fast_e2e_plan_runner()
>>>>>>> master
assert num_modules > 0 and num_resources > 0

View File

@ -13,14 +13,8 @@
# limitations under the License.
<<<<<<< HEAD
def test_counts(e2e_plan_runner):
"Test stage."
num_modules, num_resources, _ = e2e_plan_runner()
=======
def test_counts(fast_e2e_plan_runner):
"Test stage."
num_modules, num_resources, _ = fast_e2e_plan_runner()
>>>>>>> master
# TODO: to re-enable per-module resource count check print _, then test
assert num_modules > 0 and num_resources > 0

View File

@ -13,14 +13,8 @@
# limitations under the License.
<<<<<<< HEAD
def test_counts(e2e_plan_runner):
"Test stage."
num_modules, num_resources, _ = e2e_plan_runner()
=======
def test_counts(fast_e2e_plan_runner):
"Test stage."
num_modules, num_resources, _ = fast_e2e_plan_runner()
>>>>>>> master
# TODO: to re-enable per-module resource count check print _, then test
assert num_modules > 0 and num_resources > 0

View File

@ -13,14 +13,8 @@
# limitations under the License.
<<<<<<< HEAD
def test_counts(e2e_plan_runner):
"Test stage."
num_modules, num_resources, _ = e2e_plan_runner()
=======
def test_counts(fast_e2e_plan_runner):
"Test stage."
num_modules, num_resources, _ = fast_e2e_plan_runner()
>>>>>>> master
# TODO: to re-enable per-module resource count check print _, then test
assert num_modules > 0 and num_resources > 0

View File

@ -13,14 +13,8 @@
# limitations under the License.
<<<<<<< HEAD
def test_counts(e2e_plan_runner):
"Test stage."
num_modules, num_resources, _ = e2e_plan_runner()
=======
def test_counts(fast_e2e_plan_runner):
"Test stage."
num_modules, num_resources, _ = fast_e2e_plan_runner()
>>>>>>> master
# TODO: to re-enable per-module resource count check print _, then test
assert num_modules > 0 and num_resources > 0