How to check AWS secretsmanager rotation is completed successfully - amazon-web-services

Created a secret in AWS secretsmanager, enabled automatic rotation with lambda function.
when I trigger rotation for the first time from cli, It's not completed. This is the initial state of secret when updated secret in aws console manually.
# aws secretsmanager list-secret-version-ids --secret-id ******
{
"Versions": [
{
"VersionId": "9e82b9e2-d074-478e-83a5-baf4e578cb49",
"VersionStages": [
"AWSCURRENT"
],
"LastAccessedDate": 1592870400.0,
"CreatedDate": 1592889913.431
},
{
"VersionId": "e32ddaf8-7f21-40e2-adf8-f976b8f3f104",
"VersionStages": [
"AWSPREVIOUS"
],
"LastAccessedDate": 1592870400.0,
"CreatedDate": 1592887518.46
}
],
"ARN": "arn:aws:secretsmanager:us-east-1:***********:secret:***********",
"Name": "*******"
}
Now I triggered rotation from aws cli
aws secretsmanager rotate-secret --secret-id ******
# aws secretsmanager list-secret-version-ids --secret-id ********
{
"Versions": [
{
"VersionId": "704102f3-b36d-4529-b257-0457354d3c93",
"VersionStages": [
"AWSPENDING"
],
"CreatedDate": 1592890351.334
},
{
"VersionId": "e32ddaf8-7f21-40e2-adf8-f976b8f3f104",
"VersionStages": [
"AWSPREVIOUS"
],
"LastAccessedDate": 1592870400.0,
"CreatedDate": 1592887518.46
},
{
"VersionId": "9e82b9e2-d074-478e-83a5-baf4e578cb49",
"VersionStages": [
"AWSCURRENT"
],
"LastAccessedDate": 1592870400.0,
"CreatedDate": 1592889913.431
}
],
"ARN": "arn:aws:secretsmanager:us-east-1:**********:secret:********",
"Name": "********"
}
Cloudwatch log stopped at this createSecret: Successfully put secret for ARN arn:aws:secretsmanager:xxxxxxx.. looks like only createsecret function is called.
When I rotate the secret again, Gets this output in cli
An error occurred (InvalidRequestException) when calling the RotateSecret operation: A previous rotation isn't complete. That rotation will be reattempted.
Unable to understand what's happening. Can someone help?

Unfortunately there is no out-of-the-box way for that, as Secrets Manger does not have build in SNS notification nor CloudWatch Events for when rotation completes.
Thus, you have to construct a solution yourself, which can be done using SDK or CLI.
For CLI you can use describe-secret and pull secret details in a loop. In the loop, you have to look into AWSPENDING and AWSCURRENT labels for the versions.
From the docs:
If instead the AWSPENDING staging label is present but is not attached to the same version as AWSCURRENT then any later invocation of RotateSecret assumes that a previous rotation request is still in progress and returns an error.
So basically, looking at your output:
{
"VersionId": "704102f3-b36d-4529-b257-0457354d3c93",
"VersionStages": [
"AWSPENDING"
],
"CreatedDate": 1592890351.334
}
you have a version with AWSPENDING label, which is not attached to the same version as AWSCURRENT. This indicates that the rotation is in progress.
The rotation completes, when a version is in one of the two states:
The AWSPENDING and AWSCURRENT staging labels are attached to the same version of the secret, or The AWSPENDING staging label is not attached to any version of the secret.

Secrets Manager will publish an event via CloudTrail - 'RotationSucceeded' when there is a successful rotation.
See this for more information on how to setup a Cloudwatch alarm off that CloudTrail event - https://docs.aws.amazon.com/secretsmanager/latest/userguide/monitoring.html

Related

Terraform Import AWS Secrets Manager Secret Version

AWS maintains a secret versioning system, a new version is created if the secret value is updated or if the secret is rotated.
I am in the process of getting existing secrets in AWS under the purview of Terraform. As step 1 I declared all the Terraform resources I needed :
resource "aws_secretsmanager_secret" "secret" {
name = var.secret_name
description = var.secret_description
kms_key_id = aws_kms_key.main.id
recovery_window_in_days = var.recovery_window_in_days
tags = var.secret_tags
policy = data.aws_iam_policy_document.secret_access_policy.json
}
// AWS secrets manager secret version
resource "aws_secretsmanager_secret_version" "secret" {
secret_id = aws_secretsmanager_secret.secret.id
secret_string = jsonencode(var.secret_name_in_secrets_file)
}
Next I imported :
Import secret to state :
terraform import module.<module_name>.aws_secretsmanager_secret.secret
arn:aws:secretsmanager:<region>:<account_id>:secret:<secret_name>-<hash_value>```
Import secret version to state :
terraform import module.<module_name>.aws_secretsmanager_secret_version.secret
arn:aws:secretsmanager:<region>:<account_id>:secret:<secret_name>-<hash_value>|<unique_secret_id aka AWSCURRENT>
Post this I expected the Terraform plan to only involve changes to the resource policy. But Terraform tried to destroy and recreate the secret version, which did not make sense to me.
After going ahead with the plan the secret version that was initially associated with the AWSCURRENT staging label, the one that I used above in the import became the AWSPREVIOUS staging label id and a new AWSCURRENT was created.
Before terraform import :
{
"Versions": [
{
"VersionId": "initial-current",
"VersionStages": [
"AWSCURRENT"
],
"LastAccessedDate": "xxxx",
"CreatedDate": "xxx"
},
{
"VersionId": "initial-previous",
"VersionStages": [
"AWSPREVIOUS"
],
"LastAccessedDate": "xxxx",
"CreatedDate": "xxxx"
}
],
"ARN": "xxxx",
"Name": "xxxx"
}
After TF import and apply:
{
"Versions": [
{
"VersionId": "post-import-current",
"VersionStages": [
"AWSCURRENT"
],
"LastAccessedDate": "xxxx",
"CreatedDate": "xxx"
},
{
"VersionId": "initial-current",
"VersionStages": [
"AWSPREVIOUS"
],
"LastAccessedDate": "xxxx",
"CreatedDate": "xxxx"
}
],
"ARN": "xxxx",
"Name": "xxxx"
}
I was expecting initial-current to remain in the AWSCURRENT stage part. Why did AWS make the initial AWSCURRENT secret ID that I imported using TF into AWSPREVIOUS and create a new one since nothing changed in terms of value or rotation? I expected no changes on that front since TF imported the version

How to DescribeVPCs in a particular AWS region using Go AWS SDK?

I want to query all VPCs belonging to a particular region in my Go-based microservice.
https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeVpcs.html indicates that there exists no filter option by region or any other request parameter.
Golang SDK reference document:
https://docs.aws.amazon.com/sdk-for-go/api/service/ec2/#EC2.DescribeVpcs
Command line SDK reference document: https://docs.aws.amazon.com/cli/latest/reference/ec2/describe-vpcs.html
Here's an example.
{
"Vpcs": [
{
"CidrBlock": "30.1.0.0/16",
"DhcpOptionsId": "dopt-19edf471",
"State": "available",
"VpcId": "vpc-0e9801d129EXAMPLE",
"OwnerId": "111122223333",
"InstanceTenancy": "default",
"CidrBlockAssociationSet": [
{
"AssociationId": "vpc-cidr-assoc-062c64cfafEXAMPLE",
"CidrBlock": "30.1.0.0/16",
"CidrBlockState": {
"State": "associated"
}
}
],
"IsDefault": false,
"Tags": [
{
"Key": "Name",
"Value": "Not Shared"
}
]
}
]
}
However, if I use the command
$aws ec2 describe-vpcs --region us-west-1
then I can query all vpcs in region us-west-1.
Question 1. Why is the --region option not mentioned in the CLI SDK document?
Question 2. How can I incorporate the same in DescribeVpcsInput while using GO SDK?
The --region flag on the CLI is not a filter, it is a required setting that tells the AWS CLI what region to connect to. The ec2 describe-vpcs command is always limited to a single region (most AWS commands are).
You would configure your AWS SDK client with the region you want it to connect to as well. See "Specifying the AWS Region" here.

Attempting to update AWS secret isn't saving in AWS

I’m on Mac Monterrey. Using the AWS CLI, I want to update a secret's value, so I did this
aws secretsmanager update-secret --secret-id 'development/database' --description '{"adapter": "mysql2", "encoding": "utf8", "host": "host.docker.internal"}'
And I get back
{
"ARN": "arn:aws:secretsmanager:us-east-1:1234678901234:secret:development/database-4walfE",
"Name": "development/database"
}
However, when I go to see the value of my secret, it is unchanged
$ aws secretsmanager get-secret-value --secret-id 'development/database'
{
"ARN": "arn:aws:secretsmanager:us-east-1:1234678901234:secret:development/database-4abcdE",
"Name": "development/database",
"VersionId": "378861d2-c5f0-48a4-a965-13877321da62",
"SecretString": "{\"adapter\": \"mysql2\", \"encoding\": \"utf8\", \"host\": \"127.0.0.1\"}",
"VersionStages": [
"AWSCURRENT"
],
"CreatedDate": "2022-04-11T12:00:43.029000-05:00"
}
What gives? What am I missing?
If you're updating the value of the secret, you should use --secret-string
aws secretsmanager update-secret --secret-id 'development/database' --secret-string '{"adapter": "mysql2", "encoding": "utf8", "host": "host.docker.internal"}'

How to trigger an AWS Event Rule when a S3 key with a specific suffix gets uploaded

I'm trying to create an AWS Event Rule that is only triggered when a file with a specific suffix is uploaded to an S3 bucket.
{
"source": [
"aws.s3"
],
"detail-type": [
"AWS API Call via CloudTrail"
],
"detail": {
"eventSource": [
"s3.amazonaws.com"
],
"eventName": [
"PutObject",
"CompleteMultipartUpload"
],
"requestParameters": {
"bucketName": [
"bucket-name"
],
"key": [
{ "suffix": ".csv" }
]
}
}
}
As I understand there AWS has content-based filtering which can be used but docs doesn't show the ability to use a suffix, only prefix among other patterns: https://docs.aws.amazon.com/eventbridge/latest/userguide/content-filtering-with-event-patterns.html
Ideally I could be able to do it here without the need for an intermediary Lambda as my event target is an ECS Fargate task.
At this time (July 2020) CloudWatch events does not appear to have suffix filtering built into it.
You could instead configure an S3 Event Notification which do support the ability to specify prefixes and suffixes.
By using an S3 event notification you can still have your target as a Lambda.

aws ec2 create-volume not creating volume

I'm running the following command:
aws ec2 create-volume --region eu-west-1 --availability-zone eu-west-1a --snapshot-id snap-02583b4b1fb1d2d84
And I get the response:
{
"SnapshotId": "snap-02583b4b1fb1d2d84",
"Size": 40,
"VolumeType": "standard",
"Encrypted": true,
"State": "creating",
"VolumeId": "vol-0d7bec77ac1164266",
"CreateTime": "2017-05-09T10:17:03.521Z",
"AvailabilityZone": "eu-west-1a"
}
However, any subsequent command; such as:
aws ec2 wait volume-available --volume-ids vol-0d7bec77ac1164266
Returns:
Waiter VolumeAvailable failed: The volume 'vol-0d7bec77ac1164266' does not exist.
When I look on the web UI volumes dashboard; I cannot see the volume. I have checked in every region.
Anyone ever seen this behaviour before?
UPDATE
The command appears to work as expected if I execute it on another computer using a different IAM user with * permissions on * resources.
UPDATE 2
It appears that the volume is encrypted and the permissions may not be compensating for an encrypted volume.
I had this same issue attempting to create a Volume from an encrypted Snapshot. The create volume command appears to complete successfully:
{
"AvailabilityZone": "eu-west-1a",
"Encrypted": true,
"VolumeType": "gp2",
"VolumeId": "vol-xxxxx",
"State": "creating",
"Iops": 100,
"SnapshotId": "snap-xxxxx",
"CreateTime": "2017-07-14T21:03:24.430Z",
"Size": 10
}
However, the Volume never appears to be created and cannot be found attempting to describe it.
The issue was that the KMS key the Snapshot was created with was pending deletion. By cancelling the KMS deletion and re-enabling the key the Volume was created successfully.
OK. I have got it working; but I still believe that there is an issue with the CLI.
The volume being created is encrypted. Therefore permissions are needed to handle encrypted volumes.
The only way I could get it to work was to add the following permissions:
"kms:CreateGrant",
"kms:ListGrants",
"kms:RevokeGrant",
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey",
"ec2:AttachVolume",
"ec2:DescribeVolume*",
"ec2:Describe*",
"ec2:CreateVolume",
"ec2:DescribeSnapshots",
"ec2:AttachVolume"
The tool doesn't report any permission errors when executing the command on an encrypted volume.
I've raised the issue: https://github.com/aws/aws-cli/issues/2592
I was unable to reproduce your problem.
I did the following steps:
Created an IAM user with these permissions as an inline policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Statement1",
"Effect": "Allow",
"Action": [
"ec2:CreateVolume"
],
"Resource": [
"*"
]
}
]
}
Created a volume from a snapshot (as that User):
aws ec2 create-volume --region ap-southeast-2 --availability-zone ap-southeast-2a --snapshot-id snap-abcd1234 --profile xyz
{
"AvailabilityZone": "ap-southeast-2a",
"Encrypted": false,
"VolumeType": "standard",
"VolumeId": "vol-03e2eee8e64f593d3",
"State": "creating",
"SnapshotId": "snap-abcd1234",
"CreateTime": "2017-05-11T05:17:23.960Z",
"Size": 30
}
The volume was created successfully.
That user doesn't have permissions to call VolumeAvailable, so I used a different user:
aws ec2 wait volume-available --volume-ids vol-03e2eee8e64f593d3 --region ap-southeast-2 --profile normal
The command completed immediately without error.