Package: aardvark
AardvarkAardvark is a multi-account AWS IAM Access Advisor API (and caching layer).Install:Ensure that you have Python 3.6 or later. Python 2 is no longer supported.gitclonehttps://github.com/Netflix-Skunkworks/aardvark.gitcdaardvark
python3-mvenvenv
.env/bin/activate
pythonsetup.pydevelopKnown Dependencieslibpq-devConfigure AardvarkThe Aardvark config wizard will guide you through the setup.% aardvark config

Aardvark can use SWAG to look up accounts. https://github.com/Netflix-Skunkworks/swag-client
Do you use SWAG to track accounts? [yN]: no
ROLENAME: Aardvark
DATABASE [sqlite:////home/github/aardvark/aardvark.db]:
# Threads [5]:

>> Writing to config.pyWhether to useSWAGto enumerate your AWS accounts. (Optional, but useful when you have many accounts.)The name of the IAM Role to assume into in each account.The Database connection string. (Defaults to sqlite in the current working directory. Use RDS Postgres for production.)Create the DB tablesaardvark create_dbIAM Permissions:Aardvark needs an IAM Role in each account that will be queried.  Additionally, Aardvark needs to be launched with a role or user which cansts:AssumeRoleinto the different account roles.AardvarkInstanceProfile:Only create one.Needs the ability to callsts:AssumeRoleinto all of the AardvarkRole'sAardvarkRole:Must exist in every account to be monitored.Must have a trust policy allowingAardvarkInstanceProfile.Has these permissions:iam:GenerateServiceLastAccessedDetails
iam:GetServiceLastAccessedDetails
iam:listrolepolicies
iam:listroles
iam:ListUsers
iam:ListPolicies
iam:ListGroupsSo if you are monitoringnaccounts, you will always needn+1roles. (nAardvarkRoles and1AardvarkInstanceProfile).Note: For locally running aardvark, you don't have to take care of the AardvarkInstanceProfile. Instead, just attach a policy which contains "sts:AssumeRole" to the user you are using on the AWS CLI to assume Aardvark Role. Also, the same user should be mentioned in the trust policy of Aardvark Role for proper assignment of the privileges.Gather Access Advisor DataYou'll likely want to refresh the Access Advisor data regularly.  We recommend running theupdatecommand about once a day.  Cron works great for this.Without SWAG:If you don't have SWAG you can pass comma separated account numbers:aardvark update -a 123456789012,210987654321With SWAG:Aardvark can useSWAGto look up accounts, so you can run against all with:aardvark updateor by account name/tag with:aardvark update -a dev,test,prodAPIStart the APIaardvark start_api -b 0.0.0.0:5000In production, you'll likely want to have something like supervisor starting the API for you.Use the APISwagger is available for the API at<Aardvark_Host>/apidocs/#!.Aardvark responds to get/post requests. All results are paginated and pagination can be controlled by passingcountand/orpagearguments. Here are a few example queries:curllocalhost:5000/api/1/advisors
curllocalhost:5000/api/1/advisors?phrase=SecurityMonkey
curllocalhost:5000/api/1/advisors?arn=arn:aws:iam::000000000000:role/SecurityMonkey&arn=arn:aws:iam::111111111111:role/SecurityMonkey
curllocalhost:5000/api/1/advisors?regex=^.*Monkey$DockerAardvark can also be deployed with Docker and Docker Compose. The Aardvark services are built on a shared container. You will need Docker and Docker Compose installed for this to work.To configure the containers for your set of accounts create a.envfile in the root of this directory. Define the environment variables within this file. This example uses AWS Access Keys. We recommend using instance roles in production.AARDVARK_ROLE=Aardvark
AARDVARK_ACCOUNTS=<account id>
AWS_DEFAULT_REGION=<aws region>
AWS_ACCESS_KEY_ID=<your access key>
AWS_SECRET_ACCESS_KEY=<you secret key>NameServiceDescriptionAARDVARK_ROLEcollectorThe name of the role for Aardvark to assume so that it can collect the data.AARDVARK_ACCOUNTScollectorOptional if using SWAG, otherwise required. Set this to a list of SWAG account name tags or a list of AWS account numbers from which to collect Access Advisor records.AWS_ARN_PARTITIONcollectorRequired if not using an AWS Commercial region. For example,aws-us-gov. By default, this isaws.AWS_DEFAULT_REGIONcollectorRequired if not running on an EC2 instance with an appropriate Instance Profile. Set these to the credentials of an AWS IAM user with permission tosts:AssumeRoleto the Aardvark audit role.AWS_ACCESS_KEY_IDcollectorRequired if not running on an EC2 instance with an appropriate Instance Profile. Set these to the credentials of an AWS IAM user with permission tosts:AssumeRoleto the Aardvark audit role.AWS_SECRET_ACCESS_KEYcollectorRequired if not running on an EC2 instance with an appropriate Instance Profile. Set these to the credentials of an AWS IAM user with permission tosts:AssumeRoleto the Aardvark audit role.AARDVARK_DATABASE_URIcollectorandapiserverSpecify a custom database URI supported by SQL Alchemy. By default, this will use theAARDVARK_DATA_DIRvalue to create a SQLLite Database. Example:sqlite:///$AARDVARK_DATA_DIR/aardvark.dbOnce this file is created, then build the containers and start the services. Aardvark consists of three services:Init - The init container creates the database within the storage volume.API Server - This is the HTTP webserver will serve the data. By default, this is listening onhttp://localhost:5000/apidocs/#!.Collector - This is a daemon that will fetch and cache the data in the local SQL database. This should be run periodically.# build the containersdocker-composebuild# start up the containersdocker-composeupFinally, to clean up the environment# bring down the containersdocker-composedown# remove the containersdocker-compoesrmNotesThreadsAardvark will launch the number of threads specified in the configuration.  Each of these threads
will retrieve Access Advisor data for an account and then persist the
data.DatabaseTheregexquery is only supported in Postgres (natively) and SQLite (via some magic courtesy of Xion
in thesqla_regexfile).TLSWe recommend enabling TLS for any service. Instructions for setting up TLS are out of scope for this document.SignalsNew in v0.3.1Aardvark usesBlinkerfor signals in its update process. These signals can be used
for things like emitting metrics, additional logging, or taking more actions on accounts. You can use them by writing a
script that defines your handlers and callsaardvark.manage.main(). For example, create a file calledsignals_example.pywith the following contents:importloggingfromaardvark.manageimportmainfromaardvark.updaterimportAccountToUpdatelogger=logging.getLogger('aardvark_signals')@AccountToUpdate.on_ready.connectdefhandle_on_ready(sender):logger.info(f"got on_ready from{sender}")@AccountToUpdate.on_complete.connectdefhandle_on_complete(sender):logger.info(f"got on_complete from{sender}")if__name__=="__main__":main()This file can now be invoked in the same way asmanage.py:pythonsignals_example.pyupdate-acool_accountThe log output will be similar to the following:INFO: getting bucket swag-bucket
INFO: Thread #1 updating account 123456789012 with all arns
INFO: got on_ready from <aardvark.updater.AccountToUpdate object at 0x10c379b50>
INFO: got on_complete from <aardvark.updater.AccountToUpdate object at 0x10c379b50>
INFO: Thread #1 persisting data for account 123456789012
INFO: Thread #1 FINISHED persisting data for account 123456789012Available signalsClassSignalsmanage.UpdateAccountThreadon_ready,on_complete,on_failureupdater.AccountToUpdateon_ready,on_complete,on_error,on_failureTODO:SeeTODO