How to stop xargs command if the input is empty - amazon-web-services

My GitLab-ci.yml file consists of the below stage-
.deploy_cloudformation_template:
extends: .deployment_job_template
when: on_success
script:
# Deploy the template.
aws cloudformation deploy --profile $AWS_PROFILE --region us-east-1
--stack-name "pa-pa-${ENVIRONMENT_NAME}"
--template-file ./cfn/stack-template.yml
--capabilities CAPABILITY_IAM
--no-fail-on-empty-changeset
--parameter-overrides $(cat ./cfn/params-${ENVIRONMENT_NAME}.ini | tr "\n" " ")
# Delete any failed changesets in the stack, which are created when there's no change in the template.
aws cloudformation list-change-sets --profile $AWS_PROFILE --region us-east-1
--stack-name "pa-pa-${ENVIRONMENT_NAME}"
--query Summaries[][ChangeSetName,Status]
--output text | grep FAILED | awk '{print $1}' | xargs -I {} aws cloudformation delete-change-set
--profile $AWS_PROFILE --region us-east-1
--change-set-name {} --stack-name "pa-zappa-${ENVIRONMENT_NAME}"
If there are no failed changeset then the xargs should not run anything. I tried -r, --no-run-if-empty but that is not supported.
Anything else that i can use to achieve this?

Related

aws cloudformation describe-stacks --query

I am trying to write a query for a specific stack. It looks like this:
$ aws cloudformation describe-stacks --region $AWS_REGION --profile $AWS_PROFILE --stack-name MyStack --query 'Stacks[?StackName == "MyStack"]'
[]
As you can see the output is an empty array. On the other hand:
$ aws cloudformation describe-stacks --region $AWS_REGION --profile $AWS_PROFILE --stack-name MyStack --query 'Stacks[0]'
{
// the output
}
What am I missing in my query version? How do I fix it?
Enclose the value in backquotes:
--query 'Stacks[?StackName == `MyStack`]'
Filtering AWS CLI output - AWS Command Line Interface

I'm getting "command not found" error after running these commands in GitLab. I used these commands 2 days ago and they worked fine

I was using these commands for my deploy-job the other day and it worked fine. This is a new pipeline for a new project and now these commands aren't working. I'm getting errors in my pipeline after every command saying "command not found". Here's my gitlab-ci file for reference
variables:
DOCKER_REGISTRY: 775362094965.dkr.ecr.us-west-2.amazonaws.com
AWS_DEFAULT_REGION: us-west-2
APP_NAME: flask-app
DOCKER_HOST: tcp://docker:2375
stages:
- build
- deploy
build-job:
stage: build
image:
name: amazon/aws-cli
entrypoint: [""]
services:
- docker:dind
before_script:
- amazon-linux-extras install docker
- aws --version
- docker --version
script:
- docker build -t $DOCKER_REGISTRY/$APP_NAME:latest .
- aws ecr get-login-password | docker login --username AWS --password-stdin $DOCKER_REGISTRY
- docker push $DOCKER_REGISTRY/$APP_NAME:latest
deploy-job:
stage: deploy
script:
- echo `aws ecs describe-task-definition --task-definition $CI_AWS_ECS_TASK_DEFINITION --region us-west-2` > input.json
- echo $(cat input.json | jq '.taskDefinition.containerDefinitions[].image="'$REPOSITORY_URI':'$IMAGE_TAG'"') > input.json
- echo $(cat input.json | jq '.taskDefinition') > input.json
- echo $(cat input.json | jq 'del(.taskDefinitionArn)' | jq 'del(.revision)' | jq 'del(.status)' | jq 'del(.requiresAttributes)' | jq 'del(.compatibilities)' | jq 'del(.registeredAt)' | jq 'del(.registeredBy)') > input.json
- aws ecs register-task-definition --cli-input-json file://input.json --region us-west-2
- revision=$(aws ecs describe-task-definition --task-definition $CI_AWS_ECS_TASK_DEFINITION --region us-west-2 | egrep "revision" | tr "/" " " | awk '{print $2}' | sed 's/"$//' | cut -d "," -f 1)
- aws ecs update-service --cluster $CI_AWS_ECS_CLUSTER --service $CI_AWS_ECS_SERVICE --task-definition $CI_AWS_ECS_TASK_DEFINITION:$revision --region us-west-2
My build-job works fine, I'm just getting "command not found" with my deploy-job.
You need to specify an image outside of the build job or in the deploy job. Right now, you're only specifying an image inside your build-job.

Why the environment variable is not working with Docker run command used in Jenkins pipeline

Below is my Deployment stage pipeline code.
stage('Deploy') {
if (continueBuild) {
println("Start Deployment");
//Deploy step for liberty-web
if ("${repo_name}" == 'enterprise-content-management/liberty-web') {
if ("${deploy_env}" == "DEV") {
def REACT_APP_CONFIGS = sh(script: "aws ssm get-parameter --region us-east-1 --name \"/liberty/config/liberty-web_dev/app.config\" | jq -r '.Parameter.Value'", returnStdout: true).trim().replaceAll('\n', '').replaceAll('\"', '\\\\"');
def APP_SPECIFIC_CONFIG = sh(script: "aws ssm get-parameter --region us-east-1 --name \"/liberty/config/liberty-web_dev/app.appSpecificConfig\" | jq -r '.Parameter.Value'", returnStdout: true).trim().replaceAll('\n', '').replaceAll('\"', '\\\\"');
print REACT_APP_CONFIGS
print APP_SPECIFIC_CONFIG
def CLOUDFRONT_DISTRIBUTION_ID = sh(script: "aws ssm get-parameter --region us-east-1 --name \"/liberty/config/liberty-web_dev/cloudfront.distribution.id\" | jq -r '.Parameter.Value'", returnStdout: true).trim()
print CLOUDFRONT_DISTRIBUTION_ID
def DEPLOYMENT_BUCKET = sh(script: "aws ssm get-parameter --region us-east-1 --name \"/liberty/config/liberty-web_dev/s3.bucket.name\" | jq -r '.Parameter.Value'", returnStdout: true).trim()
print DEPLOYMENT_BUCKET
writeFile file: 'build-web-dev.sh', text: "#!/usr/bin/env bash \n docker run --rm --env REACT_APP_CONFIGS=\"${REACT_APP_CONFIGS}\" --env APP_SPECIFIC_CONFIG=\"${APP_SPECIFIC_CONFIG}\" --name liberty-web -v /data/jenkins/workspace/liberty-web-deployment:/Project -w /Project node:12-alpine npm run build"
sh 'cat build-web-dev.sh'
sh 'bash build-web-dev.sh'
sh "aws cloudfront create-invalidation --distribution-id ${CLOUDFRONT_DISTRIBUTION_ID} --paths \"/*\" && aws s3 sync build/ s3://${DEPLOYMENT_BUCKET}"
}
}
}
}
This is a node app. When i try to access below 2 env variables mentioned(REACT_APP_CONFIGS, APP_SPECIFIC_CONFIG) only REACT_APP_CONFIGS works. These values of the params are stored in SSM in AWS. I tried by putting the same value for both variables. But still the same. Ex;-
In my node app
console.log(process.env.REACT_APP_CONFIGS) -> gives correct value
console.log(process.env.APP_SPECIFIC_CONFIG) -> undefined
What is the reason for this behaviour?

Given a role ARN, how do you find out which stack and region created the role?

Can anyone please provide CLI command to get the stack name and region that created a particular IAM role?
you will have to write a small looping script that goes through all the region and all the stack (with let's say 'CREATE_COMPLETE' status) and use the describe-stack-resources CLI command.
https://docs.aws.amazon.com/cli/latest/reference/cloudformation/describe-stack-resources.html
Here is a small example:
#!/bin/bash
for region in us-east-2 us-east-1 us-west-1 us-west-2 ap-east-1 ap-south-1 ap-northeast-3 ap-northeast-2 ap-southeast-1 ap-southeast-2 ap-northeast-1 ca-central-1 cn-north-1 cn-northwest-1 eu-central-1 eu-west-1 eu-west-2 eu-west-3 eu-north-1 me-south-1 sa-east-1
do
echo "Processing region $region ..."
for stack in $(aws cloudformation list-stacks --stack-status-filter CREATE_COMPLETE --output json --region $region | jq '.StackSummaries[] | .StackId' | sed -e 's/^"//' -e 's/"$//')
do
echo "Processing stack $stack ..."
aws cloudformation describe-stack-resources --stack-name $stack --output json --region $region | jq '.StackResources[] | select(.ResourceType=="AWS::IAM::Role") | select(.PhysicalResourceId=="PUT_YOUR_ROLE_NAME_HERE")'
done
done
Don't forget that if you have your role ARN you can easily get your account number and you role name. The format being
arn:aws:iam::account-id:role/role-name
I hope that helps, sorry about the oneliner, it's less readable.
aws cloudformation describe-stacks --stack-name myteststack

How to save output of AWS CLI in a variable?

I want to save output of an AWS CLI in a variable and use that variable in another AWS CLI, what I did is as follows:
taskarn= aws ecs list-tasks --cluster mycluster --service-name "myService" --region "eu-west-1" --output text | grep "arn" | tr -d '"'
echo $taskarn; //empty
aws ecs stop-task --cluster mycluster --task $taskarn --region "eu-west-1"
when I echo $taskarn, it is empty.
Any help would be appreciated.
I used the following command and it works fine:
taskarn=$(aws ecs list-tasks --cluster mycluster --service-name "myservice" --region "eu-west-1" | grep "arn" | tr -d '"')
echo $taskarn;
aws ecs stop-task --cluster mycluster --task $taskarn --region "eu-west-1"
Use backquote to execute the command and assign the result to the variable.
taskarn=`aws ecs list-tasks --cluster mycluster --service-name "myService" --region "eu-west-1" --output text | grep "arn" | tr -d '"'`
But the correct way is to use the --query option of the CLI to extract what you want.