-
Notifications
You must be signed in to change notification settings - Fork 10
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: Simplifying ALB and IAM Role Configuration in modules #392
Comments
@jorisdon @gabebatista - thoughts? |
I see value in simplifying the codebase, and similarly in being opinionated about specific things, but those should not lead to a loss in flexibility. Some users have no infrastructure set up yet and would just want to deploy a module that provides them with the module's functionality. Others already have an opinionated infrastructure set up and they want to add a module's functionality to it. When we're simplifying or being opinionated about things, we've got to ask ourselves: "are there any users who would object to our decisions here? if so, do they have an escape-hatch other than a fork or a pull request?" Obviously there's a trade-off there still, and I don't expect that we can support every use case easily. On IAM: generally I'd say that having modules provision IAM roles with appropriate policies makes a lot of sense. Those roles can then be exposed as an output for customization purposes and I expect that that'd suffice for most use cases. I suppose there may be a use case where users would want to manage IAM roles outside of Terraform completely (presumably using a different tool) which would necessitate having support for passing in a role, but I wouldn't really know what the motivation behind that would be. |
Here's an idea that might allow for a good level of customization, whilst also keeping the code readable and free from excessive configuration parameters / boolean logic: module layers with dependency injection. I am not entirely sure if this is supported well in Terraform nor if it's a common practice, but here's the idea; Rather than providing a single module as we do now, we provide a set of modules that are layered on top of each other in a chain, with the lowest-level module providing the most core functionality only, and the highest-level module providing a more opinionated stack of services that are required, but some users may want to customize and manage elsewhere (either within their own Terraform module, or maybe even outside of Terraform entirely). Here's an example of a bunch of layers:
And here's some of the rules / tenets governing layers:
I acknowledge that this wouldn't necessarily lead to less code nor duplication of code (we'd have to repeat the passing down of variables and up of outputs in each layer), but it would reduce conditional logic (where I think the complexity lies) significantly and give us an ability to be more opinionated (and change those opinions over time based on feedback) without sacrificing flexibility or causing breaking changes. |
While I like Joris' idea in concept, I worry it would add a lot of extra work (and potentially complexity) to the project. I think that having opinionated defaults with the ability to pass in your own resources would be ideal. This approach would keep things simple for non-tech users, while providing a simple way to manage changes either through creating resources in the console prior to deployment or defining resources in a higher level terraform template (like our samples). It might also be worth exploring adding additional samples to the modules that cover common use cases. This would provide more options for non-tech users while also giving additional examples for users who wish to customize the code themselves. |
This is great feedback folks - thanks. On the question of nested / layered modulesWhile I like this theory in practice, I think we can accomplish much of the same flexibility through variables with a flatter module structure and better variable definition. Hashicorp is pretty explicit on their guidance for nesting modules, and from my research it seems to complicate the update process for resources. Plus, we aren't expected to distinguish between a "layer 1" versus a "layer 2" versus a "layer 3" resource. You are correct that much of the complexity lies in the conditional logic - this is why I am proposing more extensive use of locals for defining logical paths. Locals for conditional creationCurrently, when resources need to be conditionally created we use Simplification of overridesI am in favor of EXTENSIVE customizations available for modules through variables. But we need to do a better job defining where the "break glass" points actually are. IAM is the best example of this. The variables |
Conceptually I'm aligned with this idea. @henrykie Implement this into Helix Core module as PR so there's a representative example of some of these ideas in practice and associate with this issue. |
@henrykie @jorisdon I would love your opinions on the Definition of Done (DoD) for this issue. It goes without saying that each module being modified would have its own DoD. I wrote this with the (Helix Authentication Service)[https://github.com/aws-games/cloud-game-development-toolkit/tree/d60f4984c84299628783f97dc54cfd16dd3f3283/modules/perforce/helix-authentication-service] module in mind, so slight changes would be made for each of the individual modules being modified. Definition of DoneGeneral Work
ALB Configuration Simplification
IAM Role Management
Documentation & Examples
Testing & Verification
|
Is this related to an existing feature request or issue?
No
What part of the Cloud Game Development Toolkit does this RFC relate to?
Modules
Summary
We currently expose customization of the application load balancer that fronts the Helix Authentication Service, the Helix Swarm service, and the Unreal Horde service through module variables. This results in a significant number of variables, which requires extensive conditional creation of resources inside the module. I propose that we adopt a more opinionated and less customizable approach to ALB creation inside of the module, and support target group and service detail module outputs so extensive networking customization can be accomplished outside of the module.
The same goes for IAM roles. We support passing in an externally created role. It may make more sense to control role creation for the service inside the module, and attach permissions / policies externally by exposing the role ARN as an output.
Use case
Proposal
Currently, I control the ALB and role creation for the Helix Authentication Service through variables:
It would be simpler if these variables were not exposed. We should enable creation (turn off/on), but be opinionated on the following topics:
debug
.Out of scope
The module should be responsible for creating NECESSARY resources for operating the service:
Potential challenges
There is nuance around how we manage security groups, both within the module and externally managed. This is something that needs further design, and probably would have holistic changes to the way we build security groups for modules.
Dependencies and Integrations
I am currently working on a sample for running Helix Core behind an NLB. This same NLB can also manage traffic for Helix Swarm and Helix Authentication Service. Currently, both Helix Swarm and Helix Authentication service create ALBs, but this is inefficient. In order to share an ALB we should be able to disable ALB creation inside of each of these modules, but pull out target groups from each for creating listeners / rules on the shared ALB and the shared NLB.
Alternative solutions
The text was updated successfully, but these errors were encountered: