Teaching vacancies - AWS credentials, MFA, and role profiles
When onboarded, you will be provided with an AWS user. You can use it to access the AWS console at: https://teaching-vacancies.signin.aws.amazon.com/console.
- Log in to the console, go to IAM and find your user: IAM users.
- Choose
Assign MFA device
and set up an authenticator app as a Virtual MFA device. Note: You may need to name the MFA device the same as your username. - If using an Authenticator App, scan the QR code, and when prompted to enter codes, enter the first code, wait 30 seconds until a new code has been generated on your authenticator app, and enter the new code in the second box.
- Log out, and back in. You should be prompted for an MFA code.
- Go to IAM and find your user again: IAM users
- Choose
Create access key
. Note the credentials securely, as you will need these to configure the AWS CLI.
Assuming a role in the console
- When you log in to AWS you will have permissions to
- Change your password
- Set up an MFA device
- Generate Access Keys To carry out more privileged operations, you will need to switch to a role
- Choose your user name on the navigation bar in the upper right. It typically looks like this: @teaching-vacancies.
- Choose
Switch Roles
. - For Account, enter
530003481352
- For Role, enter
ReadOnly
- For Display Name, this will be greyed out as
ReadOnly @ 530003481352
- Pick a colour for the role display and click
Switch Role
- Choose
Switch Roles
again - For Account, enter
530003481352
- For Role, enter
SecretEditor
- For Display Name, this will be greyed out as
SecretEditor @ 530003481352
- These two roles should now be listed in your Role History
Roles
-
Administrator
can:- administer the AWS account, and all resources, including user and group management
-
BillingManager
can:- access invoices and other billing information
- read all resources
-
Deployments
can:- deploy apps and resources
-
ReadOnly
can:- read all resources
-
SecretEditor
can:- read and update existing secrets within Parameter Store
Tool installation
Install:
macOS
brew install awscli
brew install --cask aws-vault
Ubuntu WSL2
The setup on Ubuntu is more involved, as we use GPG and pass
for a secure vault backend
Install AWS CLI v2
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip -q awscliv2.zip -d /tmp
sudo /tmp/aws/install
Install AWS Vault
wget https://github.com/99designs/aws-vault/releases/download/v6.2.0/aws-vault-linux-amd64
sudo mv ./aws-vault-linux-amd64 /usr/local/bin/aws-vault
sudo chmod +x /usr/local/bin/aws-vault
Install GPG and Pass
sudo apt-get install -y gnupg pass
There's an excellent guide to managing password with GPG, the command line and Pass but the essentials are:
Generate GPG Key
gpg --full-generate-key
Answer the interactive questions. I chose
Please select what kind of key you want:
(1) RSA and RSA (default)
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (3072)
3072
Please specify how long the key should be valid.
0 = key does not expire
<n> = key expires in n days
<n>w = key expires in n weeks
<n>m = key expires in n months
<n>y = key expires in n years
Key is valid for? (0)
2y
You are then prompted for some personal details
GnuPG needs to construct a user ID to identify your key.
Real name: <YOUR-NAME>
Email address: <YOUR-NAME>@digital.education.gov.uk
Comment: Work
You selected this USER-ID:
"<YOUR-NAME> (Work) <<YOUR-NAME>@digital.education.gov.uk>"
You are then prompted for a passphrase to protect the GPG key. I used my Windows password manager to generate and store the passphrase
After moving the mouse to generate random bytes for prime generation, we see:
gpg: key 8C6B1A2FA5910DE0 marked as ultimately trusted
gpg: revocation certificate stored as '/home/nrubuntu/.gnupg/openpgp-revocs.d/A5896473017A0DD9B983A03D8C6B1A2FA5910DE0.rev'
public and secret key created and signed.
pub rsa3072 2021-02-11 [SC] [expires: 2023-02-11]
A5896473017A0DD9B983A03D8C6B1A2FA5910DE0
uid <YOUR-NAME> (Work) <<YOUR-NAME>@digital.education.gov.uk>
sub rsa3072 2021-02-11 [E] [expires: 2023-02-11]
Typing gpg --list-keys
will repeat the output of pub
, uid
, and sub
Secure password-store with GPG key
pass init <GPG-PUB-ID from step above>
Append to ~/.bashrc
or ~/.zshrc
export AWS_VAULT_PASS_PREFIX=aws-vault
export AWS_VAULT_BACKEND=pass
Configure AWS CLI with AWS Vault profiles
Edit or create the ~/.aws/config
file, and paste this in, replacing <YOUR-AWS-USERNAME>
in the three places it appears:
[profile teaching-vacancies]
mfa_serial=arn:aws:iam::530003481352:mfa/<YOUR-AWS-USERNAME>
region=eu-west-2
[profile ReadOnly]
mfa_serial=arn:aws:iam::530003481352:mfa/<YOUR-AWS-USERNAME>
region=eu-west-2
role_arn=arn:aws:iam::530003481352:role/ReadOnly
source_profile=teaching-vacancies
[profile SecretEditor]
mfa_serial=arn:aws:iam::530003481352:mfa/<YOUR-AWS-USERNAME>
region=eu-west-2
role_arn=arn:aws:iam::530003481352:role/SecretEditor
source_profile=teaching-vacancies
If needed, two other profiles can also be included for the Deployments and Administrator roles.
[profile Deployments]
mfa_serial=arn:aws:iam::530003481352:mfa/<YOUR-AWS-USERNAME>
region=eu-west-2
role_arn=arn:aws:iam::530003481352:role/Deployments
source_profile=teaching-vacancies
[profile Administrator]
mfa_serial=arn:aws:iam::530003481352:mfa/<YOUR-AWS-USERNAME>
region=eu-west-2
role_arn=arn:aws:iam::530003481352:role/Administrator
source_profile=teaching-vacancies
Then use AWS Vault to set the credentials:
aws-vault add teaching-vacancies
You'll be prompted to enter ID of an Access Key you created here, and the key itself, which you saw when you created it:
Enter Access Key ID:
Enter Secret Access Key:
Then you will see:
Added credentials to profile "teaching-vacancies" in vault
Log in to the AWS Console with AWS Vault
Log in and switch to the ReadOnly
role:
aws-vault login ReadOnly
You should be prompted for an MFA code:
Enter token for arn:aws:iam::530003481352:mfa/<YOUR-AWS-USERNAME>:
You should see a link with a very long SigninToken
https://signin.aws.amazon.com/federation?Action=login&Issuer=aws-vault&Destination=https%3A%2F%2Fconsole.aws.amazon.com%2F&SigninToken=CfTUyKvXf1Xq3qjTRUNCATED
Work with the AWS CLI on the command line
Refresh the .env
file
aws-vault exec ReadOnly -- make -s local print-env > .env
List the S3 buckets
aws-vault exec ReadOnly -- aws s3 ls
Rotate AWS credentials for AWS Vault
Rotate your AWS access keys at least every 90 days with this command:
aws-vault rotate teaching-vacancies
Use the AWS CLI without AWS Vault
In this example you will use your personal Access Key and Secret key in the [teaching-vacancies]
profile
If for any reason you had issues with the AWS Vault tool, you could use the AWS CLI directly by:
aws configure --profile teaching-vacancies
You'll be prompted:
AWS Access Key ID [None]: AKIA
AWS Secret Access Key [None]: GXdB
Default region name [eu-west-2]:
Default output format [None]:
And then running e.g.
aws s3 ls --profile ReadOnly
Assuming an AWS role without AWS Vault
In this example you will use your personal Access Key and Secret key in the [default]
profile, and are able to use third-party tools which do not understand the AWS --profile
option, such as Terraform.
aws configure
You'll be prompted:
AWS Access Key ID [None]: AKIA
AWS Secret Access Key [None]: GXdB
Default region name [eu-west-2]:
Default output format [None]:
There is a useful Gruntwork blog
Generate an MFA token in your Authenticator App, then use it in this command
aws sts get-session-token --serial-number arn:aws:iam::530003481352:mfa/<YOUR-AWS-USERNAME> --token-code <MFA-token>
aws sts assume-role \
--role-arn arn:aws:iam::530003481352:role/ReadOnly \
--role-session-name <YOUR-AWS-USERNAME> \
--serial-number arn:aws:iam::530003481352:mfa/<YOUR-AWS-USERNAME> \
--token-code <MFA-token>
You will see temporary session credentials, which have a duration of one hour
{
"Credentials": {
"AccessKeyId": "AKIAIOSFODNN7EXAMPLE",
"SecretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYzEXAMPLEKEY",
"SessionToken": "AQoEXAMPLEH4aoAH0gNCAPyJxz4BlCFFxWNE1OPTgk5TthT+FvwqnKwRcOIfrRh3c/LTo6UDdyJwOOvEVPvLXCrrrUtdnniCEXAMPLE/IvU1dYUg2RVAJBanLiHb4IgRmpRV3zrkuWJOgQs8IZZaIv2BXIa2R4OlgkBN9bkUDNCJiBeb/AXlzBBko7b15fjrBs2+cTQtpZ3CYWFXG8C5zqx37wnOE49mRl/+OtkIKGO7fAE",
"Expiration": "2021-03-16T19:23:20+00:00"
},
"AssumedRoleUser": {
"AssumedRoleId": "AROAXWZVLKMEK2POASFO6:<YOUR-AWS-USERNAME>",
"Arn": "arn:aws:sts::530003481352:assumed-role/ReadOnly/<YOUR-AWS-USERNAME>"
}
}
Using the examples above, set these as environment variables:
export AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
export AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYzEXAMPLEKEY
export AWS_SESSION_TOKEN=AQoEXAMPLEH4aoAH0gNCAPyJxz4BlCFFxWNE1OPTgk5TthT+FvwqnKwRcOIfrRh3c/LTo6UDdyJwOOvEVPvLXCrrrUtdnniCEXAMPLE/IvU1dYUg2RVAJBanLiHb4IgRmpRV3zrkuWJOgQs8IZZaIv2BXIa2R4OlgkBN9bkUDNCJiBeb/AXlzBBko7b15fjrBs2+cTQtpZ3CYWFXG8C5zqx37wnOE49mRl/+OtkIKGO7fAE
It may be easier to copy and paste without the examples, like so:
export AWS_ACCESS_KEY_ID=
export AWS_SECRET_ACCESS_KEY=
export AWS_SESSION_TOKEN=
If you need to renew your session, you'll need to first unset the environment variables (starting a new terminal will usually have the same effect)
If generating these sessions is a regular activity, then you may find this snippet helpful. It uses jq
to extract the three values, before setting them as environment variables:
sessionInfo="$(aws sts assume-role --role-arn arn:aws:iam::530003481352:role/ReadOnly --role-session-name <YOUR-AWS-USERNAME> --serial-number arn:aws:iam::530003481352:mfa/<YOUR-AWS-USERNAME> --token-code 123456)"
export AWS_ACCESS_KEY_ID="$(echo $sessionInfo | jq '.Credentials.AccessKeyId' | tr -d '"')"
export AWS_SECRET_ACCESS_KEY="$(echo $sessionInfo | jq '.Credentials.SecretAccessKey' | tr -d '"')"
export AWS_SESSION_TOKEN="$(echo $sessionInfo | jq '.Credentials.SessionToken' | tr -d '"')"
Rotating deploy
user access key
The deploy
user is an AWS account and it is used to run the CI/CD. Both its access key
and access_key_id
are stored on Github Secrets (AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY). For security reasons, the access key needs to be rotated occasionally e.g. every 3 months
The deploy
user and its access key ( aws_iam_access_key
) are deployed via the common
terraform module. Please note, these resources are not deployed via the CI\CD pipeline.
To rotate the key, please do the following:-
- [] From the root of the project, change directory -
cd terraform/common/
- []
aws-vault exec Administrator -- terraform apply -replace aws_iam_access_key.deploy
- []
aws-vault exec Administrator -- terraform output -json
- note the newly generated ACCESS_KEY_ID and ACCESS_KEY. - [] Copy the newly generated ACCESS_KEY_ID and ACCESS_KEY to Github secrets - AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY.
- [] Test by running/triggering a deploy workflow or run a workflow_dispatch action