Where to find AWS Systems Manager (SSM) Document ARNs? - aws-ssm

I am wanting to run an SSM Document on my EC2 instance, AWSFIS-Run-CPU-Stress.
It is being executed via AWS Fault Injection Simulator (FIS), which requires a documentARN to be specified, specifically in format:
arn:aws:ssm:us-east-1::document/AWSFIS-Run-CPU-Stress.
I have also tried arn:aws:ssm:us-west-2:aws-account-ID:document/AWSFIS-Run-CPU-Stress, replacing 'aws-account-ID' with my AWS account ID.
Here is the AWS FIS documentation that states that you must provide an SSM Document ARN: https://docs.aws.amazon.com/fis/latest/userguide/actions-ssm-agent.html#awsfis-run-cpu-stress
However, when I try to run my Fault Injection experiment with the above ARN (I've tried many different regions), the Document can not be found.
Furthermore, I have tried to use aws ssm describe-document on the Document, but ARN is not returned, so I have no idea what I need to use. It doesn't even look like SSM Documents are region specific.
Here is what is returned by aws ssm describe-document:
{
"Document": {
"Hash": "f2b00b4471e7236ddb11654c4e076473f5e493e916f09840abb229d5a07822b1",
"HashType": "Sha256",
"Name": "Test-AWSFIS-Run-CPU-Stress",
"Owner": "703381282345",
"CreatedDate": "2021-05-10T21:08:14.781000+01:00",
"Status": "Active",
"DocumentVersion": "1",
"Description": "Command Document Example JSON Template",
"Parameters": [
{
"Name": "Message",
"Type": "String",
"Description": "Example",
"DefaultValue": "Hello World"
}
],
"PlatformTypes": [
"Windows",
"Linux",
"MacOS"
],
"DocumentType": "Command",
"SchemaVersion": "2.2",
"LatestVersion": "1",
"DefaultVersion": "1",
"DocumentFormat": "JSON",
"Tags": []
}
}
Where can I find the Document ARN?

Apparently Systems Manager console does not show the document ARN. In the meantime you can construct the ARN following this format:
"arn:<partition>:ssm:<region>:<account_id>:document/<document_name>"
This is a valid example of a public FIS SSM "run command" document (available from any account in us-east-1 region), not sure why it failed in your case. No account id is expected because it's a public document:
"arn:aws:ssm:us-east-1::document/AWSFIS-Run-CPU-Stress"
And this is an example of a private document (i.e. you own it), note that this does have account id:
"arn:aws:ssm:us-east-1:012345678912:document/MyFISFaultDocument"

You can execute the specified document using the following aws ssm send-command --document-name "AWSFIS-Run-CPU-Stress" --document-version "4" --parameters '{"CPU":["0"],"InstallDependencies":["True"]}' --timeout-seconds 600 --max-concurrency "50" --max-errors "0" --region us-east-1
You can obtain the above command line by filling in the parameters from this link https://console.aws.amazon.com/systems-manager/run-command/send-command?region=us-east-1#

Related

Describe EBS details volume with AWSCLI

I need to list all owner's aws ami and any details about it.
The following line returns the image_id, CreationDate, Name and organized by CreationDate:
aws ec2 describe-images --owners --query 'Images[*].[ImageId, CreationDate, Name]' | sort_by(#, &[1])' --output text
But, i need any information about BlockDevicesMapping like an Ebs volume [snapshot id, Volume size e etc...]
I did the following line aws ec2 describe-images --owners --query 'Images[*].[ImageId, CreationDate, Name, BlockDeviceMappings:[Ebs:{SnapshotID}]] --output text. But, the search on terminal stopped.
I tried a lot of ways.
Thank's for help-me.
The output from describe-images is as follows.
{
"Images": [
{
"VirtualizationType": "hvm",
"Description": "Provided by Red Hat, Inc.",
"PlatformDetails": "Red Hat Enterprise Linux",
"EnaSupport": true,
"Hypervisor": "xen",
"State": "available",
"SriovNetSupport": "simple",
"ImageId": "ami-1234567890EXAMPLE",
"UsageOperation": "RunInstances:0010",
"BlockDeviceMappings": [
{
"DeviceName": "/dev/sda1",
"Ebs": {
"SnapshotId": "snap-111222333444aaabb",
"DeleteOnTermination": true,
"VolumeType": "gp2",
"VolumeSize": 10,
"Encrypted": false
}
}
],
"Architecture": "x86_64",
"ImageLocation": "123456789012/RHEL-8.0.0_HVM-20190618-x86_64-1-Hourly2-GP2",
"RootDeviceType": "ebs",
"OwnerId": "123456789012",
"RootDeviceName": "/dev/sda1",
"CreationDate": "2019-05-10T13:17:12.000Z",
"Public": true,
"ImageType": "machine",
"Name": "RHEL-8.0.0_HVM-20190618-x86_64-1-Hourly2-GP2"
}
]
}
As you see, BlockDeviceMappings is an array, so you should flatten it first before you attempt to access its objects.
I would suggest specifying --owners 12347989. If you attempt to get all amis of all owners, terminal will hang. I ran the below command with my accountId and got the desired output, but if I don't specify owner, my terminal just hangs.
Try this:
aws ec2 describe-images --owners amazon --query 'Images[*].[ImageId, CreationDate, Name, BlockDeviceMappings[0].DeviceName, BlockDeviceMapping[0].VolumeSize, BlockDeviceMappings[0].SnapshotId]' --output text

How do I replace a Policy Record with a simple A record that points to a CloudFront Distribution without traffic interruption?

My first question would be, what's the best way to do this? It looks to me like the only way to do it without interrupting traffic would be through the AWS CLI, but if there's an easier way I'm all ears! If the CLI is the way to do it, I'm running into issues with the following command:
aws route53 change-resource-record-sets --hosted-zone-id XXXXXXXXXXXX --change-batch file://update-record.json
The update-record.json contains the following:
{
"Comment": "Swaps the Policy Record for a simple routing policy",
"Changes": [
{
"Action": "UPSERT",
"ResourceRecordSet": {
"Name": "www.example.com",
"Type": "A",
"AliasTarget": {
"HostedZoneId": "XXXXXXXXXXXX",
"DNSName": "xxxxxxxxxxxxx.cloudfront.net",
"EvaluateTargetHealth": false
}
}
}
]
}
The error I'm getting is:
An error occurred (InvalidChangeBatch) when calling the ChangeResourceRecordSets operation: [Tried to create an alias that targets xxxxxxxxxxxxx.cloudfront.net., type A in zone XXXXXXXXXXXX, but the alias target name does not lie within the target zone, Tried to create an alias that targets xxxxxxxxxxxxx.cloudfront.net., type A in zone XXXXXXXXXXXX, but that target was not found]
The Hosted Zone ID for the record in the account is accurate, as is the distribution DNS name. The record name, www.example.com, also exists in the account. The distribution has an alternate domain name (CNAME) of www.example.com.
I've also tried doing the change as a delete and create, rather than an upsert:
{
"Comment": "Swaps the Policy Record for a simple routing policy",
"Changes": [
{
"Action": "DELETE",
"ResourceRecordSet": {
"Name": "www.example.com.",
"Type": "A",
"TrafficPolicyInstanceId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
},
{
"Action": "CREATE",
"ResourceRecordSet": {
"Name": "www.example.com.",
"Type": "A",
"AliasTarget": {
"HostedZoneId": "XXXXXXXXXXXX",
"DNSName": "xxxxxxxxxxxxx.cloudfront.net",
"EvaluateTargetHealth": false
}
}
}
]
}
Doing this in two steps yields the same error message.
Each domain and subdomain in Route 53 is considered a "Hosted Zone", and as such has a "Hosted Zone ID". However, while the change-resource-record-sets documentation is extensive, it's not very clear about Alias records that point to a CloudFront distribution. I had to dig deeper, and look into the documentation around AliasTarget specifically. There, the documentation states:
Specify Z2FDTNDATAQYW2. This is always the hosted zone ID when you create an alias record that routes traffic to a CloudFront distribution.
This means that even though I was trying to create an Alias record in the hosted zone with an id of XXXXXXXXXXXX, the ID to use for any Alias record pointing to any CloudFront distribution is Z2FDTNDATAQYW2. Changing the update-record.json to the following works:
{
"Comment": "Swaps the Policy Record for a simple routing policy",
"Changes": [
{
"Action": "DELETE",
"ResourceRecordSet": {
"Name": "www.example.com.",
"Type": "A",
"TrafficPolicyInstanceId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
},
{
"Action": "CREATE",
"ResourceRecordSet": {
"Name": "www.example.com.",
"Type": "A",
"AliasTarget": {
"HostedZoneId": "Z2FDTNDATAQYW2",
"DNSName": "xxxxxxxxxxxxx.cloudfront.net",
"EvaluateTargetHealth": false
}
}
}
]
}
Doing this as a change-resource-record-set prevents interruption in traffic, as:
Change batches are considered transactional changes. Route 53 validates the changes in the request and then either makes all or none of the changes in the change batch request. This ensures that DNS routing isn't adversely affected by partial changes to the resource record sets in a hosted zone.

How to get the Azure subscription and resouce group from within a VM using REST API?

A lot of Azure API endpoints require you pass in the subscriptionID and resource group name of the resouce you want to work with.
From a bash script running on an Azure Linux VM, how can I get these info? I can't have the Azure CLI installed hence looking for some REST API.
There is this old answer which I found convoluted and requires the CLI anyway.
One answer even mentions this API to get all info of one given VM:
/subscriptions/[subscription-id]/resourceGroups/[resource-group-name]/providers/Microsoft.Compute/virtualMachines/[virtual-machine-name]
It seems to be a chicken and egg problem.
You could use this REST API - Subscriptions - List to list all the subscriptions the user can access for an Azure AD tenant.
GET https://management.azure.com/subscriptions?api-version=2019-06-01
For which tenant, it depends on the bearer token you got from, when you get the token, decode in https://jwt.io/, you will find that like below. If you use this token to call this API, it will get all the subscriptions the user can access in the tenant I hid in the screenshot.
If you want to get the resource group the VM is in, you can use this REST API - Virtual Machines - List All, no need to pass the resource-group-name, it can list all the VMs with the subscriptionId, you can get the subscriptionId from the Subscriptions - List.
GET https://management.azure.com/subscriptions/{subscriptionId}/providers/Microsoft.Compute/virtualMachines?api-version=2019-03-01
So in conclusion, if you already know the subscriptionId which the VM is in, you can list all the VMs in the subscription and find the VM in the result, then you will find the resource group name. If you don't know the subscriptionId, you can just list all the subscriptions the user can access in one tenant, and list all the VMs in every subscription. Besides, if you even don't know the tenant-id, you can use Tenants - List to gets all the tenants for your account.
I've found it. The Azure Instance Metadata Service returns a lot of metadata about the Azure VM where the request has made from. I used the following REST endpoint to retrieve the VM's subscriptionId and resourceGroupName:
curl -H Metadata:true "http://169.254.169.254/metadata/instance?api-version=2017-08-01"
{
"compute": {
"location": "",
"name": "",
"offer": "",
"osType": "",
"placementGroupId": "",
"platformFaultDomain": "",
"platformUpdateDomain": "",
"publisher": "",
"resourceGroupName": "",
"sku": "",
"subscriptionId": "",
"tags": "",
"version": "",
"vmId": "",
"vmScaleSetName": "",
"vmSize": "",
"zone": ""
},
"network": {
"interface": [
{
"ipv4": {
"ipAddress": [
{
"privateIpAddress": "",
"publicIpAddress": ""
}
],
"subnet": [
{
"address": "",
"prefix": ""
}
]
},
"ipv6": {
"ipAddress": []
},
"macAddress": ""
}
]
}
}

Managing secrets with aws cli register task definition

I use circleci to build and push the application to aws. I have now managed to create and register a new task definition in the circleci config using the aws cli. This works well. The problem or case i´am having is how do I overwrite the placeholder values using the cli?
Here is how i read the task definition:
aws ecs register-task-definition --cli-input-json file://.circleci/taskdefinition.json
The task definition file:
{
"containerDefinitions": [
{
"cpu": 10,
"environment": [
{
"name": "Secret_api_key",
"value": "placeholder_value"
}
],
"image": "<Image>",
"name": "app-dev"
}
],
"placementConstraints": [],
"memory": "512",
"family": "pp-dev",
"networkMode": "bridge"
}
What I want to know is, how do I update the placeholder_value which I have retrieved from aws secrets manager?
Use sed to replace the placeholders with secret valuables from private environment variables.

CloudFormation without snapshot

Cloudformation created a template for us which specifies both the AMI instance to start from, and also the snapshot ID of that AMI instance.
We create our base AMI instance with Packer, which reports the AMI instance it creates, but does not report the snapshot associated - we find that in the Amazon UI.
Can the Cloudformation template be modified so it does not specify the snapshot ID? Can you give an example of the stanza?
Sure you can! For example, something like this would work:
"Resources": {
"someEC2": {
"Type": "AWS::EC2::Instance",
"Properties": {
"ImageId": "...valid_ami_id...",
"InstanceType": "m3.medium",
"KeyName": "...",
"Monitoring": "false",
"NetworkInterfaces": [
{
...
}
],
"BlockDeviceMappings": [
{
"DeviceName": "/dev/sda",
"Ebs": {
"VolumeSize": 10
}
}
]
}
}
}

Resources