@mavogel/mvc-projen 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,102 @@
1
+ import { Aspects, CfnOutput, IAspect, Tags } from 'aws-cdk-lib';
2
+ import * as ec2 from 'aws-cdk-lib/aws-ec2';
3
+ import { NagSuppressions } from 'cdk-nag';
4
+ import { Construct, IConstruct } from 'constructs';
5
+ import { CrdExample } from './crd-example/crd-example';
6
+
7
+ /**
8
+ * PlaceholderProps
9
+ */
10
+ export interface PlaceholderProps {
11
+ /**
12
+ * Placeholder
13
+ *
14
+ * @default "placeholder"
15
+ */
16
+ readonly placeholder: string;
17
+
18
+ /**
19
+ * Additional tags to add to the instance
20
+ *
21
+ * @default - {}
22
+ */
23
+ readonly additionalTags?: { [key: string]: string };
24
+ }
25
+
26
+ /**
27
+ * Placeholder class
28
+ */
29
+ export class Placeholder extends Construct {
30
+ public readonly placeholderProp: string;
31
+
32
+ constructor(scope: Construct, id: string, props?: PlaceholderProps) {
33
+ super(scope, id);
34
+
35
+ // defaults
36
+ this.placeholderProp = props?.placeholder ?? 'placeholder';
37
+ // ... more
38
+
39
+ const additionalTags = props?.additionalTags ?? {};
40
+ const defaultTags = { app: 'placeholder' };
41
+
42
+ const mergedTags = { ...defaultTags, ...additionalTags };
43
+ Aspects.of(this).add(new NodeTagger(mergedTags));
44
+
45
+ // resources
46
+ const vpc = new ec2.Vpc(this, 'vpc', {
47
+ vpcName: this.placeholderProp,
48
+ maxAzs: 2,
49
+ createInternetGateway: true,
50
+ subnetConfiguration: [
51
+ {
52
+ name: 'public',
53
+ subnetType: ec2.SubnetType.PUBLIC,
54
+ },
55
+ ],
56
+ enableDnsHostnames: true,
57
+ enableDnsSupport: true,
58
+ });
59
+ NagSuppressions.addResourceSuppressions(
60
+ [vpc],
61
+ [
62
+ {
63
+ id: 'AwsSolutions-VPC7',
64
+ reason: 'For this tmp vpc we do not need flow logs',
65
+ },
66
+ ],
67
+ true,
68
+ );
69
+
70
+ // crd example
71
+ // Have a custom resource to pass the secret data on? -> yes because not resolvable on compile time
72
+ const crdExample = CrdExample.new({
73
+ secretArn: 'dummy-secretArn',
74
+ })._bind(this);
75
+
76
+ const dummyPassword = crdExample.secretPasswordPlaintext;
77
+ console.log(dummyPassword);
78
+
79
+ // outputs
80
+ new CfnOutput(this, 'placeholder', {
81
+ description: 'The placeholder',
82
+ value: this.placeholderProp,
83
+ });
84
+ }
85
+ }
86
+
87
+ /**
88
+ * Tags all the resources in the construct
89
+ */
90
+ class NodeTagger implements IAspect {
91
+ private readonly tags: { [key: string]: string };
92
+
93
+ constructor(tags: { [key: string]: string }) {
94
+ this.tags = tags;
95
+ }
96
+
97
+ visit(node: IConstruct) {
98
+ Object.entries(this.tags).forEach(([key, value]) =>
99
+ Tags.of(node).add(key, value),
100
+ );
101
+ }
102
+ }
@@ -0,0 +1,69 @@
1
+ // UNCOMMENT
2
+ // const spyGetSecretValue = jest.fn();
3
+ // const spySecM = jest.fn(() => ({
4
+ // getSecretValue: spyGetSecretValue,
5
+ // }));
6
+
7
+ // Mock the SSM client
8
+ // jest.mock("@aws-sdk/client-secrets-manager", () => ({
9
+ // SecretsManager: spySecM,
10
+ // }));
11
+
12
+ // eslint-disable-next-line import/no-unresolved
13
+ // import type { OnEventRequest } from 'aws-cdk-lib/custom-resources/lib/provider-framework/types';
14
+ // import { handler } from '../../src/crd-example/crd-example.lambda'; // <- UNCOMMENT
15
+
16
+ describe('secret-retriever lambda', () => {
17
+ beforeEach(() => {
18
+ // Reset mocks before each test
19
+ jest.resetModules();
20
+ jest.clearAllMocks();
21
+ });
22
+
23
+ afterEach(() => {});
24
+
25
+ test('should handle successful Secret retrieval', async () => {
26
+ // UNCOMMENT
27
+ // const secretString = '{"username":"john","password":"foobar"}';
28
+ // spyGetSecretValue.mockImplementation(() => ({
29
+ // SecretString: secretString,
30
+ // }));
31
+
32
+ // const secretArn = 'arn:123';
33
+ // const event = {
34
+ // RequestType: 'Create',
35
+ // ResourceProperties: {
36
+ // SecretArn: secretArn,
37
+ // },
38
+ // } as unknown as OnEventRequest;
39
+
40
+ // const result = await handler(event);
41
+
42
+ // expect(spyGetSecretValue).toHaveBeenCalledWith({
43
+ // SecretId: secretArn,
44
+ // });
45
+
46
+ // expect(result).toEqual({
47
+ // Data: {
48
+ // secretPasswordValue: "foobar",
49
+ // },
50
+ // });
51
+ });
52
+
53
+ test('should fail to handle Secret retrieval', async () => {
54
+ // UNCOMMENT
55
+ // const errorMessage = 'Failed to retrieve secret';
56
+ // spyGetSecretValue.mockImplementation(() => {
57
+ // throw new Error(errorMessage);
58
+ // });
59
+
60
+ // const event = {
61
+ // RequestType: 'Create',
62
+ // ResourceProperties: {
63
+ // SecretArn: 'arn:123',
64
+ // },
65
+ // } as unknown as OnEventRequest;
66
+
67
+ // await expect(handler(event)).rejects.toThrow(errorMessage);
68
+ });
69
+ });
@@ -0,0 +1,51 @@
1
+ import { App, Aspects, Stack } from 'aws-cdk-lib';
2
+ import { Annotations, Match } from 'aws-cdk-lib/assertions';
3
+ import { AwsSolutionsChecks } from 'cdk-nag';
4
+ import { Placeholder } from '../src';
5
+
6
+ describe('placeholder-nag-AwsSolutions-Pack', () => {
7
+ let stack: Stack;
8
+ let app: App;
9
+ // In this case we can use beforeAll() over beforeEach() since our tests
10
+ // do not modify the state of the application
11
+ beforeAll(() => {
12
+ // GIVEN
13
+ app = new App();
14
+ stack = new Stack(app, 'testStack', {
15
+ env: {
16
+ region: 'us-east-1',
17
+ account: '1234',
18
+ },
19
+ });
20
+
21
+ new Placeholder(stack, 'Placeholder', {
22
+ placeholder: 'placeholder',
23
+ });
24
+ // suppressCommonNags(stack);
25
+
26
+ // WHEN
27
+ Aspects.of(stack).add(new AwsSolutionsChecks({ verbose: true }));
28
+ });
29
+
30
+ // THEN
31
+ test('No unsuppressed Warnings', () => {
32
+ const warnings = Annotations.fromStack(stack).findWarning(
33
+ '*',
34
+ Match.stringLikeRegexp('AwsSolutions-.*'),
35
+ );
36
+ expect(warnings).toHaveLength(0);
37
+ });
38
+
39
+ test('No unsuppressed Errors', () => {
40
+ const errors = Annotations.fromStack(stack).findError(
41
+ '*',
42
+ Match.stringLikeRegexp('AwsSolutions-.*'),
43
+ );
44
+ if (errors.length > 0) {
45
+ for (const error of errors) {
46
+ console.log(`id: '${error.id}': ${error.entry.data}`);
47
+ }
48
+ }
49
+ expect(errors).toHaveLength(0);
50
+ });
51
+ });
@@ -0,0 +1,70 @@
1
+ # Contributing Guidelines
2
+
3
+ Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional
4
+ documentation, we greatly value feedback and contributions from our community.
5
+
6
+ Please read through this document before submitting any issues or pull requests to ensure we have all the necessary
7
+ information to effectively respond to your bug report or contribution.
8
+
9
+
10
+ ## Reporting Bugs/Feature Requests
11
+
12
+ We welcome you to use the GitHub issue tracker to report bugs or suggest features.
13
+
14
+ When filing an issue, please check existing open, or recently closed, issues to make sure somebody else hasn't already
15
+ reported the issue. Please try to include as much information as you can. Details like these are incredibly useful:
16
+
17
+ * A reproducible test case or series of steps
18
+ * The version of our code being used
19
+ * Any modifications you've made relevant to the bug
20
+ * Anything unusual about your environment or deployment
21
+
22
+
23
+ ## Contributing via Pull Requests
24
+ Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that:
25
+
26
+ 1. You are working against the latest source on the *main* branch.
27
+ 2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already.
28
+ 3. You open an issue to discuss any significant work - we would hate for your time to be wasted.
29
+
30
+ To send us a pull request, please:
31
+
32
+ 1. Fork the repository.
33
+ 2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change.
34
+ 3. Ensure local tests pass -> `npm test`
35
+ 4. The integ tests will run separately in the AWS account of the owner of the project.
36
+ 5. Build the project -> `npm build` to also update the `API.md` file.
37
+ ```bash
38
+ # do this within the container as we build jsii for multiple targets
39
+ docker run -it --rm -v $(pwd):/source -w /source --user 0:0 public.ecr.aws/jsii/superchain:1-bookworm-slim-node22 bash
40
+ # clean node_modules for fresh dependencies for the OS within the container
41
+ rm -rf node_modules
42
+ npm ci
43
+ # now build it
44
+ npx projen build
45
+ # also check for awscdk linting, which checks the API.md
46
+ npm run awslint
47
+ ```
48
+ 6. Commit to your fork using clear commit messages.
49
+ 7. Send us a pull request, answering any default questions in the pull request interface.
50
+ 8. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation.
51
+
52
+ GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and
53
+ [creating a pull request](https://help.github.com/articles/creating-a-pull-request/).
54
+
55
+
56
+ ## Finding contributions to work on
57
+ Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any 'help wanted' issues is a great place to start.
58
+
59
+
60
+ ## Code of Conduct
61
+ See the [Code of Conduct](CODE_OF_CONDUCT) file or contact `info@manuel-vogel.de` with any additional questions or comments.
62
+
63
+
64
+ ## Security issue notifications
65
+ If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue.
66
+
67
+
68
+ ## Licensing
69
+
70
+ See the [LICENSE](LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution.
@@ -0,0 +1,81 @@
1
+ <mxfile host="65bd71144e">
2
+ <diagram id="Ht1M8jgEwFfnCIfOTk4-" name="Page-1">
3
+ <mxGraphModel dx="2147" dy="364" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1169" pageHeight="827" math="0" shadow="0">
4
+ <root>
5
+ <mxCell id="0"/>
6
+ <mxCell id="1" parent="0"/>
7
+ <mxCell id="UEzPUAAOIrF-is8g5C7q-74" value="AWS Cloud" style="points=[[0,0],[0.25,0],[0.5,0],[0.75,0],[1,0],[1,0.25],[1,0.5],[1,0.75],[1,1],[0.75,1],[0.5,1],[0.25,1],[0,1],[0,0.75],[0,0.5],[0,0.25]];outlineConnect=0;gradientColor=none;html=1;whiteSpace=wrap;fontSize=12;fontStyle=0;shape=mxgraph.aws4.group;grIcon=mxgraph.aws4.group_aws_cloud_alt;strokeColor=#232F3E;fillColor=none;verticalAlign=top;align=left;spacingLeft=30;fontColor=#232F3E;dashed=0;labelBackgroundColor=#ffffff;container=1;pointerEvents=0;collapsible=0;recursiveResize=0;" parent="1" vertex="1">
8
+ <mxGeometry x="70" y="100" width="860" height="690" as="geometry"/>
9
+ </mxCell>
10
+ <mxCell id="1NWmoB_3eEeEF4lO7WTZ-13" value="Public subnet" style="points=[[0,0],[0.25,0],[0.5,0],[0.75,0],[1,0],[1,0.25],[1,0.5],[1,0.75],[1,1],[0.75,1],[0.5,1],[0.25,1],[0,1],[0,0.75],[0,0.5],[0,0.25]];outlineConnect=0;gradientColor=none;html=1;whiteSpace=wrap;fontSize=12;fontStyle=0;container=1;pointerEvents=0;collapsible=0;recursiveResize=0;shape=mxgraph.aws4.group;grIcon=mxgraph.aws4.group_security_group;grStroke=0;strokeColor=#7AA116;fillColor=#F2F6E8;verticalAlign=top;align=left;spacingLeft=30;fontColor=#248814;dashed=0;" parent="UEzPUAAOIrF-is8g5C7q-74" vertex="1">
11
+ <mxGeometry x="55.5" y="68" width="744.5" height="572" as="geometry"/>
12
+ </mxCell>
13
+ <mxCell id="1NWmoB_3eEeEF4lO7WTZ-1" value="VPC" style="sketch=0;outlineConnect=0;gradientColor=none;html=1;whiteSpace=wrap;fontSize=12;fontStyle=0;shape=mxgraph.aws4.group;grIcon=mxgraph.aws4.group_vpc;strokeColor=#879196;fillColor=none;verticalAlign=top;align=left;spacingLeft=30;fontColor=#879196;dashed=0;" parent="1NWmoB_3eEeEF4lO7WTZ-13" vertex="1">
14
+ <mxGeometry x="-30" y="-30" width="810" height="630" as="geometry"/>
15
+ </mxCell>
16
+ <mxCell id="1NWmoB_3eEeEF4lO7WTZ-16" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1NWmoB_3eEeEF4lO7WTZ-13" edge="1">
17
+ <mxGeometry relative="1" as="geometry">
18
+ <mxPoint x="402.5" y="246" as="sourcePoint"/>
19
+ <mxPoint x="264.5" y="330" as="targetPoint"/>
20
+ </mxGeometry>
21
+ </mxCell>
22
+ <mxCell id="3" value="" style="edgeStyle=none;html=1;" edge="1" parent="1NWmoB_3eEeEF4lO7WTZ-13">
23
+ <mxGeometry relative="1" as="geometry">
24
+ <mxPoint x="441.5" y="285" as="sourcePoint"/>
25
+ <mxPoint x="441.5" y="365" as="targetPoint"/>
26
+ </mxGeometry>
27
+ </mxCell>
28
+ <mxCell id="1NWmoB_3eEeEF4lO7WTZ-31" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1NWmoB_3eEeEF4lO7WTZ-13" edge="1">
29
+ <mxGeometry relative="1" as="geometry">
30
+ <mxPoint x="616.5" y="120" as="sourcePoint"/>
31
+ <mxPoint x="616.5" y="382.0239361702128" as="targetPoint"/>
32
+ </mxGeometry>
33
+ </mxCell>
34
+ <mxCell id="1NWmoB_3eEeEF4lO7WTZ-33" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1NWmoB_3eEeEF4lO7WTZ-13" edge="1">
35
+ <mxGeometry relative="1" as="geometry">
36
+ <Array as="points">
37
+ <mxPoint x="525" y="82"/>
38
+ <mxPoint x="525" y="82"/>
39
+ </Array>
40
+ <mxPoint x="577.5" y="82" as="sourcePoint"/>
41
+ <mxPoint x="481.5" y="82" as="targetPoint"/>
42
+ </mxGeometry>
43
+ </mxCell>
44
+ <mxCell id="1NWmoB_3eEeEF4lO7WTZ-23" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1NWmoB_3eEeEF4lO7WTZ-13" edge="1">
45
+ <mxGeometry relative="1" as="geometry">
46
+ <mxPoint x="162.25" y="120" as="sourcePoint"/>
47
+ <mxPoint x="162.25" y="292" as="targetPoint"/>
48
+ </mxGeometry>
49
+ </mxCell>
50
+ <mxCell id="1NWmoB_3eEeEF4lO7WTZ-27" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1NWmoB_3eEeEF4lO7WTZ-13" edge="1">
51
+ <mxGeometry relative="1" as="geometry">
52
+ <mxPoint x="479.5" y="421" as="sourcePoint"/>
53
+ <mxPoint x="584.5" y="421" as="targetPoint"/>
54
+ </mxGeometry>
55
+ </mxCell>
56
+ <mxCell id="1NWmoB_3eEeEF4lO7WTZ-21" value="&lt;span style=&quot;text-wrap-mode: nowrap;&quot;&gt;SecGroup Port 80&amp;nbsp;&lt;/span&gt;&lt;br style=&quot;padding: 0px; margin: 0px; text-wrap-mode: nowrap;&quot;&gt;&lt;span style=&quot;text-wrap-mode: nowrap;&quot;&gt;from PrefixListId&lt;/span&gt;" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1NWmoB_3eEeEF4lO7WTZ-13" vertex="1">
57
+ <mxGeometry x="93.5" y="492" width="107.75" height="30" as="geometry"/>
58
+ </mxCell>
59
+ <mxCell id="1NWmoB_3eEeEF4lO7WTZ-36" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1NWmoB_3eEeEF4lO7WTZ-13" edge="1">
60
+ <mxGeometry relative="1" as="geometry">
61
+ <mxPoint x="401.5" y="421" as="sourcePoint"/>
62
+ <mxPoint x="162.30000000000018" y="370" as="targetPoint"/>
63
+ </mxGeometry>
64
+ </mxCell>
65
+ <mxCell id="1NWmoB_3eEeEF4lO7WTZ-14" value="" style="sketch=0;pointerEvents=1;shadow=0;dashed=0;html=1;strokeColor=none;fillColor=#434445;aspect=fixed;labelPosition=center;verticalLabelPosition=bottom;verticalAlign=top;align=center;outlineConnect=0;shape=mxgraph.vvd.web_browser;" parent="1" vertex="1">
66
+ <mxGeometry x="-20" y="231.25" width="50" height="35.5" as="geometry"/>
67
+ </mxCell>
68
+ <mxCell id="1NWmoB_3eEeEF4lO7WTZ-15" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="1NWmoB_3eEeEF4lO7WTZ-14" edge="1">
69
+ <mxGeometry relative="1" as="geometry">
70
+ <mxPoint x="248.75" y="249" as="targetPoint"/>
71
+ </mxGeometry>
72
+ </mxCell>
73
+ <mxCell id="1NWmoB_3eEeEF4lO7WTZ-29" value="https access" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="1NWmoB_3eEeEF4lO7WTZ-15" vertex="1" connectable="0">
74
+ <mxGeometry x="-0.3846" y="4" relative="1" as="geometry">
75
+ <mxPoint as="offset"/>
76
+ </mxGeometry>
77
+ </mxCell>
78
+ </root>
79
+ </mxGraphModel>
80
+ </diagram>
81
+ </mxfile>
@@ -0,0 +1,39 @@
1
+ ---
2
+ name: "\U0001F41B Bug Report"
3
+ about: "If something isn't working as expected \U0001F914."
4
+ title: ''
5
+ labels: 'i: bug, i: needs triage'
6
+ assignees: ''
7
+
8
+ ---
9
+
10
+ ## Bug Report
11
+
12
+ **Current Behavior**
13
+ A clear and concise description of the behavior.
14
+
15
+ **Input Code / configuration of the construct**
16
+ ```ts
17
+ new TheConstruct(this, 'theConstruct', {
18
+ // the props passed in...
19
+ })
20
+ ```
21
+
22
+ **Expected behavior/code**
23
+ A clear and concise description of what you expected to happen (or code).
24
+
25
+ **Commands you ran**
26
+ ```bash
27
+ npx run build # for example
28
+ ```
29
+
30
+ **Environment**
31
+ - `node --version`:
32
+ - `npx cdk --version`:
33
+ - version of the construct: `x.x.x`
34
+
35
+ **Possible Solution**
36
+ <!--- Only if you have suggestions on a fix for the bug -->
37
+
38
+ **Additional context/Screenshots**
39
+ Add any other context about the problem here. If applicable, add screenshots to help explain.
@@ -0,0 +1,24 @@
1
+ ---
2
+ name: "\U0001F680 Feature Request"
3
+ about: "I have a suggestion (and may want to implement it \U0001F642)!"
4
+ title: ''
5
+ labels: 'i: enhancement, i: needs triage'
6
+ assignees: ''
7
+
8
+ ---
9
+
10
+ ## Feature Request
11
+
12
+ **Is your feature request related to a problem? Please describe.**
13
+ A clear and concise description of what the problem is. Ex. I have an issue when [...]
14
+
15
+ **Describe the solution you'd like**
16
+ A clear and concise description of what you want to happen. Add any considered drawbacks.
17
+
18
+ **Describe alternatives you've considered**
19
+ A clear and concise description of any alternative solutions or features you've considered.
20
+
21
+ **Teachability, Documentation, Adoption, Migration Strategy**
22
+ If you can, explain how users will be able to use this and possibly write out a version the docs.
23
+
24
+ Maybe a screenshot or design?
@@ -0,0 +1,22 @@
1
+ **Please check if the PR fulfills these requirements**
2
+ - [ ] The commit message describes your change
3
+ - [ ] Tests for the changes have been added if possible (for bug fixes / features)
4
+ - [ ] Docs have been added / updated (for bug fixes / features)
5
+
6
+ **What kind of change does this PR introduce? (Bug fix, feature, documentation, performance ...)**
7
+ > add here...
8
+
9
+ **What is the current behaviour? (You can also link to an open issue here)**
10
+ > add here...
11
+
12
+ **What is the new behaviour (if this is a feature change)?**
13
+ > add here...
14
+
15
+ **Does this PR introduce a breaking change? (What changes might users need to make in their setup due to this PR?)**
16
+ > add here...
17
+
18
+ **Environment**
19
+ - `node --version`:
20
+ - `npx cdk --version`:
21
+ - version of the construct: `x.x.x`
22
+
@@ -0,0 +1,55 @@
1
+ ## ๐Ÿš€ Unlock the Full Potential of Your AWS Cloud Infrastructure
2
+
3
+ Hi, Iโ€™m Manuel, an AWS expert passionate about empowering businesses with **scalable, resilient, and cost-optimized cloud solutions**. With **MV Consulting**, I specialize in crafting **tailored AWS architectures** and **DevOps-driven workflows** that not only meet your current needs but grow with you.
4
+
5
+ ---
6
+
7
+ ### ๐ŸŒŸ Why Work With Me?
8
+
9
+ โœ”๏ธ **Tailored AWS Solutions:** Every business is unique, so I design custom solutions that fit your goals and challenges.
10
+ โœ”๏ธ **Well-Architected Designs:** From scalability to security, my solutions align with AWS Well-Architected Framework.
11
+ โœ”๏ธ **Cloud-Native Focus:** I specialize in modern, cloud-native systems that embrace the full potential of AWS.
12
+ โœ”๏ธ **Business-Driven Tech:** Technology should serve your business, not the other way around.
13
+
14
+ ---
15
+
16
+ ### ๐Ÿ›  What I Bring to the Table
17
+
18
+ ๐Ÿ”‘ **12x AWS Certifications**
19
+ Iโ€™m **AWS Certified Solutions Architect and DevOps โ€“ Professional** and hold numerous additional certifications, so you can trust Iโ€™ll bring industry best practices to your projects. Feel free to explose by [badges](https://www.credly.com/users/manuel-vogel)
20
+
21
+ โš™๏ธ **Infrastructure as Code (IaC)**
22
+ With deep expertise in **AWS CDK** and **Terraform**, I ensure your infrastructure is automated, maintainable, and scalable.
23
+
24
+ ๐Ÿ“ฆ **DevOps Expertise**
25
+ From CI/CD pipelines with **GitHub Actions** and **GitLab CI** to container orchestration **Kubernetes** and others, I deliver workflows that are smooth and efficient.
26
+
27
+ ๐ŸŒ **Hands-On Experience**
28
+ With over **7 years of AWS experience** and a decade in the tech world, Iโ€™ve delivered solutions for companies large and small. My open-source contributions showcase my commitment to transparency and innovation. Feel free to explore my [GitHub profile](https://github.com/mavogel)
29
+
30
+ ---
31
+
32
+ ### ๐Ÿ’ผ Letโ€™s Build Something Great Together
33
+
34
+ I know that choosing the right partner is critical to your success. When you work with me, youโ€™re not just contracting an engineer โ€“ youโ€™re gaining a trusted advisor and hands-on expert who cares about your business as much as you do.
35
+
36
+ โœ”๏ธ **Direct Collaboration**: No middlemen or red tape โ€“ you work with me directly.
37
+ โœ”๏ธ **Transparent Process**: Expect open communication, clear timelines, and visible results.
38
+ โœ”๏ธ **Real Value**: My solutions focus on delivering measurable impact for your business.
39
+
40
+
41
+ <a href="https://tinyurl.com/mvc-15min"><img alt="Schedule your call" src="https://img.shields.io/badge/schedule%20your%20call-success.svg?style=for-the-badge"/></a>
42
+
43
+ ---
44
+
45
+ ## ๐Ÿ™Œ Acknowledgements
46
+
47
+ Big shoutout to the amazing team behind [Projen](https://github.com/projen/projen)!
48
+ Their groundbreaking work simplifies cloud infrastructure projects and inspires us every day. ๐Ÿ’ก
49
+
50
+ ## Author
51
+
52
+ [Manuel Vogel](https://manuel-vogel.de/about/)
53
+
54
+ [![](https://img.shields.io/badge/LinkedIn-0077B5?style=for-the-badge&logo=linkedin&logoColor=white)](https://www.linkedin.com/in/manuel-vogel)
55
+ [![](https://img.shields.io/badge/GitHub-2b3137?style=for-the-badge&logo=github&logoColor=white)](https://github.com/mavogel)
File without changes
package/lib/index.d.ts ADDED
@@ -0,0 +1 @@
1
+ export * from './projects';
package/lib/index.js ADDED
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./projects"), exports);
18
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLDZDQUEyQiIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCAqIGZyb20gJy4vcHJvamVjdHMnOyJdfQ==
@@ -0,0 +1,26 @@
1
+ import { AwsCdkConstructLibrary, AwsCdkConstructLibraryOptions } from 'projen/lib/awscdk';
2
+ /**
3
+ * The options for the construct
4
+ */
5
+ export interface MvcCdkConstructLibraryOptions extends AwsCdkConstructLibraryOptions {
6
+ /**
7
+ * Base directory for the assets
8
+ *
9
+ * @default ${cwd()}/node_modules/mvc-projen/assets
10
+ */
11
+ readonly baseAssetsDirectory?: string;
12
+ /**
13
+ * The regions to run the integ tests in
14
+ *
15
+ * @default eu-west-1 and eu-west-2
16
+ */
17
+ readonly integTestRegions?: string[];
18
+ }
19
+ /**
20
+ * TypeScript library
21
+ *
22
+ * @pjid mvc-awscdk-construct
23
+ */
24
+ export declare class MvcCdkConstructLibrary extends AwsCdkConstructLibrary {
25
+ constructor(options: MvcCdkConstructLibraryOptions);
26
+ }