I am creating a aws-amplify app via aws-cdk and everything works fine except it doesn't start a build automatically. If I do a git commit (I have enabled continuous deploys) it will build and run just fine. But on a new aws account with a cdk deploy I have to start the first commit manually...
I had this issue as well while working on the deployment of an amplify hosted application.
After going through the AWS CLI documentation for Amplify, I found the start-job command. This command allows you to start an amplify job for a specific branch.
You can then create an AwsCustomResource that makes an SDK call to start-job.
This is what I ended up with.
const build_trigger = new customResource.AwsCustomResource(this, 'triggerAppBuild', {
policy: customResource.AwsCustomResourcePolicy.fromSdkCalls({
resources: customResource.AwsCustomResourcePolicy.ANY_RESOURCE
}),
onCreate: {
service: 'Amplify',
action: 'startJob',
physicalResourceId: customResource.PhysicalResourceId.of('app-build-trigger'),
parameters: {
appId: amplifyApp.appId,
branchName: master.branchName,
jobType: 'RELEASE',
jobReason: 'Auto Start build',
}
},
});
Note that you should replace amplifyApp.apiId and master.branchName with your own app ID and branch name. I am using the amplify-alpha, so you may need to get the App ID and branch name another way.
Amplify app builds are triggered by push events. Use a CDK Custom Resource or its simpler cousin Trigger to generate a push event during the CDK stack creation.
For a github repo, for instance, your Trigger construct's lambda would call the Github webhook test API, which will trigger the hook with the latest push to the current repository. Both Custom Resources and Triggers can be configured to run only on stack creation. Remember to give your lambda any necessary repo credentials (e.g. set environment variables via a secret).
Related
I uses CDK to create and deploy pipeline(with AWS CodePipeline https://aws.amazon.com/codepipeline/), and today Source stage stopped working, complaining about insufficient permission, which turns out to be that the Github token is expired. Error:
"Could not access the GitHub repository: "pandaWebsite". The access token might be invalid or has been revoked. Edit the pipeline to reconnect with GitHub."
So I re-genereate the Github token, and updated it in AWS Secrets Manager. And click "Retry" button in pipeline, and it still failed. Eventually I have to run cdk destroy to destroy the pipeline, and run cdk deploy to re-deploy the pipeline, and then it works.
My question is, why I have to destroy and re-deploy the pipeline? I was expecting that once I updated the token in Secrets Manager, it should just work.
More context
AWS Secrets Manager is where I stored the Github token, and my CDK code fetch from it. See code here:
// Add Source stage to fetch code from GitHub repository.
private addSourceStage(
pipeline: codepipeline.Pipeline,
sourceCode: codepipeline.Artifact
) {
pipeline.addStage({
stageName: "Source",
actions: [
new codepipeline_actions.GitHubSourceAction({
actionName: "Checkout",
owner: "yangliu",
repo: "pandaWebsite",
branch: "main",
// read the value from Secrets Manager
oauthToken: CDK.SecretValue.secretsManager(
"github-token"
),
output: sourceCode,
trigger: codepipeline_actions.GitHubTrigger.WEBHOOK,
}),
],
});
}
I'm using CDK and am trying to define a CodePipeline that triggers a Lambda Deployment. It doesn't seem as if there are any CDK constructs to achieve this.
I could only find CodeDeployEcsDeployAction and CodeDeployServerDeployAction.
The problems are:
CodeDeployEcsDeployAction: asks for an ECS task definition
CodeDeployServerDeployAction: only accepts an artifact input for properties. However, it won't pick up the appspec file I have defined in the artifact and there are no properties to define the path
(There is no way to do artifact.atPath('appspec.json'))
(Submitted issue 20782 just in case this is an actual request)
Here's my Lambda CodeDeploy setup
const application = new codedeploy.LambdaApplication(
this,
'CodeDeployLambdaApplication',
{
applicationName: 'LambdaApplication',
},
);
const lambdaDeploymentGroup = new codedeploy.LambdaDeploymentGroup(
this,
'AllAtOnceDeployment',
{
application,
alias,
deploymentConfig: codedeploy.LambdaDeploymentConfig.ALL_AT_ONCE,
},
);
You need to use CodeDeploy and Lambda Action:
https://docs.aws.amazon.com/cdk/api/v1/docs/aws-codedeploy-readme.html for the general docs, specifically:
https://docs.aws.amazon.com/cdk/api/v1/docs/aws-codedeploy-readme.html#lambda-applications
Alternatively, if your program is not that complex and does not need all the additional overhead that CodeDeploy brings (having to synth the template and pass it to CodeDeploy and all) then just use a codebuild, that takes a source from your git repo and runs the command cdk deploy your stack
I am trying to do something that seems fairly logical and straight forward.
I am using the AWS CDK to provision an ecr repo:
repository = ecr.Repository(
self,
id="Repo",
repository_name=ecr_repo_name,
removal_policy=core.RemovalPolicy.DESTROY
)
I then have a Dockerfile which lives at the root of my project that I am trying to push to the same ECR repo in the deployment.
I do this in the same service code with:
assets = DockerImageAsset(
self,
"S3_text_image",
directory=str(Path(__file__).parent.parent),
repository_name=ecr_repo_name
)
The deployment is fine and goes ahead and the ECR Repo is created, but the image is pushed to a default location aws-cdk/assets
How do I make the deployment send my Dockerfile to the exact ECR repo I want it to live in ?
AWS CDK depricated the repositoryName property on DockerImageAsset. There are a few issues on GitHub referencing the problem. See this comment from one of the developers:
At the moment the CDK comes with 2 asset systems:
The legacy one (currently still the default), where you get to specify a repositoryName per asset, and the CLI will create and push to whatever ECR repository you name.
The new one (will become the default in the future), where a single ECR repository will be created by doing cdk bootstrap and all images will be pushed into it. The CLI will not create the repository any more, it must already exist. IIRC this was done to limit the permissions required for deployments. #eladb, can you help me remember why we chose to do it this way?
There is a request for a new construct that will allow you to deploy to a custom ECR repository at (aws-ecr-assets) ecr-deployment #12597.
Use Case
I would like to use this feature to completely deploy my local image source code to ECR for me using an ECR repo that I have previously created in my CDK app or more importantly outside the app using an arn. The biggest problem is that the image cannot be completely abstracted into the assets repo because of auditing and semantic versioning.
There is also a third party solution at https://github.com/wchaws/cdk-ecr-deployment if you do not want to wait for the CDK team to implement the new construct.
I am using terraform to create all the infra(CodePipeline, lambda, buckets) on AWS
currently, I've created a pipeline that builds the source zip file and puts it on s3 bucket but the lambda still keeps using the older source. So, I update the URL manually in the AWS console and it works.
Now I want to automate the flow but available solutions are:
AWS SAM + CFT
Codebuild Stage to update the source using AWS CLI
Create a lambda that updates the source
Code Deploy + AWS SAM + CFT
I am not willing to use CFT at all since all of our code is in terraform and CFT requires me to create new lambdas instead of using old ones.
is there any other simpler way to update the lambda source through Codepipeline
The preferred way to deploy a Lambda via CodePipeline is using a CloudFormation Deploy action [1]. Since you are not looking to use CloudFormation, next option could be to run your terraform plan/apply commands from within a CodeBuild job that is part of the pipeline. You will need to provide the CodeBuild role required permission for resource creation (or export the credentials in Environment variabels for TF to use via this [2] method) and install the TF binary within install phase of buildspec.
Ref:
[1] Building a Continuous Delivery Pipeline for a Lambda Application with AWS CodePipeline - https://docs.aws.amazon.com/lambda/latest/dg/build-pipeline.html
[2] How to retrieve Secret Manager data in buildspec.yaml
I have a CodePipeline setup. But now I want to only have my Pipeline run when I trigger it manually, is that possible?
This worked for me:
Set up a regular pipeline with Github webhook set.
This will create and register an internal aws webhook.
Then simply deregister and remove the webhooks like it is written in the aws docs via aws-cli.
Adjust the following to your region, mine is us-east-2:
Find out the name of the webhook:
aws codepipeline list-webhooks
De-register:
aws codepipeline deregister-webhook-with-third-party --webhook-name <webhook-name>
Delete:
aws codepipeline delete-webhook --name <webhook-name>
Note:
It's necessary to have the source step configured to use the Github webhook.
Now you can trigger your pipeline manually via AWS Console or via aws-cli with:
aws codepipeline start-pipeline-execution --name <pipeline-name>
You need configure your CodePipeline to be triggered by CloudWatch event. Once you've done that, an event rule under CloudWatch named "codepipeline-{repository_name}" will be created.
Disabling this rule will stop CodePipeline from been triggered by CodeCommit. When you need a build, just click 'Release Change' button.
You can use CloudWatch Events, to never trigger your pipeline:
https://docs.aws.amazon.com/codepipeline/latest/userguide/pipelines-trigger-source-schedule-console.html
Set up a cronjob that will never execute, and then you can manually trigger the pipeline whenever you want by clicking on the 'Release change' button.
I haven't tested, but I think it should work.