mirror of
https://github.com/Sea-Haven-Industries/engineering-handbook.git
synced 2026-09-30 04:33:13 +00:00
Add engineering handbook
Conventions covering naming, git workflow, commit messages, pull requests, code review, GitHub standards, AWS infrastructure, SAM project layout, and secrets management. Commit messages section adapted from RomuloOliveira/commit-messages-guide (CC-BY-4.0).
This commit is contained in:
commit
0333e7f8f5
12 changed files with 945 additions and 0 deletions
26
CONTRIBUTING.md
Normal file
26
CONTRIBUTING.md
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
# Contributing
|
||||||
|
|
||||||
|
## How to Suggest Changes
|
||||||
|
|
||||||
|
- Open an issue describing the proposed change and why it's needed
|
||||||
|
- Or submit a PR with edits to the relevant markdown file
|
||||||
|
|
||||||
|
## Style Guidelines
|
||||||
|
|
||||||
|
- Keep it concise and scannable
|
||||||
|
- Use headers, bullet points, and code blocks
|
||||||
|
- One topic per file
|
||||||
|
- Concrete examples are better than abstract rules
|
||||||
|
- No emoji
|
||||||
|
|
||||||
|
## Adding a New Topic
|
||||||
|
|
||||||
|
If a convention doesn't fit into an existing file:
|
||||||
|
|
||||||
|
1. Create a new kebab-case markdown file at the root (e.g., `testing-standards.md`)
|
||||||
|
2. Add a link to it in `README.md` under the Contents section
|
||||||
|
3. Submit as a PR
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
Contributions to this repository are licensed under [CC-BY-4.0](https://creativecommons.org/licenses/by/4.0/).
|
||||||
395
LICENSE
Normal file
395
LICENSE
Normal file
|
|
@ -0,0 +1,395 @@
|
||||||
|
Attribution 4.0 International
|
||||||
|
|
||||||
|
=======================================================================
|
||||||
|
|
||||||
|
Creative Commons Corporation ("Creative Commons") is not a law firm and
|
||||||
|
does not provide legal services or legal advice. Distribution of
|
||||||
|
Creative Commons public licenses does not create a lawyer-client or
|
||||||
|
other relationship. Creative Commons makes its licenses and related
|
||||||
|
information available on an "as-is" basis. Creative Commons gives no
|
||||||
|
warranties regarding its licenses, any material licensed under their
|
||||||
|
terms and conditions, or any related information. Creative Commons
|
||||||
|
disclaims all liability for damages resulting from their use to the
|
||||||
|
fullest extent possible.
|
||||||
|
|
||||||
|
Using Creative Commons Public Licenses
|
||||||
|
|
||||||
|
Creative Commons public licenses provide a standard set of terms and
|
||||||
|
conditions that creators and other rights holders may use to share
|
||||||
|
original works of authorship and other material subject to copyright
|
||||||
|
and certain other rights specified in the public license below. The
|
||||||
|
following considerations are for informational purposes only, are not
|
||||||
|
exhaustive, and do not form part of our licenses.
|
||||||
|
|
||||||
|
Considerations for licensors: Our public licenses are
|
||||||
|
intended for use by those authorized to give the public
|
||||||
|
permission to use material in ways otherwise restricted by
|
||||||
|
copyright and certain other rights. Our licenses are
|
||||||
|
irrevocable. Licensors should read and understand the terms
|
||||||
|
and conditions of the license they choose before applying it.
|
||||||
|
Licensors should also secure all rights necessary before
|
||||||
|
applying our licenses so that the public can reuse the
|
||||||
|
material as expected. Licensors should clearly mark any
|
||||||
|
material not subject to the license. This includes other CC-
|
||||||
|
licensed material, or material used under an exception or
|
||||||
|
limitation to copyright. More considerations for licensors:
|
||||||
|
wiki.creativecommons.org/Considerations_for_licensors
|
||||||
|
|
||||||
|
Considerations for the public: By using one of our public
|
||||||
|
licenses, a licensor grants the public permission to use the
|
||||||
|
licensed material under specified terms and conditions. If
|
||||||
|
the licensor's permission is not necessary for any reason--for
|
||||||
|
example, because of any applicable exception or limitation to
|
||||||
|
copyright--then that use is not regulated by the license. Our
|
||||||
|
licenses grant only permissions under copyright and certain
|
||||||
|
other rights that a licensor has authority to grant. Use of
|
||||||
|
the licensed material may still be restricted for other
|
||||||
|
reasons, including because others have copyright or other
|
||||||
|
rights in the material. A licensor may make special requests,
|
||||||
|
such as asking that all changes be marked or described.
|
||||||
|
Although not required by our licenses, you are encouraged to
|
||||||
|
respect those requests where reasonable. More considerations
|
||||||
|
for the public:
|
||||||
|
wiki.creativecommons.org/Considerations_for_licensees
|
||||||
|
|
||||||
|
=======================================================================
|
||||||
|
|
||||||
|
Creative Commons Attribution 4.0 International Public License
|
||||||
|
|
||||||
|
By exercising the Licensed Rights (defined below), You accept and agree
|
||||||
|
to be bound by the terms and conditions of this Creative Commons
|
||||||
|
Attribution 4.0 International Public License ("Public License"). To the
|
||||||
|
extent this Public License may be interpreted as a contract, You are
|
||||||
|
granted the Licensed Rights in consideration of Your acceptance of
|
||||||
|
these terms and conditions, and the Licensor grants You such rights in
|
||||||
|
consideration of benefits the Licensor receives from making the
|
||||||
|
Licensed Material available under these terms and conditions.
|
||||||
|
|
||||||
|
|
||||||
|
Section 1 -- Definitions.
|
||||||
|
|
||||||
|
a. Adapted Material means material subject to Copyright and Similar
|
||||||
|
Rights that is derived from or based upon the Licensed Material
|
||||||
|
and in which the Licensed Material is translated, altered,
|
||||||
|
arranged, transformed, or otherwise modified in a manner requiring
|
||||||
|
permission under the Copyright and Similar Rights held by the
|
||||||
|
Licensor. For purposes of this Public License, where the Licensed
|
||||||
|
Material is a musical work, performance, or sound recording,
|
||||||
|
Adapted Material is always produced where the Licensed Material is
|
||||||
|
synched in timed relation with a moving image.
|
||||||
|
|
||||||
|
b. Adapter's License means the license You apply to Your Copyright
|
||||||
|
and Similar Rights in Your contributions to Adapted Material in
|
||||||
|
accordance with the terms and conditions of this Public License.
|
||||||
|
|
||||||
|
c. Copyright and Similar Rights means copyright and/or similar rights
|
||||||
|
closely related to copyright including, without limitation,
|
||||||
|
performance, broadcast, sound recording, and Sui Generis Database
|
||||||
|
Rights, without regard to how the rights are labeled or
|
||||||
|
categorized. For purposes of this Public License, the rights
|
||||||
|
specified in Section 2(b)(1)-(2) are not Copyright and Similar
|
||||||
|
Rights.
|
||||||
|
|
||||||
|
d. Effective Technological Measures means those measures that, in the
|
||||||
|
absence of proper authority, may not be circumvented under laws
|
||||||
|
fulfilling obligations under Article 11 of the WIPO Copyright
|
||||||
|
Treaty adopted on December 20, 1996, and/or similar international
|
||||||
|
agreements.
|
||||||
|
|
||||||
|
e. Exceptions and Limitations means fair use, fair dealing, and/or
|
||||||
|
any other exception or limitation to Copyright and Similar Rights
|
||||||
|
that applies to Your use of the Licensed Material.
|
||||||
|
|
||||||
|
f. Licensed Material means the artistic or literary work, database,
|
||||||
|
or other material to which the Licensor applied this Public
|
||||||
|
License.
|
||||||
|
|
||||||
|
g. Licensed Rights means the rights granted to You subject to the
|
||||||
|
terms and conditions of this Public License, which are limited to
|
||||||
|
all Copyright and Similar Rights that apply to Your use of the
|
||||||
|
Licensed Material and that the Licensor has authority to license.
|
||||||
|
|
||||||
|
h. Licensor means the individual(s) or entity(ies) granting rights
|
||||||
|
under this Public License.
|
||||||
|
|
||||||
|
i. Share means to provide material to the public by any means or
|
||||||
|
process that requires permission under the Licensed Rights, such
|
||||||
|
as reproduction, public display, public performance, distribution,
|
||||||
|
dissemination, communication, or importation, and to make material
|
||||||
|
available to the public including in ways that members of the
|
||||||
|
public may access the material from a place and at a time
|
||||||
|
individually chosen by them.
|
||||||
|
|
||||||
|
j. Sui Generis Database Rights means rights other than copyright
|
||||||
|
resulting from Directive 96/9/EC of the European Parliament and of
|
||||||
|
the Council of 11 March 1996 on the legal protection of databases,
|
||||||
|
as amended and/or succeeded, as well as other essentially
|
||||||
|
equivalent rights anywhere in the world.
|
||||||
|
|
||||||
|
k. You means the individual or entity exercising the Licensed Rights
|
||||||
|
under this Public License. Your has a corresponding meaning.
|
||||||
|
|
||||||
|
|
||||||
|
Section 2 -- Scope.
|
||||||
|
|
||||||
|
a. License grant.
|
||||||
|
|
||||||
|
1. Subject to the terms and conditions of this Public License,
|
||||||
|
the Licensor hereby grants You a worldwide, royalty-free,
|
||||||
|
non-sublicensable, non-exclusive, irrevocable license to
|
||||||
|
exercise the Licensed Rights in the Licensed Material to:
|
||||||
|
|
||||||
|
a. reproduce and Share the Licensed Material, in whole or
|
||||||
|
in part; and
|
||||||
|
|
||||||
|
b. produce, reproduce, and Share Adapted Material.
|
||||||
|
|
||||||
|
2. Exceptions and Limitations. For the avoidance of doubt, where
|
||||||
|
Exceptions and Limitations apply to Your use, this Public
|
||||||
|
License does not apply, and You do not need to comply with
|
||||||
|
its terms and conditions.
|
||||||
|
|
||||||
|
3. Term. The term of this Public License is specified in Section
|
||||||
|
6(a).
|
||||||
|
|
||||||
|
4. Media and formats; technical modifications allowed. The
|
||||||
|
Licensor authorizes You to exercise the Licensed Rights in
|
||||||
|
all media and formats whether now known or hereafter created,
|
||||||
|
and to make technical modifications necessary to do so. The
|
||||||
|
Licensor waives and/or agrees not to assert any right or
|
||||||
|
authority to forbid You from making technical modifications
|
||||||
|
necessary to exercise the Licensed Rights, including
|
||||||
|
technical modifications necessary to circumvent Effective
|
||||||
|
Technological Measures. For purposes of this Public License,
|
||||||
|
simply making modifications authorized by this Section 2(a)
|
||||||
|
(4) never produces Adapted Material.
|
||||||
|
|
||||||
|
5. Downstream recipients.
|
||||||
|
|
||||||
|
a. Offer from the Licensor -- Licensed Material. Every
|
||||||
|
recipient of the Licensed Material automatically
|
||||||
|
receives an offer from the Licensor to exercise the
|
||||||
|
Licensed Rights under the terms and conditions of this
|
||||||
|
Public License.
|
||||||
|
|
||||||
|
b. No downstream restrictions. You may not offer or impose
|
||||||
|
any additional or different terms or conditions on, or
|
||||||
|
apply any Effective Technological Measures to, the
|
||||||
|
Licensed Material if doing so restricts exercise of the
|
||||||
|
Licensed Rights by any recipient of the Licensed
|
||||||
|
Material.
|
||||||
|
|
||||||
|
6. No endorsement. Nothing in this Public License constitutes or
|
||||||
|
may be construed as permission to assert or imply that You
|
||||||
|
are, or that Your use of the Licensed Material is, connected
|
||||||
|
with, or sponsored, endorsed, or granted official status by,
|
||||||
|
the Licensor or others designated to receive attribution as
|
||||||
|
provided in Section 3(a)(1)(A)(i).
|
||||||
|
|
||||||
|
b. Other rights.
|
||||||
|
|
||||||
|
1. Moral rights, such as the right of integrity, are not
|
||||||
|
licensed under this Public License, nor are publicity,
|
||||||
|
privacy, and/or other similar personality rights; however, to
|
||||||
|
the extent possible, the Licensor waives and/or agrees not to
|
||||||
|
assert any such rights held by the Licensor to the limited
|
||||||
|
extent necessary to allow You to exercise the Licensed
|
||||||
|
Rights, but not otherwise.
|
||||||
|
|
||||||
|
2. Patent and trademark rights are not licensed under this
|
||||||
|
Public License.
|
||||||
|
|
||||||
|
3. To the extent possible, the Licensor waives any right to
|
||||||
|
collect royalties from You for the exercise of the Licensed
|
||||||
|
Rights, whether directly or through a collecting society
|
||||||
|
under any voluntary or waivable statutory or compulsory
|
||||||
|
licensing scheme. In all other cases the Licensor expressly
|
||||||
|
reserves any right to collect such royalties.
|
||||||
|
|
||||||
|
|
||||||
|
Section 3 -- License Conditions.
|
||||||
|
|
||||||
|
Your exercise of the Licensed Rights is expressly made subject to the
|
||||||
|
following conditions.
|
||||||
|
|
||||||
|
a. Attribution.
|
||||||
|
|
||||||
|
1. If You Share the Licensed Material (including in modified
|
||||||
|
form), You must:
|
||||||
|
|
||||||
|
a. retain the following if it is supplied by the Licensor
|
||||||
|
with the Licensed Material:
|
||||||
|
|
||||||
|
i. identification of the creator(s) of the Licensed
|
||||||
|
Material and any others designated to receive
|
||||||
|
attribution, in any reasonable manner requested by
|
||||||
|
the Licensor (including by pseudonym if
|
||||||
|
designated);
|
||||||
|
|
||||||
|
ii. a copyright notice;
|
||||||
|
|
||||||
|
iii. a notice that refers to this Public License;
|
||||||
|
|
||||||
|
iv. a notice that refers to the disclaimer of
|
||||||
|
warranties;
|
||||||
|
|
||||||
|
v. a URI or hyperlink to the Licensed Material to the
|
||||||
|
extent reasonably practicable;
|
||||||
|
|
||||||
|
b. indicate if You modified the Licensed Material and
|
||||||
|
retain an indication of any previous modifications; and
|
||||||
|
|
||||||
|
c. indicate the Licensed Material is licensed under this
|
||||||
|
Public License, and include the text of, or the URI or
|
||||||
|
hyperlink to, this Public License.
|
||||||
|
|
||||||
|
2. You may satisfy the conditions in Section 3(a)(1) in any
|
||||||
|
reasonable manner based on the medium, means, and context in
|
||||||
|
which You Share the Licensed Material. For example, it may be
|
||||||
|
reasonable to satisfy the conditions by providing a URI or
|
||||||
|
hyperlink to a resource that includes the required
|
||||||
|
information.
|
||||||
|
|
||||||
|
3. If requested by the Licensor, You must remove any of the
|
||||||
|
information required by Section 3(a)(1)(A) to the extent
|
||||||
|
reasonably practicable.
|
||||||
|
|
||||||
|
4. If You Share Adapted Material You produce, the Adapter's
|
||||||
|
License You apply must not prevent recipients of the Adapted
|
||||||
|
Material from complying with this Public License.
|
||||||
|
|
||||||
|
|
||||||
|
Section 4 -- Sui Generis Database Rights.
|
||||||
|
|
||||||
|
Where the Licensed Rights include Sui Generis Database Rights that
|
||||||
|
apply to Your use of the Licensed Material:
|
||||||
|
|
||||||
|
a. for the avoidance of doubt, Section 2(a)(1) grants You the right
|
||||||
|
to extract, reuse, reproduce, and Share all or a substantial
|
||||||
|
portion of the contents of the database;
|
||||||
|
|
||||||
|
b. if You include all or a substantial portion of the database
|
||||||
|
contents in a database in which You have Sui Generis Database
|
||||||
|
Rights, then the database in which You have Sui Generis Database
|
||||||
|
Rights (but not its individual contents) is Adapted Material; and
|
||||||
|
|
||||||
|
c. You must comply with the conditions in Section 3(a) if You Share
|
||||||
|
all or a substantial portion of the contents of the database.
|
||||||
|
|
||||||
|
For the avoidance of doubt, this Section 4 supplements and does not
|
||||||
|
replace Your obligations under this Public License where the Licensed
|
||||||
|
Rights include other Copyright and Similar Rights.
|
||||||
|
|
||||||
|
|
||||||
|
Section 5 -- Disclaimer of Warranties and Limitation of Liability.
|
||||||
|
|
||||||
|
a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
|
||||||
|
EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
|
||||||
|
AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
|
||||||
|
ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
|
||||||
|
IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
|
||||||
|
WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
|
||||||
|
ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
|
||||||
|
KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
|
||||||
|
ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
|
||||||
|
|
||||||
|
b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
|
||||||
|
TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
|
||||||
|
NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
|
||||||
|
INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
|
||||||
|
COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
|
||||||
|
USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
|
||||||
|
ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
|
||||||
|
DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
|
||||||
|
IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
|
||||||
|
|
||||||
|
c. The disclaimer of warranties and limitation of liability provided
|
||||||
|
above shall be interpreted in a manner that, to the extent
|
||||||
|
possible, most closely approximates an absolute disclaimer and
|
||||||
|
waiver of all liability.
|
||||||
|
|
||||||
|
|
||||||
|
Section 6 -- Term and Termination.
|
||||||
|
|
||||||
|
a. This Public License applies for the term of the Copyright and
|
||||||
|
Similar Rights licensed here. However, if You fail to comply with
|
||||||
|
this Public License, then Your rights under this Public License
|
||||||
|
terminate automatically.
|
||||||
|
|
||||||
|
b. Where Your right to use the Licensed Material has terminated under
|
||||||
|
Section 6(a), it reinstates:
|
||||||
|
|
||||||
|
1. automatically as of the date the violation is cured, provided
|
||||||
|
it is cured within 30 days of Your discovery of the
|
||||||
|
violation; or
|
||||||
|
|
||||||
|
2. upon express reinstatement by the Licensor.
|
||||||
|
|
||||||
|
For the avoidance of doubt, this Section 6(b) does not affect any
|
||||||
|
right the Licensor may have to seek remedies for Your violations
|
||||||
|
of this Public License.
|
||||||
|
|
||||||
|
c. For the avoidance of doubt, the Licensor may also offer the
|
||||||
|
Licensed Material under separate terms or conditions or stop
|
||||||
|
distributing the Licensed Material at any time; however, doing so
|
||||||
|
will not terminate this Public License.
|
||||||
|
|
||||||
|
d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
|
||||||
|
License.
|
||||||
|
|
||||||
|
|
||||||
|
Section 7 -- Other Terms and Conditions.
|
||||||
|
|
||||||
|
a. The Licensor shall not be bound by any additional or different
|
||||||
|
terms or conditions communicated by You unless expressly agreed.
|
||||||
|
|
||||||
|
b. Any arrangements, understandings, or agreements regarding the
|
||||||
|
Licensed Material not stated herein are separate from and
|
||||||
|
independent of the terms and conditions of this Public License.
|
||||||
|
|
||||||
|
|
||||||
|
Section 8 -- Interpretation.
|
||||||
|
|
||||||
|
a. For the avoidance of doubt, this Public License does not, and
|
||||||
|
shall not be interpreted to, reduce, limit, restrict, or impose
|
||||||
|
conditions on any use of the Licensed Material that could lawfully
|
||||||
|
be made without permission under this Public License.
|
||||||
|
|
||||||
|
b. To the extent possible, if any provision of this Public License is
|
||||||
|
deemed unenforceable, it shall be automatically reformed to the
|
||||||
|
minimum extent necessary to make it enforceable. If the provision
|
||||||
|
cannot be reformed, it shall be severed from this Public License
|
||||||
|
without affecting the enforceability of the remaining terms and
|
||||||
|
conditions.
|
||||||
|
|
||||||
|
c. No term or condition of this Public License will be waived and no
|
||||||
|
failure to comply consented to unless expressly agreed to by the
|
||||||
|
Licensor.
|
||||||
|
|
||||||
|
d. Nothing in this Public License constitutes or may be interpreted
|
||||||
|
as a limitation upon, or waiver of, any privileges and immunities
|
||||||
|
that apply to the Licensor or You, including from the legal
|
||||||
|
processes of any jurisdiction or authority.
|
||||||
|
|
||||||
|
|
||||||
|
=======================================================================
|
||||||
|
|
||||||
|
Creative Commons is not a party to its public
|
||||||
|
licenses. Notwithstanding, Creative Commons may elect to apply one of
|
||||||
|
its public licenses to material it publishes and in those instances
|
||||||
|
will be considered the “Licensor.” The text of the Creative Commons
|
||||||
|
public licenses is dedicated to the public domain under the CC0 Public
|
||||||
|
Domain Dedication. Except for the limited purpose of indicating that
|
||||||
|
material is shared under a Creative Commons public license or as
|
||||||
|
otherwise permitted by the Creative Commons policies published at
|
||||||
|
creativecommons.org/policies, Creative Commons does not authorize the
|
||||||
|
use of the trademark "Creative Commons" or any other trademark or logo
|
||||||
|
of Creative Commons without its prior written consent including,
|
||||||
|
without limitation, in connection with any unauthorized modifications
|
||||||
|
to any of its public licenses or any other arrangements,
|
||||||
|
understandings, or agreements concerning use of licensed material. For
|
||||||
|
the avoidance of doubt, this paragraph does not form part of the
|
||||||
|
public licenses.
|
||||||
|
|
||||||
|
Creative Commons may be contacted at creativecommons.org.
|
||||||
23
README.md
Normal file
23
README.md
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
# Engineering Handbook
|
||||||
|
|
||||||
|
Engineering conventions and best practices for Sea Haven Industries.
|
||||||
|
|
||||||
|
## Contents
|
||||||
|
|
||||||
|
- [Naming Conventions](naming-conventions.md) -- kebab-case everywhere, no exceptions
|
||||||
|
- [Git Workflow](git-workflow.md) -- feature branches, incremental commits, deploy-then-merge
|
||||||
|
- [Commit Messages](commit-messages.md) -- imperative mood, 50/72 rule, explain "why"
|
||||||
|
- [Pull Requests](pull-requests.md) -- scope, title, description format, merge strategy
|
||||||
|
- [Code Review](code-review.md) -- what to look for, giving feedback, turnaround expectations
|
||||||
|
- [GitHub Standards](github-standards.md) -- branch defaults, repo hygiene, Dependabot
|
||||||
|
- [AWS Infrastructure](aws-infrastructure.md) -- SAM vs CDK, Lambda defaults, CloudFormation
|
||||||
|
- [SAM Project Layout](sam-project-layout.md) -- standard directory structure for serverless projects
|
||||||
|
- [Secrets and Configuration](secrets-and-config.md) -- Secrets Manager vs SSM Parameter Store
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
See [CONTRIBUTING.md](CONTRIBUTING.md).
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
This work is licensed under [CC-BY-4.0](https://creativecommons.org/licenses/by/4.0/). The commit messages section adapts content from [commit-messages-guide](https://github.com/RomuloOliveira/commit-messages-guide) by Romulo Oliveira, also licensed under CC-BY-4.0.
|
||||||
45
aws-infrastructure.md
Normal file
45
aws-infrastructure.md
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
# AWS Infrastructure
|
||||||
|
|
||||||
|
## IaC Strategy
|
||||||
|
|
||||||
|
- **SAM** is the default for new serverless stacks (Lambda + API Gateway + DynamoDB)
|
||||||
|
- **CDK** only for complex infrastructure (ECS, VPCs, multi-service compositions)
|
||||||
|
- Every deployed resource should be managed by CloudFormation
|
||||||
|
- No manually-created Lambdas, roles, or other resources outside of IaC
|
||||||
|
|
||||||
|
## Lambda Defaults
|
||||||
|
|
||||||
|
These apply to every Lambda in every project. Verify, don't assume.
|
||||||
|
|
||||||
|
| Setting | Value |
|
||||||
|
|---|---|
|
||||||
|
| Runtime | Python 3.12 or Node 22.x |
|
||||||
|
| Architecture | arm64 |
|
||||||
|
| Log retention | 60 days (explicit in IaC template) |
|
||||||
|
| Naming | kebab-case, matching the stack name prefix |
|
||||||
|
|
||||||
|
Never rely on the CloudWatch default for log retention. Always set `RetentionInDays` explicitly in the template.
|
||||||
|
|
||||||
|
## CloudFormation Outputs
|
||||||
|
|
||||||
|
Every stack should export:
|
||||||
|
|
||||||
|
- Function ARNs
|
||||||
|
- Any externally-consumable URLs (API Gateway endpoints, etc.)
|
||||||
|
|
||||||
|
## S3
|
||||||
|
|
||||||
|
- Every non-CloudFormation bucket must have `Purpose` and `ManagedBy` tags
|
||||||
|
- Define lifecycle policies in the IaC template
|
||||||
|
- Use Glacier Deep Archive for archival data
|
||||||
|
|
||||||
|
## README
|
||||||
|
|
||||||
|
Every repo must have a README that accurately describes:
|
||||||
|
|
||||||
|
- Project architecture
|
||||||
|
- Lambdas and services
|
||||||
|
- Data flow
|
||||||
|
- Configuration requirements
|
||||||
|
|
||||||
|
Update the README in the same commit where functionality changes. If a README is missing or outdated when you start working on a project, fix it as part of the current work.
|
||||||
47
code-review.md
Normal file
47
code-review.md
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
# Code Review
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
|
||||||
|
Code review exists to catch defects, share knowledge, and maintain consistency. It is not a gatekeeping exercise.
|
||||||
|
|
||||||
|
## What Reviewers Should Look For
|
||||||
|
|
||||||
|
### Always check
|
||||||
|
|
||||||
|
- Does the change do what the PR description says it does?
|
||||||
|
- Are there obvious bugs, edge cases, or error handling gaps?
|
||||||
|
- Does it follow [naming conventions](naming-conventions.md)?
|
||||||
|
- Are secrets handled correctly per [secrets-and-config.md](secrets-and-config.md)?
|
||||||
|
- If AWS resources changed, are Lambda defaults correct per [aws-infrastructure.md](aws-infrastructure.md)?
|
||||||
|
|
||||||
|
### Watch for
|
||||||
|
|
||||||
|
- Unused code, dead imports, or leftover debug statements
|
||||||
|
- Missing or outdated README updates for functionality changes
|
||||||
|
- Hardcoded values that should be in config or Secrets Manager
|
||||||
|
- Security concerns (input validation, injection, overly broad IAM policies)
|
||||||
|
|
||||||
|
### Don't nitpick
|
||||||
|
|
||||||
|
- Minor formatting differences handled by linters
|
||||||
|
- Personal style preferences that don't affect correctness
|
||||||
|
- Naming choices that are reasonable even if you'd pick something different
|
||||||
|
|
||||||
|
## Giving Feedback
|
||||||
|
|
||||||
|
- Be specific. "This might fail if the list is empty" is useful. "Needs work" is not.
|
||||||
|
- Distinguish between must-fix and suggestions. Prefix optional feedback with "nit:" or "suggestion:"
|
||||||
|
- Ask questions instead of making assumptions. "Is this intentional?" is better than "This is wrong."
|
||||||
|
- If a PR is good, say so. A simple "Looks good" is fine.
|
||||||
|
|
||||||
|
## Turnaround
|
||||||
|
|
||||||
|
- Aim to review within one business day of being requested
|
||||||
|
- If you can't review in time, say so and suggest another reviewer
|
||||||
|
- Don't let PRs sit in review for days without feedback
|
||||||
|
|
||||||
|
## Approving
|
||||||
|
|
||||||
|
- Approve when you're confident the change is correct and complete
|
||||||
|
- If you left suggestions but the PR is otherwise good, approve with comments rather than blocking
|
||||||
|
- One approval is sufficient for most changes
|
||||||
83
commit-messages.md
Normal file
83
commit-messages.md
Normal file
|
|
@ -0,0 +1,83 @@
|
||||||
|
# Commit Messages
|
||||||
|
|
||||||
|
> Adapted from [commit-messages-guide](https://github.com/RomuloOliveira/commit-messages-guide) by Romulo Oliveira, licensed under [CC-BY-4.0](https://creativecommons.org/licenses/by/4.0/).
|
||||||
|
|
||||||
|
## Rules
|
||||||
|
|
||||||
|
### Use imperative mood
|
||||||
|
|
||||||
|
Write what the commit *does*, not what you *did*.
|
||||||
|
|
||||||
|
| Good | Bad |
|
||||||
|
|---|---|
|
||||||
|
| Add retry logic to payment processor | Added retry logic to payment processor |
|
||||||
|
| Fix null check in auth handler | Fixed null check in auth handler |
|
||||||
|
| Remove deprecated endpoint | Removing deprecated endpoint |
|
||||||
|
|
||||||
|
### Capitalize the first letter
|
||||||
|
|
||||||
|
| Good | Bad |
|
||||||
|
|---|---|
|
||||||
|
| Fix null check in auth handler | fix null check in auth handler |
|
||||||
|
|
||||||
|
### Keep the subject line under 50 characters
|
||||||
|
|
||||||
|
The subject line is for scanning. Details go in the body.
|
||||||
|
|
||||||
|
### Wrap the body at 72 characters
|
||||||
|
|
||||||
|
If you need to explain more, add a blank line after the subject and write a body wrapped at 72 characters per line.
|
||||||
|
|
||||||
|
### Explain "why," not "what"
|
||||||
|
|
||||||
|
The diff shows what changed. The commit message should explain why.
|
||||||
|
|
||||||
|
| Good | Bad |
|
||||||
|
|---|---|
|
||||||
|
| Increase timeout to handle slow upstream responses | Change timeout from 30 to 60 |
|
||||||
|
| Switch to arm64 to reduce Lambda cold start cost | Update architecture setting |
|
||||||
|
|
||||||
|
### No generic messages
|
||||||
|
|
||||||
|
These are not acceptable:
|
||||||
|
|
||||||
|
- `Fix stuff`
|
||||||
|
- `Update code`
|
||||||
|
- `WIP`
|
||||||
|
- `Misc changes`
|
||||||
|
- `Address review comments`
|
||||||
|
|
||||||
|
Every commit should describe a specific change.
|
||||||
|
|
||||||
|
### No self-referential language
|
||||||
|
|
||||||
|
| Good | Bad |
|
||||||
|
|---|---|
|
||||||
|
| Fix race condition in queue processor | This commit fixes a race condition |
|
||||||
|
| Add input validation for email field | This PR adds validation |
|
||||||
|
| Refactor auth middleware for clarity | I refactored the auth middleware |
|
||||||
|
|
||||||
|
## Template
|
||||||
|
|
||||||
|
```
|
||||||
|
Subject line (50 chars max, imperative, capitalized)
|
||||||
|
|
||||||
|
Optional body wrapped at 72 characters. Explain the problem
|
||||||
|
this commit solves and why this approach was chosen. Mention
|
||||||
|
side effects or non-obvious consequences.
|
||||||
|
|
||||||
|
Refs: #123
|
||||||
|
```
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
```
|
||||||
|
Add retry logic for transient upstream failures
|
||||||
|
|
||||||
|
The payment processor occasionally returns 503 during
|
||||||
|
deployments. Without retries, these surface as user-facing
|
||||||
|
errors. This adds exponential backoff with 3 attempts,
|
||||||
|
which matches the upstream's documented recovery window.
|
||||||
|
|
||||||
|
Refs: #45
|
||||||
|
```
|
||||||
86
git-workflow.md
Normal file
86
git-workflow.md
Normal file
|
|
@ -0,0 +1,86 @@
|
||||||
|
# Git Workflow
|
||||||
|
|
||||||
|
## Branching
|
||||||
|
|
||||||
|
- Never commit directly to `main`
|
||||||
|
- Delete branches after merge
|
||||||
|
- Use the appropriate branch prefix for the type of work:
|
||||||
|
|
||||||
|
| Prefix | Use when |
|
||||||
|
|---|---|
|
||||||
|
| `feature/<description>` | Adding new functionality or enhancing existing features |
|
||||||
|
| `bug/<description>` | Fixing a non-urgent defect found during development or testing |
|
||||||
|
| `hotfix/<description>` | Fixing a production issue that needs immediate attention |
|
||||||
|
|
||||||
|
**bug vs hotfix:** Use `bug/` for defects caught before they affect production (failing tests, broken dev flows, issues found in review). Use `hotfix/` only when production is impacted and the fix needs to bypass normal review cadence.
|
||||||
|
|
||||||
|
## Commits
|
||||||
|
|
||||||
|
- Commit each logical change individually with a descriptive message
|
||||||
|
- See [commit-messages.md](commit-messages.md) for formatting rules
|
||||||
|
- Keep the working tree clean: commit or stash before switching context
|
||||||
|
|
||||||
|
## Deploy-Then-Merge
|
||||||
|
|
||||||
|
The standard flow for changes that deploy to AWS:
|
||||||
|
|
||||||
|
1. Create a feature branch (`feature/add-receipt-parser`)
|
||||||
|
2. Develop and commit locally
|
||||||
|
3. Open a PR via `gh pr create`
|
||||||
|
4. Merge the feature branch into `main` locally
|
||||||
|
5. Deploy to the target environment (`sam deploy`, etc.)
|
||||||
|
6. Verify in production
|
||||||
|
7. Merge the PR on GitHub
|
||||||
|
|
||||||
|
This ensures production works before the PR closes. If the deploy fails, the PR stays open and `main` on GitHub is still clean.
|
||||||
|
|
||||||
|
## Push Discipline
|
||||||
|
|
||||||
|
- Push regularly; don't accumulate unpushed commits
|
||||||
|
- Never force push `main`
|
||||||
|
- Never amend or rewrite commits already pushed to `main`
|
||||||
|
- If you need to add context to a past change, use PR descriptions or issue comments
|
||||||
|
|
||||||
|
## Versioning
|
||||||
|
|
||||||
|
Use [Semantic Versioning](https://semver.org/) (SemVer) as the standard: `MAJOR.MINOR.PATCH`.
|
||||||
|
|
||||||
|
| Increment | When |
|
||||||
|
|---|---|
|
||||||
|
| `MAJOR` | Breaking changes to the public API or contract (removed endpoints, changed request/response shapes, incompatible config changes) |
|
||||||
|
| `MINOR` | New functionality that is backwards-compatible (new endpoints, new optional fields, new features) |
|
||||||
|
| `PATCH` | Backwards-compatible bug fixes, dependency updates, documentation corrections |
|
||||||
|
|
||||||
|
### When to version
|
||||||
|
|
||||||
|
Not every project needs versioning. Apply SemVer when the project has consumers that depend on its interface:
|
||||||
|
|
||||||
|
| Version | Don't version |
|
||||||
|
|---|---|
|
||||||
|
| Published packages (npm, PyPI) | Internal SAM stacks with no external consumers |
|
||||||
|
| Public APIs with external consumers | One-off scripts and migration tools |
|
||||||
|
| Shared libraries used across repos | Internal tools used only by the team that builds them |
|
||||||
|
| CLIs distributed to users | |
|
||||||
|
|
||||||
|
### How to tag
|
||||||
|
|
||||||
|
Create annotated tags on `main` after the PR is merged:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git tag -a v1.2.0 -m "v1.2.0"
|
||||||
|
git push origin v1.2.0
|
||||||
|
```
|
||||||
|
|
||||||
|
Start at `v0.1.0` for new projects. Move to `v1.0.0` when the interface is stable and has external consumers.
|
||||||
|
|
||||||
|
## Cleaning Up
|
||||||
|
|
||||||
|
After a PR is merged:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git checkout main
|
||||||
|
git pull
|
||||||
|
git branch -d feature/add-receipt-parser
|
||||||
|
```
|
||||||
|
|
||||||
|
Don't let stale local branches or untracked project directories accumulate.
|
||||||
32
github-standards.md
Normal file
32
github-standards.md
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
# GitHub Standards
|
||||||
|
|
||||||
|
## Repository Defaults
|
||||||
|
|
||||||
|
- Default branch: `main`
|
||||||
|
- Every repo gets a one-line description
|
||||||
|
- Default to `private` visibility for org repos
|
||||||
|
- Dependabot alerts and security updates enabled on all active repos
|
||||||
|
|
||||||
|
## Branch Protection
|
||||||
|
|
||||||
|
- Require a PR for merges to `main` (no direct push)
|
||||||
|
- No force push to `main`
|
||||||
|
- No branch deletion for `main`
|
||||||
|
|
||||||
|
## Repo Hygiene
|
||||||
|
|
||||||
|
- Delete feature branches after merge
|
||||||
|
- Archive repos that are no longer actively developed (close issues first)
|
||||||
|
- Don't delete repos unless truly disposable
|
||||||
|
- Scrub all company-specific info from git history before making any repo public
|
||||||
|
|
||||||
|
## Public Repos
|
||||||
|
|
||||||
|
Before making a repo public, verify the entire git history contains no:
|
||||||
|
|
||||||
|
- Phone numbers or customer data
|
||||||
|
- API subdomains or internal URLs
|
||||||
|
- Webhook endpoints
|
||||||
|
- Employee names or internal identifiers
|
||||||
|
|
||||||
|
If sensitive data was committed at any point, start fresh with a clean `git init` rather than rewriting history.
|
||||||
39
naming-conventions.md
Normal file
39
naming-conventions.md
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
# Naming Conventions
|
||||||
|
|
||||||
|
## The Rule
|
||||||
|
|
||||||
|
kebab-case for everything. No exceptions.
|
||||||
|
|
||||||
|
No `snake_case`, `PascalCase`, or mixed styles anywhere.
|
||||||
|
|
||||||
|
## Where It Applies
|
||||||
|
|
||||||
|
| Resource | Example |
|
||||||
|
|---|---|
|
||||||
|
| Repository names | `expense-approval-bot`, `door-unlock-api` |
|
||||||
|
| CloudFormation stack names | `expense-approval-bot` (must match repo name) |
|
||||||
|
| Lambda function names | `expense-approval-bot-process-receipt` |
|
||||||
|
| DynamoDB table names | `expense-approval-bot-receipts` |
|
||||||
|
| S3 bucket names | `expense-approval-bot-uploads` |
|
||||||
|
| Secrets Manager secrets | `expense-approval-bot/slack-signing` |
|
||||||
|
| Feature branches | `feature/add-receipt-parser` |
|
||||||
|
|
||||||
|
## CDK Gotcha
|
||||||
|
|
||||||
|
CDK generates PascalCase stack names by default. Always set an explicit `stackName` (TypeScript) or `stack_name` (Python) in your stack definition to enforce kebab-case.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
new MyStack(app, 'MyStack', {
|
||||||
|
stackName: 'my-stack',
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
| Bad | Good | Why |
|
||||||
|
|---|---|---|
|
||||||
|
| `ExpenseApprovalBot` | `expense-approval-bot` | PascalCase |
|
||||||
|
| `expense_approval_bot` | `expense-approval-bot` | snake_case |
|
||||||
|
| `expenseApprovalBot` | `expense-approval-bot` | camelCase |
|
||||||
|
| `Expense-Approval-Bot` | `expense-approval-bot` | Mixed case |
|
||||||
|
| `feature/AddParser` | `feature/add-parser` | PascalCase in branch |
|
||||||
53
pull-requests.md
Normal file
53
pull-requests.md
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
# Pull Requests
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
Each PR should represent a single logical change. If you find yourself writing "and" in the title, consider splitting it into separate PRs.
|
||||||
|
|
||||||
|
| Good scope | Too broad |
|
||||||
|
|---|---|
|
||||||
|
| Add receipt parser Lambda | Add receipt parser and refactor auth middleware |
|
||||||
|
| Fix timeout in payment processor | Fix timeout and update dependencies |
|
||||||
|
| Update Lambda runtime to Python 3.12 | Update runtime and add new endpoint |
|
||||||
|
|
||||||
|
## Title
|
||||||
|
|
||||||
|
- Keep it under 70 characters
|
||||||
|
- Use imperative mood, same as commit messages
|
||||||
|
- Describe the change, not the ticket
|
||||||
|
|
||||||
|
| Good | Bad |
|
||||||
|
|---|---|
|
||||||
|
| Add retry logic for transient upstream failures | JIRA-123 |
|
||||||
|
| Fix null check in auth handler | Bug fix |
|
||||||
|
| Update Lambda runtime to Python 3.12 | Updates |
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
Use a structured format:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
## Summary
|
||||||
|
Brief explanation of what this PR does and why.
|
||||||
|
|
||||||
|
## Changes
|
||||||
|
- Bullet list of specific changes
|
||||||
|
|
||||||
|
## Test Plan
|
||||||
|
- How you verified this works
|
||||||
|
- What to check during review
|
||||||
|
```
|
||||||
|
|
||||||
|
The summary should explain **why** the change is needed, not just restate the diff. Reviewers can read the code; they need context.
|
||||||
|
|
||||||
|
## When to Open a PR
|
||||||
|
|
||||||
|
- Before deploying to production (see [deploy-then-merge](git-workflow.md) workflow)
|
||||||
|
- When the work is ready for review, not as a draft for parking incomplete work
|
||||||
|
- After verifying locally that the change works as expected
|
||||||
|
|
||||||
|
## Merging
|
||||||
|
|
||||||
|
- Squash merge for feature branches with messy interim commits
|
||||||
|
- Regular merge for branches with clean, meaningful commit history
|
||||||
|
- Delete the branch after merge
|
||||||
48
sam-project-layout.md
Normal file
48
sam-project-layout.md
Normal file
|
|
@ -0,0 +1,48 @@
|
||||||
|
# SAM Project Layout
|
||||||
|
|
||||||
|
## Standard Directory Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
project-name/
|
||||||
|
├── template.yaml # SAM template at root
|
||||||
|
├── samconfig.toml # Deploy config (gitignored)
|
||||||
|
├── samconfig.toml.example # Template for onboarding (committed)
|
||||||
|
├── src/
|
||||||
|
│ ├── function_name/
|
||||||
|
│ │ ├── app.py # Lambda handler
|
||||||
|
│ │ └── requirements.txt # Per-function dependencies
|
||||||
|
│ └── shared/ # Shared layer code (if needed)
|
||||||
|
└── .gitignore
|
||||||
|
```
|
||||||
|
|
||||||
|
## File Purposes
|
||||||
|
|
||||||
|
### `template.yaml`
|
||||||
|
|
||||||
|
The SAM/CloudFormation template. Lives at the project root. Defines all Lambda functions, IAM roles, API Gateway endpoints, DynamoDB tables, and other resources.
|
||||||
|
|
||||||
|
### `samconfig.toml`
|
||||||
|
|
||||||
|
Contains real ARNs, S3 bucket names, and deploy parameters. **Gitignored** because it varies per environment and may contain account-specific values.
|
||||||
|
|
||||||
|
### `samconfig.toml.example`
|
||||||
|
|
||||||
|
A committed template showing the expected structure and parameter names. New contributors copy this to `samconfig.toml` and fill in their values.
|
||||||
|
|
||||||
|
### `src/function_name/`
|
||||||
|
|
||||||
|
One directory per Lambda function. Each contains its own handler (`app.py`) and dependencies (`requirements.txt`). This keeps functions independently deployable and avoids bloating one function with another's dependencies.
|
||||||
|
|
||||||
|
### `src/shared/`
|
||||||
|
|
||||||
|
Optional. Used for code shared across multiple functions, typically deployed as a Lambda layer.
|
||||||
|
|
||||||
|
## Standard .gitignore
|
||||||
|
|
||||||
|
```
|
||||||
|
.aws-sam/
|
||||||
|
__pycache__/
|
||||||
|
*.pyc
|
||||||
|
.env
|
||||||
|
samconfig.toml
|
||||||
|
```
|
||||||
68
secrets-and-config.md
Normal file
68
secrets-and-config.md
Normal file
|
|
@ -0,0 +1,68 @@
|
||||||
|
# Secrets and Configuration
|
||||||
|
|
||||||
|
## The Boundary
|
||||||
|
|
||||||
|
There is a strict separation between sensitive and non-sensitive configuration. No gray areas.
|
||||||
|
|
||||||
|
## AWS Secrets Manager
|
||||||
|
|
||||||
|
Use Secrets Manager for **all** sensitive values:
|
||||||
|
|
||||||
|
- API access tokens and keys
|
||||||
|
- Signing values used for request verification
|
||||||
|
- Webhook URLs that act as implicit authentication
|
||||||
|
- Database connection strings with embedded passwords
|
||||||
|
- Any value that would be dangerous if leaked
|
||||||
|
|
||||||
|
When in doubt about whether something qualifies as sensitive, treat it as sensitive.
|
||||||
|
|
||||||
|
### Naming Convention
|
||||||
|
|
||||||
|
```
|
||||||
|
stack-name/value-name
|
||||||
|
```
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
- `my-stack/slack-signing`
|
||||||
|
- `my-stack/stripe-key`
|
||||||
|
|
||||||
|
## SSM Parameter Store
|
||||||
|
|
||||||
|
Use Parameter Store **only** for non-sensitive configuration:
|
||||||
|
|
||||||
|
- Feature flags
|
||||||
|
- Endpoint URLs (public, non-authenticated)
|
||||||
|
- Schedule expressions
|
||||||
|
- Channel IDs and non-sensitive identifiers
|
||||||
|
|
||||||
|
## Lambda Pattern
|
||||||
|
|
||||||
|
1. Store the sensitive value in Secrets Manager
|
||||||
|
2. Grant the function's IAM role `secretsmanager:GetSecretValue` scoped to only the values it needs
|
||||||
|
3. Read the value on cold start via the AWS SDK
|
||||||
|
4. Cache it in a module-level variable so subsequent invocations reuse it
|
||||||
|
|
||||||
|
```python
|
||||||
|
import boto3
|
||||||
|
import json
|
||||||
|
|
||||||
|
_client = boto3.client('secretsmanager')
|
||||||
|
_cached = None
|
||||||
|
|
||||||
|
def get_config():
|
||||||
|
global _cached
|
||||||
|
if _cached is None:
|
||||||
|
resp = _client.get_secret_value(SecretId='my-stack/config')
|
||||||
|
_cached = json.loads(resp['SecretString'])
|
||||||
|
return _cached
|
||||||
|
|
||||||
|
def handler(event, context):
|
||||||
|
config = get_config()
|
||||||
|
# use config values
|
||||||
|
```
|
||||||
|
|
||||||
|
## What NOT to Do
|
||||||
|
|
||||||
|
- **Never use Lambda environment variables for sensitive values.** Even with `NoEcho` CloudFormation parameters, the values end up as plaintext in the Lambda console and are readable by anyone with `GetFunctionConfiguration` access.
|
||||||
|
- **Never commit `.env` files** containing real values to a repository.
|
||||||
|
- **Never store sensitive values** in Notion, Slack messages, or other plaintext documents.
|
||||||
Loading…
Add table
Reference in a new issue