Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add deployer command exec-aws-shell and update AWS access docs to include info about MFA access for CLI #2998

Merged
merged 4 commits into from
Aug 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions deployer/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# registered into the app
import deployer.billing.app # noqa: F401
import deployer.cilogon_app # noqa: F401
import deployer.cloud_access # noqa: F401
import deployer.debug # noqa: F401
import deployer.deployer # noqa: F401
import deployer.generate.generate_aws_cluster # noqa: F401
Expand Down
52 changes: 52 additions & 0 deletions deployer/cloud_access.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
"""
Helper methods for commandline access to cloud providers.

Google Cloud's `gcloud` is more user friendly than AWS's `aws`,
so we have some augmented methods here primarily for AWS use.
"""
import json
import os
import subprocess

import typer

from .cli_app import app


@app.command()
def exec_aws_shell(
profile: str = typer.Argument(..., help="Name of AWS profile to operate on"),
mfa_device_id: str = typer.Argument(
..., help="Full ARN of MFA Device the code is from"
),
auth_token: int = typer.Argument(
..., help="6 digit 2 factor authentication code from the MFA device"
),
):
"""
Exec into a shall with appropriate AWS credentials (including MFA)
"""
creds = json.loads(
subprocess.check_output(
[
"aws",
"sts",
"get-session-token",
"--serial-number",
mfa_device_id,
"--token-code",
str(auth_token),
"--profile",
profile,
]
).decode()
)

env = os.environ | {
"AWS_ACCESS_KEY_ID": creds["Credentials"]["AccessKeyId"],
"AWS_SECRET_ACCESS_KEY": creds["Credentials"]["SecretAccessKey"],
"AWS_SESSION_TOKEN": creds["Credentials"]["SessionToken"],
"AWS_PROFILE": profile,
}

subprocess.check_call([os.environ["SHELL"], "-l"], env=env)
33 changes: 33 additions & 0 deletions docs/topic/access-creds/cloud-auth.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ AWS Organizations
AWS Management Account
: A special account that is a centralized place for configuration for an AWS Organization and other accounts that might be in it. Our AWS Management account is `2i2c-sandbox`. It defines our **payment methods** for centralized payment across all of our accounts. So each of our AWS Accounts generates a bill, and these are consolidated into `2i2c-sandbox` and payed with a single credit card.


(cloud-access:aws-sso)=
### Access with Single Sign-On (SSO)

Expand Down Expand Up @@ -110,6 +111,7 @@ To do so, follow these steps:
AWS accounts we create.
4. Create the account! They'll receive an email with appropriate instructions.

(cloud-access:aws-individual-accnts)=
### Access individual AWS accounts

For AWS accounts that are managed by clients, we use an individual AWS account for each team member, and ask the client to provide us access for each person.
Expand Down Expand Up @@ -155,4 +157,35 @@ are used to provide access to the AWS account from your terminal.
This helps manage multiple sets of credentials easily. You can validate this works by running
`aws sts get-caller-identity`.

4. For accounts that enforce mandatory Multi-Factor Authentication, we will also
need to get a temporary set of credentials fetched by providing a 6 digit
token from your MFA device. The documentation to do this is here: <https://repost.aws/knowledge-center/authenticate-mfa-cli>.

The two parameters required to login are:

- `arn-of-the-mfa-device` can be found by visiting the 'Security Credentials' page when you're logged into the web console, after
- `code-from-token` is a 6 digit integer code generated by your MFA device

Alternatively, the deployer has a convenience command - `exec-aws-shell`
to simplify this, purely implementing the suggestions from
[the AWS docs](https://repost.aws/knowledge-center/authenticate-mfa-cli).
You can execute it like so:

```bash
$ deployer exec-aws-shell <your-cluster-hname> <arn-of-mfa-device> <code-from-token>
```

This will open a new subshell with all the appropriate AWS environment
variables setup to perform actions with `terraform`, `eksctl`, etc. Note
this requires that you have an aws profile set up under `~/.aws/credentials`
with the profile name matching the name of the cluster (step 3 above).

Regardless of method used, the commandline authentication with MFA will
expire in 12 hours, and you will need to re-authenticate.

```{note}
Currently, the only accounts that enforce MFA are some [individual accounts](cloud-access:aws-individual-accnts) not under 2i2c's organisation SSO.
Though in the future, we may enforce MFA for our orgnisation as well.
```

% TODO: Add instructions for Azure as well.