Beanstalk Audit:

Overview:

I recently ran a configuration and security assessment on my company’s AWS beanstalk ecosystem. The process was mostly manual as I worked my way through identifying how to obtain the information I needed for the assessment. If I have to do many more of these, I’ll figure out a way to automate at least some of it.

The assessment was both command line based and via the AWS portal. I used the portal to see what information was available to me, then tried ot figure out a command to obtain it.

While the aws cli commands are easily automated, either through shell scripts or an sdk, the eb commands seem to require intervention. You can’t loop through 14 different environments across 3 different applications, for instance.

The commands below assume aws sso is configured, logged in, and current. References to ${profile} indicate the AWS profile in which the AWS beanstalk ecosystem exists.

Memory map:

As mentioned elsewhere, I recently came across the concept of memory maps and quite like them. They strike me as graphical checklists which fit well with my standard approach to tasks like this.

With that, here’s the memory map I generated for auditing beanstalk applications. Unfortunately, I haven’t figured out how to display them reasonably inline, so download the image or right click to open in a new tab.

Lessons learned:

  • Two switch beanstalk apps/envs, need to blast .elasticbeanstalk/config.yaml and rerun eb init. Haven’t found a way through that yet.

AWS cli commands:

AMIs:

  • Give detailed info on a specific ami:

    aws ec2 describe-images --image-ids ami-017a87410cd29f14e \
    --region $region --profile ${profile}
    
  • Filtering describe images by ‘Corretto’ and the owner id:

    aws ec2 describe-images --filters "Name=name, Values=*corretto*" "Name=owner-id, Values=732788773938" \
      --profile ${profile} --query 'Images[*].[ImageId,CreationDate,Name]' --output text  | \
      sort -k 2
    

Network:

  • Get security group rules. Need the security group ID (${sg}):

    aws ec2 describe-security-groups --profile ${profile} \
      --group-ids ${sg} --region ${region} \
      --query 'SecurityGroups[*].IpPermissions' --output yaml:
    

Beanstalk commands:

  • Creates a table of application info. Descriptions with embedded newline cause issues:

    aws elasticbeanstalk describe-applications --region ${region} \
    --profile ${profile} --output table \
    --query 'Applications[*].[ApplicationName, Description, DateUpdated]'
    
  • Obtain a list of applications, descriptions and when they were last updated. sed command removes embedded newlines in the descriptions:

    aws elasticbeanstalk describe-applications --region ${region} \
      --profile ${profile} \
      --query 'Applications[*].[ApplicationName, Description, DateUpdated]' \
      --output text | sed 's/\n//g' | column -t -s$'\t'
    App1                  Application one description      2024-03-08T14:52:08.312000+00:00
    App2                  Application two description      2023-05-08T09:51:43.550000+00:00
    App3                  Application three description    2023-03-23T17:20:26.009000+00:00
    ...
    AppN                  Application N description        2022-12-08T15:30:30.127000+00:00:
    
  • List applications; can be used as source for other commands:

    aws elasticbeanstalk describe-applications --region ${region} \
    --profile ${profile} --query 'Applications[*].ApplicationName' \
    --output yaml | sed 's/^- //g'
    App1
    App2
    App3
    ...
    AppN:
    
  • Creates a tabular view of an application’s environments:

    aws elasticbeanstalk describe-environments --application ${an}  \
    --region $region --profile ${profile} --query 'Environments[*].{
    Appname:ApplicationName,
    Env: EnvironmentName,
    Health: Health,
    Status: HealthStatus,
    Updated: DateUpdated}' --output table
    
    ----------------------------------------------------------------------------------
    |                             DescribeEnvironments                               |
    +---------+------------+---------+---------+-------------------------------------+
    | Appname |    Env     | Health  | Status  |               Updated               |
    +---------+------------+---------+---------+-------------------------------------+
    |  App1   |  App1-prod |  Green  |  Ok     |  2024-04-24T06:00:47.140000+00:00   |
    |  App1   |  App1-uat  |  Green  |  Ok     |  2024-04-24T06:02:46.480000+00:00   |
    |  App1   |  App1-dev  |  Green  |  Ok     |  2024-04-24T13:50:45.292000+00:00   |
    +---------+------------+---------+---------+-------------------------------------+
    
  • Another tabular view of an application’s environments w/env id:

    aws elasticbeanstalk describe-environments \
    --application-name "${app}" --profile ${profile} \
    --query 'Environments[*].{
    App:ApplicationName,
    Env:EnvironmentName,
    ID:EnvironmentId}' --output table:
    
    ---------------------------------------------------
    |            DescribeEnvironments                 |
    +---------------+----------------+----------------+
    |     App       |     Env        |      ID        |
    +---------------+----------------+----------------+
    |  App2         |  app2-test-v5  |  e-hcjiaputsk  |
    |  App2         |  app2-prod-v5  |  e-iii8i3admr  |
    |  App2         |  app2-demo     |  e-xji2nh2bhv  |
    +---------------+----------------+----------------+
    
  • Inline script to loop through application names then generate the table above for each app:

    aws elasticbeanstalk describe-applications --region ${region} --profile ${profile} \
      --query 'Applications[*].ApplicationName' --output yaml | sed 's/^- //g' | \
      while read an
      do
        aws elasticbeanstalk describe-environments --application "${an}"  --region $r \
          --profile ${profile} --query 'Environments[*].{
              Appname:ApplicationName,
              Env: EnvironmentName,
              Status: HealthStatus,
              Updated: DateUpdated,
              StackName: SolutionStackName}' --output table
      done
    
  • List available stacks. Compare/contrast against what’s running:

    aws elasticbeanstalk list-available-solution-stacks --profile ${profile}
    
  • Displays app/env configuraiton settings. Useful for checking sslpolicy and SSLCertificateArns for environment ssl info:

    aws elasticbeanstalk describe-configuration-settings \
      --application-name your-app-name --environment-name your-env-name
    
  • ID instance IDs associated with specific env:

    aws elasticbeanstalk describe-instances-health \
      --environment-name App3-prod --profile ${profile} --query 'InstanceHealthList[*].InstanceId' --output yaml
    
  • Retrieve all instance ids using a data file as a source. Columns separated by ‘|’ and the first column is enviornment name:

    for e in $(awk -F\| '{print $1}' envs)
    do
    id=$(aws elasticbeanstalk describe-instances-health --environment-name ${e} \
      --profile ${profile} --query 'InstanceHealthList[*].InstanceId' --output yaml | \
      sed 's/^- //g')
    printf "%-25s %s\n" ${e} ${id}
    done
    
  • Reads environment name and instance ID from a ‘|’ separated source file, obtains token requirement and if IMDv2 is enabled:

    awk -F\| '{print $1, $3}' envs | while read env id
    do
    read token epoint <<< $( aws ec2 describe-instances --instance-ids ${id} \
      --profile ${profile} \
      --query 'Reservations[*].Instances[*].MetadataOptions.[HttpTokens,HttpEndpoint]' \
      --output text)
    printf "%-25s %s %-10s %s\n" ${env} ${id} ${token} ${epoint}
    done
    app1-dev-env-1            i-07b53e9c7f8504aff required   enabled
    app1-prod                 i-0ae4e5725092961a7 required   enabled
    app1-uat-env-1            i-0f54e229b0efb1a38 required   enabled
    app2-demo-1               i-02c9d48fcc9f885c4 optional   enabled
    app2-prod                 i-0501d814272e35fdf optional   enabled
    app3-demo                 i-01afdf58466f50548 required   enabled
    app3-dev                  i-0dd44322dfd28c90d optional   enabled
    app3-prod                 i-011477e04f2931cea required   enabled
    

eb commands:

eb init::

Selects application and enviornment. Creates .elasticbeanstalk/config.yaml which is then used by other eb commands.

eb config::

Prints out a long yaml dump of information about the environment.

eb printenv::

Prints out the environment configuration pararameters. These are set as env vars in the instance(s)

eb tags:

Lists the tags that are defined for the environment