Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CodePipeline AND Local Deployments of Lambdas #6159

Closed
jamiepmullan opened this issue Feb 7, 2020 · 13 comments
Closed

CodePipeline AND Local Deployments of Lambdas #6159

jamiepmullan opened this issue Feb 7, 2020 · 13 comments
Assignees
Labels
@aws-cdk/aws-codepipeline Related to AWS CodePipeline guidance Question that needs advice or information.

Comments

@jamiepmullan
Copy link
Contributor

jamiepmullan commented Feb 7, 2020

❓ How can you deploy lambdas locally, but allow a Lambda Deployment Group in the pipeline to also deploy to them (i.e. through Cloudformation in the CodePipeline)

The Question

I've been trying to get a configuration working of my CDK app where I can deploy all my infrastructure from local, but also have the lambdas automatically update on a code release.

Setup:
I've recently started from the beginning to see if there was an easy way around it, following: https://docs.aws.amazon.com/de_de/cdk/latest/guide/codepipeline_example.html

So I have an application where I have a mixture of SNS, lambdas, API gateway etc. but also have my Pipeline configuration consisting of GitHub Source, CodeBuild, CdkBuild to get the template, and CloudFormationCreateUpdateStackAction.

This is 3 stacks in total:

  1. Lambda stack
  2. Infrastructure stack (such as SNS Topic and API Gateway etc.)
  3. Pipeline stack

This is a bit more complicated than what the example in the documentation shows because we have to share resources across multiple stacks to assign lambdas to api gateway for example.

To try and get round it I've got a context variable (set on cdk command) called 'inPipeline' to see if its being run from the pipeline, or locally in a bid to try and set my lambda code to just a Code.asset('') value if in fact local. However because we have the dependency on CfnParametersCode in other stacks, it quickly breaks when you try deploy it with no asset being set (i.e. its local so there isn't one!).

Has anyone else has approached this differently? Or have any suggestions?
I guess the problem here is that I want to allow a lambda to have multiple code sources which isn't going to work.
I can't think of any other way than just putting the whole App creation into the pipeline.

Guess a couple of other alternative would be:

  1. cdk deploy but that will do the whole App

Environment

  • CDK CLI Version: 1.22.0 & 1.23.0
  • OS: [OSX]
  • Language: [TypeScript]

Other information

@jamiepmullan jamiepmullan added the needs-triage This issue or PR still needs to be triaged. label Feb 7, 2020
@skinny85
Copy link
Contributor

skinny85 commented Feb 7, 2020

Hey @jamiepmullan ,

thanks for opening the issue. This is a common question, and I'd figured instead of pasting a ton of code here, I'll create a brand-new CDK project showing how to achieve that:

https://github.com/skinny85/cdk-codepipeline-and-local-lambda-guidance

Let me know if this helps!

Thanks,
Adam

@skinny85 skinny85 added guidance Question that needs advice or information. @aws-cdk/aws-codepipeline Related to AWS CodePipeline and removed needs-triage This issue or PR still needs to be triaged. labels Feb 7, 2020
@skinny85 skinny85 self-assigned this Feb 7, 2020
@jamiepmullan
Copy link
Contributor Author

Hey @skinny85
Thanks for the sample, I will give this a go. Ironically I've been through many permutations of this such as checking the validity of the 'Location' object when it is passed through to to the Lambda or even trying to put extra logic into the pipeline to say whether its to use CfnParametersCode.

@jamiepmullan
Copy link
Contributor Author

jamiepmullan commented Feb 9, 2020

Hey @skinny85
It works... but stuck again because of DnsValidatedCertificate generates an error similar to:

Parameters: [AssetParameters00ArtifactHash00, AssetParameters00S3VersionKey00, AssetParameters00S3Bucket00] must have values (Service: AmazonCloudFormation; Status Code: 400; Error Code: ValidationError; Request ID: 96bf2f48-c252-4a71-8513-a887b7ddff1e)

Looks like you've already commented in #4928 that we are blocked until #3437 is delivered.

@skinny85
Copy link
Contributor

Yes, things that use assets internally, like DNS validated certificates, are blocked until #3437.

As an alternative, you can use the the layer 1 class for the certificate (CfnCertificate).

@jamiepmullan
Copy link
Contributor Author

Thanks @skinny85 - I'm hoping that its not going to be too long until #3437 is delivered!

@jamiepmullan
Copy link
Contributor Author

Hey @skinny85 - quick clarification question...

What I want to be able to do is:

  • Have a separate stack deployment similar to what you are doing in the example you provided with the lambdas. This stack will have lambdas + API Gateway in, to make it a fully functioning microservice (independent to what is currently live).
  • Once we have this new stack spun up, we can then run a 'post deploy' codebuild with our integration tests to show whether the new stack is working as expected. (we don't want to use the postHook's etc. which you can config if you were to use LambdaDeploymentGroup).
  • Once confirmed it is working, we want to promote this stack to live (updating a 'live' stack which controls Route53 records).

My question... only way I can think about doing this is by appending the github hash ID on to the stack name, but can't see a way of doing this... what is your opinion on this? Is there anything else you can suggest?

Let me know if I need to clarify this...

@skinny85
Copy link
Contributor

skinny85 commented Feb 25, 2020

@jamiepmullan just have 2 instantiations of your Stack classes:

new ApiGwStack(app, 'DevStack');
new ApiGwStack(app, 'ProdStack', {
  route53records: ... // optional property
});

@jamiepmullan
Copy link
Contributor Author

jamiepmullan commented Feb 25, 2020

@skinny85 Not a good idea to stand up a side-by-side stack and just migrate traffic to the new stack? (then destroy the old eventually), instead of deploying the infrastructure twice in a CodePipeline as you mentioned in your previous comment?

@skinny85
Copy link
Contributor

skinny85 commented Feb 26, 2020

@skinny85 Not a good idea to stand up a side-by-side stack and just migrate traffic to the new stack? (then destroy the old eventually), instead of deploying the infrastructure twice in a CodePipeline as you mentioned in your previous comment?

How would you do that?

I don't think having a test stack, with an integration test that checks it before deploying production, is anything unusual...

@jamiepmullan
Copy link
Contributor Author

jamiepmullan commented Feb 26, 2020

@skinny85
I have tried to look at being able to set a custom stackName in CloudFormationCreateUpdateStackAction i.e. prefixing a git hash in the stack name to separate them out/avoid clashing and not affect live traffic. I've had no success thus far as the pipeline stack is deployed upfront and needs to use some dynamic name.
i.e. stack name could be:

'r1-lambda'
'r2-lambda'
...

The way I imagined this working was to allow us to do blue/green deployments on stacks as a whole, instead of just individual resources/lambda's. Meaning we're testing the actual stack and infrastructure, before we promote to live (without having to redeploy everything again, we're just changing the dns).

I think the only way of doing this is having a custom CodeBuild that literally runs cdk deploy but I wanted to try and keep it to managed resources from CDK.

One of our use cases that we need to be able to keep the old stack still alive i.e. not destroy/replace it.
I don't think this concept is hugely custom to just us?

@skinny85
Copy link
Contributor

do blue/green deployments on stacks as a whole,

This is what I was asking before. How are you doing that?

@jamiepmullan
Copy link
Contributor Author

do blue/green deployments on stacks as a whole,

This is what I was asking before. How are you doing that?

I don’t think it’s possible at the moment to create stacks in this way... but we would to do it in this way. It’s kinda terraform-ish!

@skinny85
Copy link
Contributor

Sorry, you lost me :(

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
@aws-cdk/aws-codepipeline Related to AWS CodePipeline guidance Question that needs advice or information.
Projects
None yet
Development

No branches or pull requests

2 participants