AWS CodeDeploy Most Recent Revision - amazon-web-services

I am using AWS CLI for CodeDeploy.
CodeDeploy is not deploying the most recent revision, instead it is deploying the last revision I manually deployed.
I have left the version and etag out of my cli command. As per the documentation:
(Optional) The Amazon S3 version identifier for the revision. (If the
version identifier is not specified, AWS CodeDeploy will use the most
recent version.)
aws deploy create-deployment --application-name MyApp --deployment-config-name CodeDeployDefault.OneAtATime --deployment-group-name MyAppGroup --description "My App" --s3-location bucket=MyAppBucket,bundleType=zip,key=MyApp.zip
But it is not working. Any ideas? Is there a way to specifically enforce CodeDeploy to use the latest revision?
There is the S3 lifecycle to make sure the older versions are removed, but that is a hack at best. There needs to be an overwrite, or simply a way to force this.

By default, if you don't specify the version identifier when creating a deployment, CodeDeploy will try to deploy the latest revision by default according to http://docs.aws.amazon.com/codedeploy/latest/userguide/deployments-create-cli.html. But do you know how long do you create a deployment after push the new revision to S3?
Thanks,
Binbin

Here's a one-liner for that:
aws deploy list-application-revisions \
--sort-by registerTime --sort-order descending \
--application-name $MY_APPLICATION_NAME \
--region eu-central-1 --s3-bucket $MY_BUCKET \
--query 'revisions[0].s3Location.key' \
--output text --no-paginate
Flags --sort-by registerTime --sort-order descending sort the result such that we can parse out the first one easily (see --query).
Flags --output text --no-paginate returns the result in plain text instead of json. The --no-paginate option is required here due to an oddity with the cli to avoid returning the word "None" along with the results.
The --query flag parses the result, getting the key property of the s3Location object which is the first element of the revisions array.

Related

AWS CLI get-parameter seems to be getting old version

I have a few versions of a SecureString value in AWS Parameter Store. When the following command is invoked locally:
aws ssm get-parameter --with-decryption --name "/my/secret/path" --output text --query Parameter.Value
I get the latest version of the parameter. However, when this is enacted via a GitHub runner, it is only ever getting version 1 of the parameter. When I attempt to specify the version:
aws ssm get-parameter --with-decryption --name "/my/secret/path:4" --output text --query Parameter.Value
I get a message back saying that version 4 of the parameter doesn't exist, although the query does execute when run locally.
I have tried running it with Parameter.Version without the version number specified to confirm and have confirmed when I run it locally, version 4 comes back, but when the runner executes it, version 1 comes back.
AWS CLI 2.8.6 is being used both locally and on the Runner. The documentation says that this should be returning the latest version when no version is specified
Has anyone experienced this before and are there any tricks to getting this to work?
Much appreciation to Marcin above who very quickly pointed out that there may be a difference in accounts coming into effect. The secret had been updated in one but not the other, and the identical naming was throwing the investigation off. I was able to resolve this by updating the secret in both the account that the local environment and the GitHub environment were using.

Difference between --parameter-overrides and --tags

I am having a hard time understanding the difference between --parameter-overrides and --tags when deploying an AWS stack using CloudFormation.
I tried to read through the documentation but I still do not understand, I seem to get exactly the same behaviour when I use the cli to deploy my stack with the usage of one or the other flag, such as
aws --profile $PROFILE cloudformation deploy
--stack-name ${STACK_NAME}
--template-file $TEMPLATE_FILE
--parameter-overrides
ApplicationName=$APP_NAME
--no-fail-on-empty-changeset
--tags
ApplicationName=$APP_NAME
When and why would I use the tags? Any help?
--tags set arbitrary Tags on the Stack. Tags are key-value metadata for labelling and categorizing AWS resources. Tags are optional. They do not affect how CloudFormation deploys the stack.
--parameter-overrides inject parameter values into the template. Optional if you are happy with the template's parameter defaults (for new deploys) or currently deployed values (for updates).

put-rest-api aws cli not updating endpoint description tags

I am trying to update my rest api via the aws cli and I don't get the results I desire. I am running the commands
aws apigateway put-rest-api --rest-api-id XXXXXXXXXX --mode merge --body 'file://api.yaml'
aws apigateway create-deployment --rest-api XXXXXXXXXX --stage-name latest
However I notice that even though the endpoint was added, documentation specific things such as tags and description are not being set and so when we fetch the swagger definition from aws, these keys are omitted.
I put the yaml file I am using with the into https://editor.swagger.io/ and no problems there as well
I don't get any errors when running the above commands. I don't understand why the "merge" process is not finding the swagger keys and applying them.
I figured out that not only do I need to run an update via the put-rest-api command but I also need to publish the documentation(did this via the AWS Console UI and it worked). I haven't found the best command to do so via the aws cli. Will make an edit when I do.
EDIT
I have learned that the aws cli cmd put-rest-api is a precursor for updating the documentation and definition of the REST API, and that the two are deployed via different commands. So I was missing the step:
aws apigateway create-documentation-version --rest-api-id XXXXXXXXX --documentation-version test_version --stage dev
As you may or may not know, you can only deploy documentation once so use
aws apigateway update-stage --stage-name dev --rest-api-id tu2ye61vyg --patch-operations "op=replace,path=/documentationVersion,value=test_version" to deploy an existing version to another stage

How to export serverless cloudformation output variables to a file or a task runner?

I'm using serverless.yml to create a couple services in AWS cloudformation, specifically: cognitoUserPool and UserPoolClient.
Both of these creations will return IDs that I will use on my flat html files with the cognito library to connect to amazon cognito, so, since I am serving flat files from S3, I need these values to be coded inside the files.
Now I'm looking for a way of automating this, perhaps leaving a placeholder in the files and then running them through a preprocessor that changes the placeholders with the output values before uploading them to S3.
Any ideas how this can be achieved? My first guess would be to export the output variables from serverless deploy and then use these values on a task runner.
To achieve this without using a Serverless plugin, add the follow to your package.json file:
"scripts": {
"sls:info": "sls info --verbose | tee ./.slsinfo",
}
This will create the file .slsinfo containing your serverless outputs (amongst other things). Run by calling npm run sls:info
You can then update package.json:
"scripts": {
"sls:deploy": "sls deploy && npm run sls:info",
"sls:info": "sls info --verbose | tee .slsinfo",
}
Now you can call npm run sls:deploy and it will deploy your service and add your outputs to .slsinfo file.
To use the info in .slsinfo the easiest way I have found is to use regex. Example below:
const slsinfo = require('fs').readFileSync('./.slsinfo', 'utf8');
function getOutput(output) {
return slsinfo.match(new RegExp('('+output+': )((.?)+)(\\n)'))[2];
}
Using the above method you can get your output as follow:
const var = getOutput('MyOutputName')
To get outputs from serverless you can use the serverless-stack-output plugin or you can deduce the stack name and use the aws command.
aws cloudformation describe-stacks --stack-name SERVICE-STAGE --query Stacks[0].Outputs
Replace SERVICE with your service name and STAGE with your stage. You should get a JSON object with the outputs from this command.
If you want to get just specific outputs, try:
aws cloudformation describe-stacks --stack-name SERVICE-STAGE --query 'Stacks[0].Outputs[?OutputKey==`OUTPUT_KEY`].OutputValue' --output text
Replace SERVICE, STAGE and OUTPUT_KEY with the values you want.
On Windows use (the quotes work differently):
aws cloudformation describe-stacks --stack-name SERVICE-STAGE --query Stacks[0].Outputs[?OutputKey==`OUTPUT_KEY`].OutputValue --output text
For more details on --query see https://docs.aws.amazon.com/cli/latest/userguide/controlling-output.html

How to find latest or most recent AWS RDS snapshot?

I can call aws rds describe-db-snapshots --db-instance-identifier {my_db_instance} and sort all automated snapshots to find the most recently created one but I was hoping someone has a better idea out there.
For me, this one works:
aws rds describe-db-snapshots \
--query="max_by(DBSnapshots, &SnapshotCreateTime)"
The query parameter returns only the most recent one.
If only the Arn is needed, this one might help:
aws rds describe-db-snapshots \
--query="max_by(DBSnapshots, &SnapshotCreateTime).DBSnapshotArn" \
--output text
And all that for a specific database instance:
aws rds describe-db-snapshots \
--db-instance-identifier={instance identifier} \
--query="max_by(DBSnapshots, &SnapshotCreateTime).DBSnapshotArn" \
--output text
I know this is old, but I was needing to know the same information and was able to construct the following which will then just give me the snapshot name. It doesn't totally answer your question about emphatically finding the latest snapshot but in this example might give you some better direction.
aws rds describe-db-snapshots --db-instance-identifier prd --snapshot-type automated --query "DBSnapshots[?SnapshotCreateTime>='2017-06-05'].DBSnapshotIdentifier"
To break it down with the options
--db-instance-identifier (put in your instance name your are looking for)
--snapshot-type (I put in automated to find the automated backups)
--query "DBSnapshots[?SnapshotCreateTime>='2017-06-05'].DBSnapshotIdentifier"
(This is what I used to refine my search as we do daily backups, I just look for the snapshot create time to be greater than today and by giving the .DBSnapshotIdentifier gives me back just the name.
Hopefully this will help somebody else out.
My way:
> aws rds describe-db-snapshots --db-instance-identifier ${yourDbIdentifier} --query="reverse(sort_by(DBSnapshots, &SnapshotCreateTime))[0]|DBSnapshotIdentifier"
> "rds:dbName-2018-06-20-00-07"
If someone is looking for cluster command:
aws rds describe-db-cluster-snapshots --db-cluster-identifier prod --snapshot-type automated --query "DBClusterSnapshots[?SnapshotCreateTime>='2017-06-05'].DBClusterSnapshotIdentifier"
As at 31th October 2014, it looks like you can use the --t flag to list only automated backups.
http://docs.aws.amazon.com/AmazonRDS/latest/CommandLineReference/CLIReference-cmd-DescribeDBSnapshots.html
From there, you should be able to parse the output to determine your latest snapshots.
rds-describe-db-snapshots --t automated
DBSNAPSHOT rds:<NAME>-2016-08-09-17-12
There is no any other more simple way around for this.
I am getting this error while restoring the db from snapshot with the id that I get with the command from the above methods:
An error occurred (InvalidParameterValue) when calling the RestoreDBInstanceFromDBSnapshot operation: Invalid snapshot identifier: "rds:dev-mysql-rds1-2018-10-06-01-09"
So, I have modified the above query to make it work for me, here is a query that worked for me to get the latest snapshot that worked with restore-db-instance-from-db-snapshot
aws rds describe-db-snapshots --query "DBSnapshots[?DBInstanceIdentifier=='MASTER_INSTANCE_IDENTIFIER']" | jq -r 'max_by(.SnapshotCreateTime).DBSnapshotIdentifier'
aws rds describe-db-cluster-snapshots --snapshot-type=automated --query="max_by(DBClusterSnapshots,&SnapshotCreateTime)"
This works in 2022.08
If it is RDS cluster then you can use below command:
aws rds describe-db-cluster-snapshots --db-cluster-identifier <DBClusterIdentifier> --region <region> --query="max_by(DBClusterSnapshots, &SnapshotCreateTime)"
you can use below command to fetch specific snapshot ARN:
aws rds describe-db-cluster-snapshots --db-cluster-identifier <DBClusterIdentifier> --region <region> --query="max_by(DBClusterSnapshots, &SnapshotCreateTime).DBClusterSnapshotArn"