Giter Club home page Giter Club logo

aws-bootstrap-kit-examples's Issues

SDLC Org Step 4 (deploy pipeline) : Unable to resolve AWS account to use

Description

Going through the setup steps and I am getting the following error when running the cdk bootstrap as part of step 4 of the SDLC Organization sample (deploy the pipeline).

1-SDLC-organization % npm run bootstrap

[email protected] bootstrap
cdk --profile main-admin bootstrap --cloudformation-execution-policies arn:aws:iam::aws:policy/AdministratorAccess

Unable to resolve AWS account to use. It must be either configured when you define your CDK Stack, or through the environment

bug(cicd): CICD script does not check if target regions are deployable

Context

In SDLC-Organization we auto bootstrap accounts with the right trust of CICD account on specified regions
(https://github.com/aws-samples/aws-bootstrap-kit-examples/blob/main/source/1-SDLC-organization/cdk.json#L11) .
In Service / App CDK side we automatically create stages based on the account tags created in the previous steps (https://github.com/aws-samples/aws-bootstrap-kit-examples/blob/main/source/3-landing-page-cicd/cdk/lib/cicd-stack.ts#L89) but we don't check if the target region is deployable .

Issue

If pipeline deployed in CICD account is deployed in a region not listed in "pipeline_deployable_regions", assets steps will fail with credentials error : Missing credentials in config, if using AWS_CONFIG_FILE, set AWS_SDK_LOAD_CONFIG=1.

Proposed fix

Option 1: find a way to figure out if target is bootstrapped properly and throw if not

Option 2:

feat: Move away from Github Personal Access Token

This approach should never be recommended, as it can be a serious concern.

Anyone who has access to PAT essentially has access to the GitHub user's entire account (even if it is scoped by permissions).

Since GitHub practices an "account per person" policy, one person may have access to many orgs.

Sharing a PAT in a shared environment (which AWS accounts often can be), can lead to someone stealing this PAT and then using that to gain access to information they were not privy of.


Alternative approaches to be considered:

  1. aws-cdk-github-oidc (https://github.com/aripalo/aws-cdk-github-oidc)
  2. Custom GitHub app
  3. CodeStar connections (https://docs.aws.amazon.com/codepipeline/latest/userguide/connections-github.html)

Allow DNS update with no downtime

Context

Current update of domain_name in 1-SDLC-Organization's cdk.json file will create a new zone and sub domains properly but delete the old one making all apps dependent on this unreachable while new domain_name is updated in each apps.

Solution

Allow array of domain names to enable 3 waves updates (1. add new one 2. update apps 3. delete old one) and as well enable multi domains feature.

Feature branch CI/CD strategy

Context

Current examples only show how to develop, integrate and deploy following a trunk base strategy with immutable infrastructure (main branch built once and promoted automatically to each stages).

Goal

Offer an alternative approach based on gitflow / feature branching strategy.

Offer a Python version of the Bootstrap Kit

Description

One of the really nice features of the CDK is that it supports different languages to describe your AWS infrastructure (Typescript, Javascript, Python, etc.). Most of our current infrastructure-as-code has been written using the AWS CDK in Python.

While porting this to Typescript would be do-able (not desired though!), it would be good to be able to leverage existing code in Python to support migrating to one AWS account per "context" (tenant, person, envt type etc.)

Update Domain Name

Hi All,

Can I update the domain which is set on cdk.json after applying all the changes.
The infra for SDLC has been created along with all the route 53 registration by the cdk itself.
Now, if I want to change it to some other doman, can I go ahead and do it

I dont want to mess the current setup right now, so it would be great if anycone can help me out on this..

Deploy the pipeline: --require-approval broadening, but TTY is not attached

Hello,

At the 'Deploy the pipeline' stage the process fails because of wanting to ask for approval but not having a terminal.

I was able to get around it by following this step to disable approval, but I'm not sure if that keeps to best practice or not.

$ npm run deploy

> [email protected] deploy C:\...\aws-bootstrap-kit-examples\source\1-SDLC-organization
> cdk --profile main-admin deploy

This deployment will make potentially sensitive changes according to your current security approval level (--require-approval broadening).
Please confirm you intend to make the following modifications:

... all the changes listed ...

"--require-approval" is enabled and stack includes security-sensitive updates, but terminal (TTY) is not attached so we are unable to get a confirmation from the user
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] deploy: `cdk --profile main-admin deploy`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] deploy script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

Deploy LandingPagePipelineStack: AWS::KMS::Key creation failed

Hello,

At the 'Deploy LandingPagePipelineStack' stage the LandingPagePipelineArtifactsBucketEncryptionKey creation fails because of error below:

LandingPagePipelineStack: creating CloudFormation changeset...
21:49:19 | CREATE_FAILED        | AWS::KMS::Key               | LandingPagePipelin...ryptionKeyF698B715
Resource handler returned message: "Policy contains a statement with one or more invalid principals. (Service: Kms, Status Code: 400, Request ID: 8a2bf088-71e3-40c1-8868-a119c1a20ba7, Extended Req
uest ID: null)" (RequestToken: 4f1e7ab4-10e0-2496-080e-9c06058fd176, HandlerErrorCode: InvalidRequest)

	new Key (/Users/apple/AWSWorkshop/MyLandingPage/infrastructure/node_modules/@aws-cdk/aws-kms/lib/key.ts:401:22)
	\_ new Pipeline (/Users/apple/AWSWorkshop/MyLandingPage/infrastructure/node_modules/@aws-cdk/aws-codepipeline/lib/pipeline.ts:233:25)
	\_ new CdkPipeline (/Users/apple/AWSWorkshop/MyLandingPage/infrastructure/node_modules/@aws-cdk/pipelines/lib/legacy/pipeline.ts:95:24)
	\_ new LandingPagePipelineStack (/Users/apple/AWSWorkshop/MyLandingPage/infrastructure/lib/cicd-pipeline-stack.ts:36:26)
	\_ Object.<anonymous> (/Users/apple/AWSWorkshop/MyLandingPage/infrastructure/bin/main.ts:13:23)
	\_ Module._compile (internal/modules/cjs/loader.js:688:30)
	\_ Module.m._compile (/Users/apple/AWSWorkshop/MyLandingPage/infrastructure/node_modules/ts-node/src/index.ts:858:23)
	\_ Module._extensions..js (internal/modules/cjs/loader.js:699:10)
	\_ Object.require.extensions.(anonymous function) [as .ts] (/Users/apple/AWSWorkshop/MyLandingPage/infrastructure/node_modules/ts-node/src/index.ts:861:12)
	\_ Module.load (internal/modules/cjs/loader.js:598:32)
	\_ tryModuleLoad (internal/modules/cjs/loader.js:537:12)
	\_ Function.Module._load (internal/modules/cjs/loader.js:529:3)
	\_ Function.Module.runMain (internal/modules/cjs/loader.js:741:12)
	\_ main (/Users/apple/AWSWorkshop/MyLandingPage/infrastructure/node_modules/ts-node/src/bin.ts:227:14)
	\_ Object.<anonymous> (/Users/apple/AWSWorkshop/MyLandingPage/infrastructure/node_modules/ts-node/src/bin.ts:513:3)
	\_ Module._compile (internal/modules/cjs/loader.js:688:30)
	\_ Object.Module._extensions..js (internal/modules/cjs/loader.js:699:10)
	\_ Module.load (internal/modules/cjs/loader.js:598:32)
	\_ tryModuleLoad (internal/modules/cjs/loader.js:537:12)
	\_ Function.Module._load (internal/modules/cjs/loader.js:529:3)
	\_ Function.Module.runMain (internal/modules/cjs/loader.js:741:12)
	\_ startup (internal/bootstrap/node.js:285:19)
	\_ bootstrapNodeJSCore (internal/bootstrap/node.js:739:3)


 ❌  LandingPagePipelineStack failed: Error: The stack named LandingPagePipelineStack failed creation, it may need to be manually deleted from the AWS console: ROLLBACK_COMPLETE
The stack named LandingPagePipelineStack failed creation, it may need to be manually deleted from the AWS console: ROLLBACK_COMPLETE
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] cdk: `cdk "deploy" "LandingPagePipelineStack" "--profile" "cicd"`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the [email protected] cdk script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/apple/.npm/_logs/2021-09-27T13_51_00_206Z-debug.log
 + │ ${LandingPagePipeline/Pipeline/ArtifactsBu │ Allow  │ kms:CancelKeyDeletion                      │ AWS:arn:${AWS::Partition}:iam::${AWS::Acco │                                              │
│   │ cketEncryptionKey.Arn}                     │        │ kms:Create*                                │ untId}:root                                │                                              │
│   │                                            │        │ kms:Delete*                                │                                            │                                              │
│   │                                            │        │ kms:Describe*                              │                                            │                                              │
│   │                                            │        │ kms:Disable*                               │                                            │                                              │
│   │                                            │        │ kms:Enable*                                │                                            │                                              │
│   │                                            │        │ kms:GenerateDataKey                        │                                            │                                              │
│   │                                            │        │ kms:Get*                                   │                                            │                                              │
│   │                                            │        │ kms:List*                                  │                                            │                                              │
│   │                                            │        │ kms:Put*                                   │                                            │                                              │
│   │                                            │        │ kms:Revoke*                                │                                            │                                              │
│   │                                            │        │ kms:ScheduleKeyDeletion                    │                                            │                                              │
│   │                                            │        │ kms:TagResource                            │                                            │                                              │
│   │                                            │        │ kms:UntagResource                          │                                            │                                              │
│   │                                            │        │ kms:Update*                                │                                            │                                              │
│ + │ ${LandingPagePipeline/Pipeline/ArtifactsBu │ Allow  │ kms:Decrypt                                │ AWS:${LandingPagePipeline/Assets/FileRole. │                                              │
│   │ cketEncryptionKey.Arn}                     │        │ kms:Encrypt                                │ Arn}                                       │                                              │
│   │                                            │        │ kms:GenerateDataKey*                       │                                            │                                              │
│   │                                            │        │ kms:ReEncrypt*                             │                                            │                                              │
│ + │ ${LandingPagePipeline/Pipeline/ArtifactsBu │ Allow  │ kms:Decrypt                                │ AWS:arn:${AWS::Partition}:iam::80574403528 │                                              │
│   │ cketEncryptionKey.Arn}                     │        │ kms:DescribeKey                            │ 5:role/cdk-hnb659fds-deploy-role-805744035 │                                              │
│   │                                            │        │                                            │ 285-${AWS::Region}                         │                                              │
│ + │ ${LandingPagePipeline/Pipeline/ArtifactsBu │ Allow  │ kms:Decrypt                                │ AWS:arn:${AWS::Partition}:iam::78606670454 │                                              │
│   │ cketEncryptionKey.Arn}                     │        │ kms:DescribeKey                            │ 2:role/cdk-hnb659fds-deploy-role-786066704 │                                              │
│   │                                            │        │                                            │ 542-${AWS::Region}                         │                                              │
│ + │ ${LandingPagePipeline/Pipeline/ArtifactsBu │ Allow  │ kms:Decrypt                                │ AWS:${LandingPagePipeline/Assets/FileRole} │                                              │
│   │ cketEncryptionKey.Arn}                     │        │ kms:DescribeKey                            │                                            │                                              │
│ + │ ${LandingPagePipeline/Pipeline/ArtifactsBu │ Allow  │ kms:Decrypt                                │ AWS:${LandingPagePipeline/UpdatePipeline/S │                                              │
│   │ cketEncryptionKey.Arn}                     │        │ kms:Encrypt                                │ elfMutation/Role}                          │                                              │
│   │                                            │        │ kms:GenerateDataKey*                       │                                            │                                              │
│   │                                            │        │ kms:ReEncrypt*                             │                                            │                                              │
│ + │ ${LandingPagePipeline/Pipeline/ArtifactsBu │ Allow  │ kms:Decrypt                                │ AWS:${LandingPagePipeline/UpdatePipeline/S │                                              │
│   │ cketEncryptionKey.Arn}                     │        │ kms:DescribeKey                            │ elfMutation/Role}                          │                                              │
│ + │ ${LandingPagePipeline/Pipeline/ArtifactsBu │ Allow  │ kms:Decrypt                                │ AWS:${LandingPagePipeline/Pipeline/Build/S │                                              │
│   │ cketEncryptionKey.Arn}                     │        │ kms:DescribeKey                            │ ynth/CdkBuildProject/Role.Arn}             │                                              │
│   │                                            │        │ kms:Encrypt                                │                                            │                                              │
│   │                                            │        │ kms:GenerateDataKey*                       │                                            │                                              │
│   │                                            │        │ kms:ReEncrypt*                             │                                            │                                              │
│ + │ ${LandingPagePipeline/Pipeline/ArtifactsBu │ Allow  │ kms:Decrypt                                │ AWS:${LandingPagePipeline/Pipeline/Build/S │                                              │
│   │ cketEncryptionKey.Arn}                     │        │ kms:Encrypt                                │ ynth/CdkBuildProject/Role}                 │                                              │
│   │                                            │        │ kms:GenerateDataKey*                       │                                            │                                              │
│   │                                            │        │ kms:ReEncrypt*                             │                                            │                                              │
│ + │ ${LandingPagePipeline/Pipeline/ArtifactsBu │ Allow  │ kms:Decrypt                                │ AWS:${LandingPagePipeline/Pipeline/Build/S │                                              │
│   │ cketEncryptionKey.Arn}                     │        │ kms:DescribeKey                            │ ynth/CdkBuildProject/Role}                 │                                              │
│   │                                            │        │ kms:Encrypt                                │                                            │                                              │
│   │                                            │        │ kms:GenerateDataKey*                       │                                            │                                              │
│   │                                            │        │ kms:ReEncrypt*                             │                                            │                                              │
│ + │ ${LandingPagePipeline/Pipeline/ArtifactsBu │ Allow  │ kms:Decrypt                                │ AWS:${LandingPagePipeline/Pipeline/Build/S │                                              │
│   │ cketEncryptionKey.Arn}                     │        │ kms:Encrypt                                │ ynth/CdkBuildProject/Role.Arn}             │                                              │
│   │                                            │        │ kms:GenerateDataKey*                       │                                            │                                              │
│   │                                            │        │ kms:ReEncrypt*                             │                                            │                                              │
│ + │ ${LandingPagePipeline/Pipeline/ArtifactsBu │ Allow  │ kms:Decrypt                                │ AWS:${LandingPagePipeline/UpdatePipeline/S │                                              │
│   │ cketEncryptionKey.Arn}                     │        │ kms:DescribeKey                            │ elfMutation/Role.Arn}                      │                                              │
│ + │ ${LandingPagePipeline/Pipeline/ArtifactsBu │ Allow  │ kms:Decrypt                                │ AWS:${LandingPagePipeline/UpdatePipeline/S │                                              │
│   │ cketEncryptionKey.Arn}                     │        │ kms:Encrypt                                │ elfMutation/Role.Arn}                      │                                              │
│   │                                            │        │ kms:GenerateDataKey*                       │                                            │                                              │
│   │                                            │        │ kms:ReEncrypt*                             │                                            │                                              │
│ + │ ${LandingPagePipeline/Pipeline/ArtifactsBu │ Allow  │ kms:Decrypt                                │ AWS:${LandingPagePipeline/Pipeline/Role}   │                                              │
│   │ cketEncryptionKey.Arn}                     │        │ kms:DescribeKey                            │                                            │                                              │
│   │                                            │        │ kms:Encrypt                                │                                            │                                              │
│   │                                            │        │ kms:GenerateDataKey*                       │                                            │                                              │
│   │                                            │        │ kms:ReEncrypt*                             │                                            │                                              │
│ + │ ${LandingPagePipeline/Pipeline/ArtifactsBu │ Allow  │ kms:Decrypt                                │ AWS:${LandingPagePipeline/Assets/FileRole. │                                              │
│   │ cketEncryptionKey.Arn}                     │        │ kms:DescribeKey                            │ Arn}                                       │                                              │
│ + │ ${LandingPagePipeline/Pipeline/ArtifactsBu │ Allow  │ kms:Decrypt                                │ AWS:${LandingPagePipeline/Pipeline/Role.Ar │                                              │
│   │ cketEncryptionKey.Arn}                     │        │ kms:DescribeKey                            │ n}                                         │                                              │
│   │                                            │        │ kms:Encrypt                                │                                            │                                              │
│   │                                            │        │ kms:GenerateDataKey*                       │                                            │                                              │
│   │                                            │        │ kms:ReEncrypt*                             │       

I don't know what's wrong and how to fix it.

Should the account emails use the parent account id ?

Description

I just deployed the AWS Bootstrap Kit Examples' SDLC Org app, with a slightly different org structure :

Screen Shot 2022-08-04 at 1 42 27 PM

Notice how the Prod and Staging accounts for Tenant-A have the following :

This is, of course, from the perspective of a SaaS provider deploying multiple tenant environments.

So if we want to create Tenant-B with the same Prod and Staging structure we would be re-using the same email account to send AWS account creation notices, effectively making it impossible to distinguish which AWS account those are for.

The emails received (8 in total), all had one of the following 2 recipients :

Note : account numbers masked and email domains changed on purpose.

Suggestion

Would it be possible to use email addresses with the actual ID of the account being created, rather than the stack account number ?

Current code below :

      else if(this.emailPrefix && this.domain)
      {
        accountEmail = `${this.emailPrefix}+${accountSpec.name}-${Stack.of(this).account}@${this.domain}`
      }

Using "domain_name" in context with valid DNS completely breaks deployment

I have followed the steps in the Activate tutorial: https://activate.workshop.aws/

After bootstrapping and deploying the SDLC Org, I cut my DreamHost domain DNS over to the created Route53 zone in the "main" account of my new AWS setup.

I waited 8 hours for DNS to propagate, and checked it from multiple NS servers using dig

When I try to deploy my FrontendPipeline, deployment breaks at the Staging deployment step.

Note: If I run the deployment without "domain_name" context, deployment seems to work without issue., but that's not the desired outcome :)

I'm thinking about a few things:

  • Does this have to do with the permissionBoundary we set as an aspect of the PipelineStack?
// Respect cdk bootstrap policy insuring pipelines construct can't create more than what it needs for CI/CD pipeline creation
const permissionBoundaryArn = cdk.Fn.importValue('CICDPipelinePermissionsBoundaryArn');
cdk.Aspects.of(pipelineStack).add(new AddPermissionsBoundaryToRoles(permissionBoundaryArn));
  • Is there a Route53 "Permission Set" I should be creating and assigning in the "AWS Accounts" section of my SSO Organization? If so, what permissions should those be, which SSO Groups and/or accounts should they be assigned and applied to?

  • Are there missing IAM roles with read/list/write permissions for Route53 in my "main" account, which the Pipeline in the CICD account should be able to assume, but cannot?

  • It looks like the Staging account is trying to get permissions/assumeRole to make changes to my "main" account's DNS zones. Is that the case? If so, is that the intended behavior?

  • Are Route53 zones and DNS Delegation even being set up correctly?
    In my root account DNS, I have the following hosted zones:

redacted-domain.me
dev.redacted-domain.me
prod.redacted-domain.me
staging.redacted-domain.me

Inside of Hosted Zone redacted-domain.me (in root account) I have a record for `staging.redacted-domain.me:

staging.redacted-domain.me | NS | Simple | - |
ns-555.awsdns-05.net
ns-1506.awsdns-60.org
ns-269.awsdns-33.com
ns-1775.awsdns-29.co.uk

Inside of Hosted Zone staging.redacted-domain.me (in root account) I have the following:

staging.redacted-domain.me | NS | Simple | - |
ns-269.awsdns-33.com.ns-1775.awsdns-29.co.uk.ns-555.awsdns-05.net.ns-1506.awsdns-60.org.


staging.redacted-domain.me | SOA | Simple | - |
ns-269.awsdns-33.com. awsdns-hostmaster.amazon.com. 1 7200 900 1209600 86400

...but in my staging account, I only have 1 hosted zone, named appname-web.staging.redacted-domain.me and no other zones, with the following records. Should this just be a DNS entry, as opposed to a zone?

appname-web.staging.redacted-domain.me | SOA | Simple | - | 
ns-287.awsdns-35.com. awsdns-hostmaster.amazon.com. 1 7200 900 1209600 86400

appname-web.staging.redacted-domain.me | NS | Simple | - | 
ns-287.awsdns-35.com.
ns-919.awsdns-50.net.
ns-1768.awsdns-29.co.uk
.ns-1117.awsdns-11.org.

_4837233fe50fb47655752c4dda901bec.appname-web.staging.redacted-domain.me | CNAME | Simple | - |
_703233e4799c310561b5ec55b015e433.nfyddsqlcy.acm-validations.aws.

Please see logs below -->

Logs:

Stack:
staging-WebAppStack-FrontendStackNestedStackFrontendStackNestedStackResource7A0E341B-OQN6W90BEOT8

Logical ID:
subzoneDelegationHostedZone61C4EBB4

Physical ID:
<REDACTED ZONE Z0699...>

Type:

AWS::Route53::HostedZone

Status:
DELETE_FAILED

The specified hosted zone contains non-required resource record sets and so cannot be deleted. (Service: Route53, Status Code: 400, Request ID: 58e24c4a-e9b3-4407-9cab-65e6c22cccbb, Extended Request ID: null)

The non-required resource in the Route53 zone file is the ACM validation entry that gets added while the stack is being deployed. From Route53.

Here's where it gets kinda bad. In my staging account, here's what I see in Route53:

Hosted Zones > appname-web.staging.redacted-domain.me

Records:

appname-web.staging.redacted-domain.me | NS | Simple --> 
ns-287.awsdns-35.com.
ns-919.awsdns-50.net.
ns-1768.awsdns-29.co.uk.
ns-1117.awsdns-11.org.

appname-web.staging.redacted-domain.me | SOA | Simple -->
ns-287.awsdns-35.com. awsdns-hostmaster.amazon.com. 1 7200 900 1209600 86400

_4837233fe50fb47655752c4dda901bec.appname-web.staging.redacted-domain.me | CNAME | Simple | -->
_703233e4799c310561b5ec55b015e433.nfyddsqlcy.acm-validations.aws.

CloudWatch Logs

Log groups > /aws/lambda/staging-WebAppStack-Front-CrossAccountZoneDelegati-TXZJK1L5YARH > 2021/03/06/[$LATEST]7aa99371b8224dcb8d08c5821bd6ca40

START RequestId: 6dd5bd2b-0260-41ac-aa08-1407c502d896 Version: $LATEST

2021-03-06T09:52:43.540Z	6dd5bd2b-0260-41ac-aa08-1407c502d896	INFO	Event: 
{
    "RequestType": "Create",
    "ServiceToken": "arn:aws:lambda:us-west-2:STAGING_ACCOUNT_NUMBER:function:staging-WebAppStack-Front-CrossAccountZoneDelegati-11KEBTW3HUW55",
    "ResponseURL": "https://cloudformation-custom-resource-response-uswest2.s3-us-west-2.amazonaws.com/arn%3Aaws%3Acloudformation%3Aus-west-2%3ASTAGING_ACCOUNT_NUMBER%3Astack/staging-WebAppStack-FrontendStackNestedStackFrontendStackNestedStackResource7A0E341B-OQN6W90BEOT8/6dc38630-7e61-11eb-b0f7-02cff3de376d%7CsubzoneDelegationCrossAccountZoneDelegationRecordCrossAccountZoneDelegationRecordappnamewebstagingredacted-domainmeD89FF7A1%7Ce6fa7aba-fdfd-4b2a-869f-1e238a9d04d6?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20210306T095241Z&X-Amz-SignedHeaders=host&X-Amz-Expires=7200&X-Amz-Credential=AKIA54RCMT6SM5P7WMPE%2F20210306%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Signature=009b44ab5b5d0d3a7dc87849a149a10984b7499b82e6bb6067956d8fda642843",
    "StackId": "arn:aws:cloudformation:us-west-2:STAGING_ACCOUNT_NUMBER:stack/staging-WebAppStack-FrontendStackNestedStackFrontendStackNestedStackResource7A0E341B-OQN6W90BEOT8/6dc38630-7e61-11eb-b0f7-02cff3de376d",
    "RequestId": "e6fa7aba-fdfd-4b2a-869f-1e238a9d04d6",
    "LogicalResourceId": "subzoneDelegationCrossAccountZoneDelegationRecordCrossAccountZoneDelegationRecordappnamewebstagingredacted-domainmeD89FF7A1",
    "ResourceType": "Custom::CrossAccountZoneDelegationRecord",
    "ResourceProperties": {
        "ServiceToken": "arn:aws:lambda:us-west-2:STAGING_ACCOUNT_NUMBER:function:staging-WebAppStack-Front-CrossAccountZoneDelegati-11KEBTW3HUW55",
        "currentAccountId": "STAGING_ACCOUNT_NUMBER",
        "toDelegateNameServers": [
            "ns-287.awsdns-35.com",
            "ns-919.awsdns-50.net",
            "ns-1768.awsdns-29.co.uk",
            "ns-1117.awsdns-11.org"
        ],
        "recordName": "appname-web.staging.redacted-domain.me"
    }
}

2021-03-06T09:52:45.029Z	6dd5bd2b-0260-41ac-aa08-1407c502d896	ERROR	Invoke Error 	
{
    "errorType": "AccessDenied",
    "errorMessage": "User: arn:aws:sts::STAGING_ACCOUNT_NUMBER:assumed-role/staging-WebAppStack-Front-CrossAccountZoneDelegati-QVR17XIY35S3/staging-WebAppStack-Front-CrossAccountZoneDelegati-TXZJK1L5YARH is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::MAIN_ACCOUNT_NUMBER:role/Staging.redacted-domain.me-dns-update",
    "code": "AccessDenied",
    "message": "User: arn:aws:sts::STAGING_ACCOUNT_NUMBER:assumed-role/staging-WebAppStack-Front-CrossAccountZoneDelegati-QVR17XIY35S3/staging-WebAppStack-Front-CrossAccountZoneDelegati-TXZJK1L5YARH is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::MAIN_ACCOUNT_NUMBER:role/Staging.redacted-domain.me-dns-update",
    "time": "2021-03-06T09:52:44.980Z",
    "requestId": "97877578-652d-46ca-a502-e051d704854e",
    "statusCode": 403,
    "retryable": false,
    "retryDelay": 76.96104528535399,
    "stack": [
        "AccessDenied: User: arn:aws:sts::STAGING_ACCOUNT_NUMBER:assumed-role/staging-WebAppStack-Front-CrossAccountZoneDelegati-QVR17XIY35S3/staging-WebAppStack-Front-CrossAccountZoneDelegati-TXZJK1L5YARH is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::MAIN_ACCOUNT_NUMBER:role/Staging.redacted-domain.me-dns-update",
        "    at Request.extractError (/var/runtime/node_modules/aws-sdk/lib/protocol/query.js:50:29)",
        "    at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:106:20)",
        "    at Request.emit (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:78:10)",
        "    at Request.emit (/var/runtime/node_modules/aws-sdk/lib/request.js:688:14)",
        "    at Request.transition (/var/runtime/node_modules/aws-sdk/lib/request.js:22:10)",
        "    at AcceptorStateMachine.runTo (/var/runtime/node_modules/aws-sdk/lib/state_machine.js:14:12)",
        "    at /var/runtime/node_modules/aws-sdk/lib/state_machine.js:26:10",
        "    at Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:38:9)",
        "    at Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:690:12)",
        "    at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:116:18)"
    ]
}

END RequestId: 6dd5bd2b-0260-41ac-aa08-1407c502d896

Log groups > /aws/lambda/staging-WebAppStack-Front-CrossAccountZoneDelegati-11KEBTW3HUW55 > 2021/03/06/[$LATEST]94540ec5bbc44794a7b6ce5ac805f5a5

2021-03-06T09:52:42.014Z	b3eb75eb-d36f-4d16-bd9d-6827d73cb763	INFO	[provider-framework] onEventHandler 
{
    "RequestType": "Create",
    "ServiceToken": "arn:aws:lambda:us-west-2:STAGING_ACCOUNT_NUMBER:function:staging-WebAppStack-Front-CrossAccountZoneDelegati-11KEBTW3HUW55",
    "ResponseURL": "https://cloudformation-custom-resource-response-uswest2.s3-us-west-2.amazonaws.com/arn%3Aaws%3Acloudformation%3Aus-west-2%3ASTAGING_ACCOUNT_NUMBER%3Astack/staging-WebAppStack-FrontendStackNestedStackFrontendStackNestedStackResource7A0E341B-OQN6W90BEOT8/6dc38630-7e61-11eb-b0f7-02cff3de376d%7CsubzoneDelegationCrossAccountZoneDelegationRecordCrossAccountZoneDelegationRecordappnamewebstagingredacted-domainmeD89FF7A1%7Ce6fa7aba-fdfd-4b2a-869f-1e238a9d04d6?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20210306T095241Z&X-Amz-SignedHeaders=host&X-Amz-Expires=7200&X-Amz-Credential=AKIA54RCMT6SM5P7WMPE%2F20210306%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Signature=009b44ab5b5d0d3a7dc87849a149a10984b7499b82e6bb6067956d8fda642843",
    "StackId": "arn:aws:cloudformation:us-west-2:STAGING_ACCOUNT_NUMBER:stack/staging-WebAppStack-FrontendStackNestedStackFrontendStackNestedStackResource7A0E341B-OQN6W90BEOT8/6dc38630-7e61-11eb-b0f7-02cff3de376d",
    "RequestId": "e6fa7aba-fdfd-4b2a-869f-1e238a9d04d6",
    "LogicalResourceId": "subzoneDelegationCrossAccountZoneDelegationRecordCrossAccountZoneDelegationRecordappnamewebstagingredacted-domainmeD89FF7A1",
    "ResourceType": "Custom::CrossAccountZoneDelegationRecord",
    "ResourceProperties": {
        "ServiceToken": "arn:aws:lambda:us-west-2:STAGING_ACCOUNT_NUMBER:function:staging-WebAppStack-Front-CrossAccountZoneDelegati-11KEBTW3HUW55",
        "currentAccountId": "STAGING_ACCOUNT_NUMBER",
        "toDelegateNameServers": [
            "ns-287.awsdns-35.com",
            "ns-919.awsdns-50.net",
            "ns-1768.awsdns-29.co.uk",
            "ns-1117.awsdns-11.org"
        ],
        "recordName": "appname-web.staging.redacted-domain.me"
    }
}

2021-03-06T09:52:42.036Z	b3eb75eb-d36f-4d16-bd9d-6827d73cb763	INFO	[provider-framework] executing user function arn:aws:lambda:us-west-2:STAGING_ACCOUNT_NUMBER:function:staging-WebAppStack-Front-CrossAccountZoneDelegati-TXZJK1L5YARH with payload 
{
    "RequestType": "Create",
    "ServiceToken": "arn:aws:lambda:us-west-2:STAGING_ACCOUNT_NUMBER:function:staging-WebAppStack-Front-CrossAccountZoneDelegati-11KEBTW3HUW55",
    "ResponseURL": "https://cloudformation-custom-resource-response-uswest2.s3-us-west-2.amazonaws.com/arn%3Aaws%3Acloudformation%3Aus-west-2%3ASTAGING_ACCOUNT_NUMBER%3Astack/staging-WebAppStack-FrontendStackNestedStackFrontendStackNestedStackResource7A0E341B-OQN6W90BEOT8/6dc38630-7e61-11eb-b0f7-02cff3de376d%7CsubzoneDelegationCrossAccountZoneDelegationRecordCrossAccountZoneDelegationRecordappnamewebstagingredacted-domainmeD89FF7A1%7Ce6fa7aba-fdfd-4b2a-869f-1e238a9d04d6?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20210306T095241Z&X-Amz-SignedHeaders=host&X-Amz-Expires=7200&X-Amz-Credential=AKIA54RCMT6SM5P7WMPE%2F20210306%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Signature=009b44ab5b5d0d3a7dc87849a149a10984b7499b82e6bb6067956d8fda642843",
    "StackId": "arn:aws:cloudformation:us-west-2:STAGING_ACCOUNT_NUMBER:stack/staging-WebAppStack-FrontendStackNestedStackFrontendStackNestedStackResource7A0E341B-OQN6W90BEOT8/6dc38630-7e61-11eb-b0f7-02cff3de376d",
    "RequestId": "e6fa7aba-fdfd-4b2a-869f-1e238a9d04d6",
    "LogicalResourceId": "subzoneDelegationCrossAccountZoneDelegationRecordCrossAccountZoneDelegationRecordappnamewebstagingredacted-domainmeD89FF7A1",
    "ResourceType": "Custom::CrossAccountZoneDelegationRecord",
    "ResourceProperties": {
        "ServiceToken": "arn:aws:lambda:us-west-2:STAGING_ACCOUNT_NUMBER:function:staging-WebAppStack-Front-CrossAccountZoneDelegati-11KEBTW3HUW55",
        "currentAccountId": "STAGING_ACCOUNT_NUMBER",
        "toDelegateNameServers": [
            "ns-287.awsdns-35.com",
            "ns-919.awsdns-50.net",
            "ns-1768.awsdns-29.co.uk",
            "ns-1117.awsdns-11.org"
        ],
        "recordName": "appname-web.staging.redacted-domain.me"
    }
}

2021-03-06T09:52:45.078Z	b3eb75eb-d36f-4d16-bd9d-6827d73cb763	INFO	[provider-framework] user function response: 
{
    "StatusCode": 200,
    "FunctionError": "Unhandled",
    "ExecutedVersion": "$LATEST",
    "Payload": "{\"errorType\":\"AccessDenied\",\"errorMessage\":\"User: arn:aws:sts::STAGING_ACCOUNT_NUMBER:assumed-role/staging-WebAppStack-Front-CrossAccountZoneDelegati-QVR17XIY35S3/staging-WebAppStack-Front-CrossAccountZoneDelegati-TXZJK1L5YARH is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::MAIN_ACCOUNT_NUMBER:role/Staging.redacted-domain.me-dns-update\",\"trace\":[\"AccessDenied: User: arn:aws:sts::STAGING_ACCOUNT_NUMBER:assumed-role/staging-WebAppStack-Front-CrossAccountZoneDelegati-QVR17XIY35S3/staging-WebAppStack-Front-CrossAccountZoneDelegati-TXZJK1L5YARH is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::MAIN_ACCOUNT_NUMBER:role/Staging.redacted-domain.me-dns-update\",\"    at Request.extractError (/var/runtime/node_modules/aws-sdk/lib/protocol/query.js:50:29)\",\"    at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:106:20)\",\"    at Request.emit (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:78:10)\",\"    at Request.emit (/var/runtime/node_modules/aws-sdk/lib/request.js:688:14)\",\"    at Request.transition (/var/runtime/node_modules/aws-sdk/lib/request.js:22:10)\",\"    at AcceptorStateMachine.runTo (/var/runtime/node_modules/aws-sdk/lib/state_machine.js:14:12)\",\"    at /var/runtime/node_modules/aws-sdk/lib/state_machine.js:26:10\",\"    at Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:38:9)\",\"    at Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:690:12)\",\"    at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:116:18)\"]}"
}
 object

 2021-03-06T09:52:45.116Z	b3eb75eb-d36f-4d16-bd9d-6827d73cb763	INFO	[provider-framework] user function threw an error: Unhandled

 2021-03-06T09:52:45.116Z	b3eb75eb-d36f-4d16-bd9d-6827d73cb763	INFO	[provider-framework] CREATE failed, responding with a marker physical resource id so that the subsequent DELETE will be ignored

 2021-03-06T09:52:45.116Z	b3eb75eb-d36f-4d16-bd9d-6827d73cb763	INFO	[provider-framework] submit response to cloudformation 
{
    "Status": "FAILED",
    "Reason": "User: arn:aws:sts::STAGING_ACCOUNT_NUMBER:assumed-role/staging-WebAppStack-Front-CrossAccountZoneDelegati-QVR17XIY35S3/staging-WebAppStack-Front-CrossAccountZoneDelegati-TXZJK1L5YARH is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::MAIN_ACCOUNT_NUMBER:role/Staging.redacted-domain.me-dns-update\n\nLogs: /aws/lambda/staging-WebAppStack-Front-CrossAccountZoneDelegati-TXZJK1L5YARH\n\n    at Request.extractError (/var/runtime/node_modules/aws-sdk/lib/protocol/query.js:50:29)\n    at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:106:20)\n    at Request.emit (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:78:10)\n    at Request.emit (/var/runtime/node_modules/aws-sdk/lib/request.js:688:14)\n    at Request.transition (/var/runtime/node_modules/aws-sdk/lib/request.js:22:10)\n    at AcceptorStateMachine.runTo (/var/runtime/node_modules/aws-sdk/lib/state_machine.js:14:12)\n    at /var/runtime/node_modules/aws-sdk/lib/state_machine.js:26:10\n    at Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:38:9)\n    at Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:690:12)\n    at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:116:18)",
    "StackId": "arn:aws:cloudformation:us-west-2:STAGING_ACCOUNT_NUMBER:stack/staging-WebAppStack-FrontendStackNestedStackFrontendStackNestedStackResource7A0E341B-OQN6W90BEOT8/6dc38630-7e61-11eb-b0f7-02cff3de376d",
    "RequestId": "e6fa7aba-fdfd-4b2a-869f-1e238a9d04d6",
    "PhysicalResourceId": "AWSCDK::CustomResourceProviderFramework::CREATE_FAILED",
    "LogicalResourceId": "subzoneDelegationCrossAccountZoneDelegationRecordCrossAccountZoneDelegationRecordappnamewebstagingredacted-domainmeD89FF7A1"
}

END RequestId: b3eb75eb-d36f-4d16-bd9d-6827d73cb763

REPORT RequestId: b3eb75eb-d36f-4d16-bd9d-6827d73cb763	Duration: 3243.30 ms	Billed Duration: 3244 ms	Memory Size: 128 MB	Max Memory Used: 90 MB	Init Duration: 428.26 ms	

START RequestId: f39e7437-d870-4de7-b968-2cd745a099c0 Version: $LATEST

2021-03-06T09:53:35.249Z	f39e7437-d870-4de7-b968-2cd745a099c0	INFO	[provider-framework] ignoring DELETE event caused by a failed CREATE event

2021-03-06T09:53:35.249Z	f39e7437-d870-4de7-b968-2cd745a099c0	INFO	[provider-framework] submit response to cloudformation 
{
    "Status": "SUCCESS",
    "Reason": "SUCCESS",
    "StackId": "arn:aws:cloudformation:us-west-2:STAGING_ACCOUNT_NUMBER:stack/staging-WebAppStack-FrontendStackNestedStackFrontendStackNestedStackResource7A0E341B-OQN6W90BEOT8/6dc38630-7e61-11eb-b0f7-02cff3de376d",
    "RequestId": "cee9bfd0-1745-4558-abf4-5c75c7148fb2",
    "PhysicalResourceId": "AWSCDK::CustomResourceProviderFramework::CREATE_FAILED",
    "LogicalResourceId": "subzoneDelegationCrossAccountZoneDelegationRecordCrossAccountZoneDelegationRecordappnamewebstagingredacted-domainmeD89FF7A1"
}

END RequestId: f39e7437-d870-4de7-b968-2cd745a099c0

Sorry for the terrible formatting (I tried). Also, I'd just like to say thank you again for all of the incredible work you've all put into this project!

Any help or direction would be much appreciated. Thank you!

Issue with Cloudtrail

Hi, I am setting up SDLC Organization in a complete new AWS Account, however the following error keeps coming up failing to create organizationTrail.

The changes are based on the latest update on the codebase.

The highlighted section is the organization id.

image

image

Pipeline deploy requires deprecated IAM policy

Following the README in 1-SDLC-organization at Step 4 Deploy the pipeline the pipeline fails during the Prod step of orgStack.Deploy.
Looking at the events in CloudFormation for the Prod-orgStack, it fails because when creating the SecureRootUserConfigRecorderConfigRecorderRole (see screenshot) it cannot attach one of the managed policies with the reason given as:

arn:aws:iam::aws:policy/service-role/AWSConfigRole does not exist or is not attachable. (Service: AmazonIdentityManagement; Status Code: 404; Error Code: NoSuchEntity; Request ID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx; Proxy: null)

deprecated-role

A quick google search shows that the AWSConfigRole was deprecated by AWS in July and replaced by a more scoped down policy named AWS_ConfigRole.

Is there a way to update the CloudFormation template that is created to use the newer/non-deprecated role? So far, no matter what I've tried, I can't get past this step of the setup.

Unable to Create organization

Hi,
I am trying to use this to implement the example on my AWS accounts.

However, organization are not being created at all by this. The stack on cloudformation is deployed successfully, but organization are not created.

Did anyone face this issue? What am I doing wrong?

Add test or utility to check all required context variables are present

Minor nitpick, but I lost a couple of hours until I hunted this down:

In my own project, I ported some of the example code from this repo after scaffolding my own cdk project.

I received no warnings or errors from npm run watch or cdk synth or npm run build during any of my development.

When it came to deploy, I kept getting a VERY cryptic and ambiguous error:

Tag must have a value

For the life of me, I couldn't figure out what was missing, or where (I'm an experienced DevOps engineer and architect, and I know JS/TS). I am, however, new to CDK.

After a few hours of trying to debug/investigate by reading through all of the Construct and Stack code, I started diffing my own ported code to the code in the examples repo. THAT is when I finally thought to compare/diff my own cdk.json file to the one in the example repo, and realized I was missing this line:

    "service_name": "myProj-web"

Would it be worth AT LEAST noting this in README.md, or otherwise maybe writing a smaller utility/helper that can check for all required context variables PRIOR to deploy/build?

I lost a few hours on this, and I'm guessing other newbies might as well.

Updating ckd dependencies/libs

Howdy! I'm a Solutions Architecture manager with AWS, and I've been playing with the CDK in my spare time!

This tutorial brought me here: https://activate.workshop.aws/011_begin.html

I had to create a copy/fork of the bootstrap example source code and push it to my own repo so that I could keep the @aws-cdk/* libs and dependencies in sync with the version of cdk libraries I am running in my own project's repo. I get all sorts of compile-time and type-related errors when attempting to use aws-bootstrap-kit as a project dependency, so what I had to do was:

  1. grab the code for this package https://www.npmjs.com/package/aws-bootstrap-kit
  2. pull down a copy of that module into my own project's infrastructure repo
  3. install https://www.npmjs.com/package/rocketcdk as a dependency in bootstrap-kit
  4. update/pin all packages to cdk library versions in my own project's infrastructure repo
  5. add/install aws-bootstrap-kit to my own infra repo's package.json in the following way:
    "aws-bootstrap-kit": "file:../aws-bootstrap-kit",
  6. import the bootstrap kit as usual

Feedback

  • The reason I'm hell-bent on using your library is because it's the ONLY reference-able solution I have found which provides a best-practices Construct that CORRECTLY configures/works with cross-account/delegated DNS automation
  • Other constructs built/provided in there are useful and reusable, and I'd happily continue to use these instead of writing my own.

I'm happy to help maintain or collaborate on this with you! Would it be cool for me to open a quick PR with updated package versions to the latest stable @aws-cdk/* libs (1.91.0)?

ssm:GetParameter fails

I'm using the latest codebases for both the bootstrap-kit examples, as well as the latest 1.91.0-locked libraries and aws-bootstrap-kit package (thanks for updating that btw 🥇 ).

I have followed the tutorial found here without making custom changes or doing anything different: https://activate.workshop.aws/

Call failed: getParameter({"Name":"/cdk-bootstrap/hnb659fds/version"}) => User: arn:aws:sts::<CICD_ACCOUNT_NUMBER>:assumed-role/cdk-hnb659fds-deploy-role-<CICD_ACCOUNT_NUMBER>-us-west-2/aws-cdk-root is not authorized to perform: ssm:GetParameter on resource: arn:aws:ssm:us-west-2:<CICD_ACCOUNT_NUMBER>:parameter/cdk-bootstrap/hnb659fds/version (code=AccessDeniedException)

From my command line, I am not able to retrieve that SSM Parameter as my "dev" user with "DevOpsEngineer" role/privileges on the CICD account.

my aws profile for "cicd" is my "armenr-dev" user, configured for my CICD account # and is configured to use the DevOpsEngineer/DevOpsAccess permissions and role.

[profile cicd]
sso_start_url = REMOVED
sso_region = us-west-2
sso_account_id = CICD_ACCOUNT_NUMBER
sso_role_name = DevOpsAccess
region = us-west-2
output = json
╭─ armenr  ~/Des/ste/gru/infra                                                                                                                              ✔  10066  03:22:37
├─  main ● 
╰─ aws ssm get-parameters-by-path --path "/cdk-bootstrap/hnb659fds/" --region us-west-2 --profile cicd

An error occurred (AccessDeniedException) when calling the GetParametersByPath operation: User: arn:aws:sts::CICD_ACCOUNT_NUMBER:assumed-role/AWSReservedSSO_DevOpsAccess_cd96dc9ee675f305/armenr-dev is not authorized to perform: ssm:GetParametersByPath on resource: arn:aws:ssm:us-west-2:CICD_ACCOUNT_NUMBER:parameter/cdk-bootstrap/hnb659fds/

DevOpsAccess "Permissions Sets" have the following managed policies attached:

  • SecretsManagerReadWrite
  • AWSCodePipeline_FullAccess
  • AmazonEC2ContainerRegistryFullAccess
  • AWSCodeBuildAdminAccess
  • AWSCloudFormationFullAccess
  • AmazonS3FullAccess
  • SecretsManagerReadWrite

NOTE: Can someone confirm that the correct managed policy is "AWSCodePipeline_FullAccess" and NOT "AWSCodePipelineFullAccess" (without the underscore)?

Any guidance or suggestions would be much appreciated...even if it means I need to add a permission or role myself.

Thank you for all of your excellent work!

Convert to Orgjen

this kit should be converted to orgjen library that can be downloaded from npm i orgjen, and should accompany projen. Projen will then respect the orgjen account structures.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.