In AWS ECS, the hostname of the docker container is the container runtime id. Is there any way that given a container rumtime id, the task ARN under which the container is running can be fetched?
There isn't any specific AWS command which can fetch the task ARN from the container runtime id. But this can be achieved using list-tasks and describe-tasks command of aws ecs, if you know the cluster and service name in prior.
Here is the idea of how you can achieve this:
tasksList=`aws ecs list-tasks --cluster mycluster --service-name myservice | awk '/mycluster/ {print}' | sed 's/,$//' | awk '{ sub(/^[ \t]+/, ""); print }' | awk '{printf "%s ",$0} END {print ""}'`
taskDesc="aws ecs describe-tasks --cluster mycluster --tasks ${tasksList}"
eval $taskDesc | awk '/taskArn|runtimeId/ {print $0}' | awk '{ sub(/^[ \t]+/, ""); print }' | awk '!visited[$0]++' | awk '/taskArn/ {$0=$0"->"} 1'
This will give you an output something like this:
"taskArn": "arn:aws:ecs:<aws_region>:<account_id>:task/mycluster/043de9ab06bb41d29e97576f1f1d1d33",->
"runtimeId": "191c90bae67844124ff2d079f4de997dc8cb9e3c93cd451d931c806283ea527d",
"runtimeId": "61e6fa6e1cbb5039e1c4df31d5c522b9439c22fbeff3c9cc1fb4429ffbb5a94d",
"taskArn": "arn:aws:ecs:<aws_region>:<account_id>:task/mycluster/14478901e8364466b8fd8236d6a66c5e",->
"runtimeId": "b679c5139f019f526c4301c8cc511723abd6aed3fa8cf9c397147d33275a860c",
"runtimeId": "0e727f660616df970b2cf767ea389bee97cd748ea9e09266cb5ee651ad2d2971",
"runtimeId": "ee7fb30715d9ff325eebcfacdde978179f07b1e3bf91a0dac92abd3b54970307",
"taskArn": "arn:aws:ecs:<aws_region>:<account_id>:task/mycluster/23d037af17f54a59afe50f810afdecf0",->
"runtimeId": "67d4ebea82e6e6622171816e1aef53489070aea5b03d5942e8e41c2dc4f49fd3",
Below every taskArn line, there are multiple runtimeId lines specifying the container runtime ids of the containers running under that task.
Hope this helps. Happy scripting.
Related
I am trying to write a bash script to confirm all unconfirmed users in a Cognito User Pool. The documentation here says that I can use cognito:user_status to filter by state. So I wrote this code.
#!/bin/bash
USER_POOL_ID=pool_id
RUN=1
until [ $RUN -eq 0 ] ; do
echo "Listing users"
# Here is the problem after the --filter param. How should I query for the unconfirmed users?
USERS=`aws --profile jaws-lap cognito-idp list-users --user-pool-id ${USER_POOL_ID} --filter 'cognito:user_status="unconfirmed"' | grep Username | awk -F: '{print $2}' | sed -e 's/\"//g' | sed -e 's/,//g'`
if [ ! "x$USERS" = "x" ] ; then
for user in $USERS; do
echo "Confirming user $user"
aws --profile jaws-lap cognito-idp admin-delete-user --user-pool-id ${USER_POOL_ID} --username ${user}
echo "Result code: $?"
echo "Done"
done
else
echo "Done, no more users"
RUN=0
fi
done
The thing is that the --filter is not configured properly. How should I write the statement so I get the unconfirmed users?
Thanks.
This command worked for me:
aws cognito-idp list-users --user-pool-id xxx --filter 'cognito:user_status="CONFIRMED"'
I am trying to get the details from the AWS SSM Parameter store. I have the data stored for which the value in SSM parameter store like this:
CompanyName\credits
Please find the SSM command executed through AWS CLI, the output is as follows:
aws ssm get-parameters --names "/Data/Details"
- Output
{
"Parameters": [
{
"Name": "/Data/Details",
"Type": "String",
"Value": "CompanyName\\Credits",
"Version": 1,
"LastModifiedDate": "2019-08-13T18:16:40.836000+00:00",
"ARN": "arn:aws:ssm:us-west-1:8484848448444:parameter/Data/Details"
}
],
"InvalidParameters": []
} ```
In the above output, I am trying to print only **Credits** in **"Value": "CompanyName\\Credits"**, so I have added more filters to my command as follows:
``` aws ssm get-parameters --names "/Data/Details" |grep -i "Value" |sed -e 's/[",]//g' |awk -F'\\' '{print $2}' ```
The above command gives nothing in the output. But when I am trying to print the first field I am able to see the output as ** Value: CompanyName ** using the following command:
``` aws ssm get-parameters --names "/Data/Details" |grep -i "Value" |sed -e 's/[",]//g' |awk -F'\\' '{print $1}' ```
Since this is Linux machine, the double slash in the field **Value : CompanyName\\Credits ** occurred to escape the '\' character for the actual value CompanyName\Credits. Can someone let me know how can I modify the command to print only the value **Credits** in my output.
Regards,
Karthik
I think this should work:
param_info=$(aws ssm get-parameters \
--names "/Data/Details" \
--query 'Parameters[0].Value' \
--output text)
echo ${param_info} | awk -F'\\' {'print $3'}
# or without awk
echo ${param_info#*\\\\} # for Credit
echo ${param_info%\\\\*} # for CompanyName
This uses query and output parameters to control output from the aws cli. Also bash parameter expansions are used.
I am trying to delete the security groups by running the command
for i in `aws ec2 describe-security-groups --filters Name=vpc-id,Values="${vpcid}" | grep sg- | sed -E 's/^.*(igw-[a-z0-9]+).*$/\1/'`; do aws ec2 delete-security-group --group-id $i; done
It will delete the custom security group successfully. However, return an error when trying to delete a default security group. I don't want the error to be returned on the terminal, and instead just return nothing.
I have tried to add || true at the end of delete-security-group command, which looks like
for i in `aws ec2 describe-security-groups --filters Name=vpc-id,Values="${vpcid}" | grep sg- | sed -E 's/^.*(igw-[a-z0-9]+).*$/\1/'`; do aws ec2 delete-security-group --group-id $i || true; done
while the error is still printed on the terminal. Any helps
using command 2>/dev/null to redirect the error
I'm trying to automate some tagging with Ansible playbooks. One of the things I want to accomplish is tagging a resource with a username of the person who created it. The issue is the sts-assume-role obfuscates the user data of the top-level account.
# cat ~/.aws/credentials
[default]
aws_secret_access_key = gggggggggggggggggggggggggggggggggg
aws_access_key_id = JJJJJJJJJJJJJJJJJJJJ
[childaccount]
role_arn = arn:aws:iam::0123456789:role/child-acct-admin
source_profile = default
# aws iam get-user
{
"User": {
"Arn": "arn:aws:iam::4567891230:user/someuser",
"UserName": "someuser",
"UserId": "CCCCCCCCCCCCCCCCC",
"Path": "/",
"CreateDate": "2018-01-04T15:21:51Z",
"PasswordLastUsed": "2019-01-11T15:24:32Z"
}
}
# aws opsworks --region us-east-1 describe-my-user-profile
{
"UserProfile": {
"IamUserArn": "arn:aws:iam::4567891230:user/someuser",
"Name": "someuser",
"SshUsername": "someuser"
}
}
# export AWS_DEFAULT_PROFILE=childaccount
# aws opsworks --region us-east-1 describe-my-user-profile
{
"UserProfile": {
"SshUsername": "child-acct-admin-botocore-sess",
"Name": "child-acct-admin/botocore-session-123456789",
"IamUserArn": "arn:aws:sts::234567898:assumed-role/child-acct-admin/botocore-session-123456789"
}
}
# aws iam get-user
An error occurred (ValidationError) when calling the GetUser operation: Must specify userName when calling with non-User credentials
I need some command I can execute to give me the top-level account details. The only avenue I can think of is to parse the credentials file and try and use the assumed-role name to map back to the profile loaded, and the parent profile. Then pass the keys directly of the top-level account (in this example, default) to give the actual username. It's a lot more involved than it should be.
I took the long way. This approach assumes that the credentials and child account role are defined in your ~/.aws/credentials file. Written in Ansible.
- name: Query AWS role loaded
shell: aws opsworks --region us-east-1 describe-my-user-profile --query 'UserProfile.Name' | awk -F'["/]' '{print $2}'
register: role_in_use
- name: Discover AWS profile loaded
shell: awk '/\[/{prefix=$0; next} $1{print prefix $0}' ~/.aws/credentials | grep role/{{ role_in_use.stdout }} | awk -F'[][]' '{print $2}'
register: profile_in_use
- name: Find AWS source profile
shell: awk '/\[/{prefix=$0; next} $1{print prefix $0}' ~/.aws/credentials| grep "\[{{ profile_in_use.stdout }}\]source_profile =" | awk '{print $3}'
register: src_profile
- name: Set AWS source user
shell: aws opsworks --region us-east-1 describe-my-user-profile --query 'UserProfile.Name' --profile {{ src_profile.stdout }} | awk -F'["/]' '{print $2}'
register: src_user
From there, you can reference the username ala: {{ src_user.stdout }}
I want to start a task from at Container Instance launch time.So I have followed the this Starting task at instance launch Document which provided the MIME multi-part user data script. I have created a cloud formation template to launch an instance with the MIME multi-part user data script.
EC2 Resource has been created with the Cloud formation template, but I am not able to SSH into that instance and I am not able to System logs from EC2 management console as well.
CloudFormation Template
{
"AWSTemplateFormatVersion" : "2010-09-09",
"Description" :" ECS instance",
"Parameters" : {
},
"Resources" :{
"EC2Instance":{
"Type" : "AWS::EC2::Instance",
"Properties" : {
"SecurityGroupIds":["sg-16021f35"]
"ImageId" : "ami-ec33cc96",
"UserData":{
"Fn::Base64":{
"Fn::Join":[
"\n",
[
{
"Fn::Join":[
"",
[
"Content-Type: multipart/mixed; boundary=",
"==BOUNDARY=="
]
]
},
"MIME-Version: 1.0",
"--==BOUNDARY==",
{
"Fn::Join":[
"",
[
"Content-Type: text/upstart-job; charset=",
"us-ascii"
]
]
},
"#!/bin/bash",
"# Specify the cluster that the container instance should register into",
"echo ECS_CLUSTER=Demo >> /etc/ecs/ecs.config",
"# Install the AWS CLI and the jq JSON parser",
"yum install -y aws-cli jq",
"#upstart-job",
{
"Fn::Join":[
" ",[
"description",
"Amazon EC2 Container Service (start task on instance boot)"
]
]
},
{
"Fn::Join":[
" ",[
"author",
"Amazon Web Services"
]
]
},
"start on started ecs",
"script",
"exec 2>>/var/log/ecs/ecs-start-task.log",
"set -x",
"until curl -s http://localhost:51678/v1/metadata",
"do",
"sleep 1",
"done",
"# Grab the container instance ARN and AWS region from instance metadata",
"instance_arn=$(curl -s http://localhost:51678/v1/metadata | jq -r '. | .ContainerInstanceArn' | awk -F/ '{print $NF}' )",
"cluster=$(curl -s http://localhost:51678/v1/metadata | jq -r '. | .Cluster' | awk -F/ '{print $NF}' )",
"region=$(curl -s http://localhost:51678/v1/metadata | jq -r '. | .ContainerInstanceArn' | awk -F: '{print $4}')",
"# Specify the task definition to run at launch",
"task_definition=ASG-Task",
"# Run the AWS CLI start-task command to start your task on this container instance",
"aws ecs start-task --cluster $cluster --task-definition $task_definition --container-instances $instance_arn --started-by $instance_arn",
"end script",
"--==BOUNDARY==--"
]
]
}
},
"IamInstanceProfile":"ecsInstanceRole",
"InstanceType":"t2.micro",
"SubnetId":"subnet-841103e1"
}
}
},
"Outputs" : {
}
}
MIME multi-part User-Data:
Content-Type: multipart/mixed; boundary="==BOUNDARY=="
MIME-Version: 1.0
--==BOUNDARY==
Content-Type: text/x-shellscript; charset="us-ascii"
#!/bin/bash
# Specify the cluster that the container instance should register into
cluster=your_cluster_name
# Write the cluster configuration variable to the ecs.config file
# (add any other configuration variables here also)
echo ECS_CLUSTER=$cluster >> /etc/ecs/ecs.config
# Install the AWS CLI and the jq JSON parser
yum install -y aws-cli jq
--==BOUNDARY==
Content-Type: text/upstart-job; charset="us-ascii"
#upstart-job
description "Amazon EC2 Container Service (start task on instance boot)"
author "Amazon Web Services"
start on started ecs
script
exec 2>>/var/log/ecs/ecs-start-task.log
set -x
until curl -s http://localhost:51678/v1/metadata
do
sleep 1
done
# Grab the container instance ARN and AWS region from instance metadata
instance_arn=$(curl -s http://localhost:51678/v1/metadata | jq -r '. | .ContainerInstanceArn' | awk -F/ '{print $NF}' )
cluster=$(curl -s http://localhost:51678/v1/metadata | jq -r '. | .Cluster' | awk -F/ '{print $NF}' )
region=$(curl -s http://localhost:51678/v1/metadata | jq -r '. | .ContainerInstanceArn' | awk -F: '{print $4}')
# Specify the task definition to run at launch
task_definition=my_task_def
# Run the AWS CLI start-task command to start your task on this container instance
aws ecs start-task --cluster $cluster --task-definition $task_definition --container-instances $instance_arn --started-by $instance_arn --region $region
end script
--==BOUNDARY==--
you need to specify the key file and security group in your formation template as suggested by jarmod above.