Skip to content

Commit 3bae3af

Browse files
authored
Update README to include information on connecting to rails console via aws ecs execute-command (#55)
* Update README to include information on connecting to rails console via aws ecs execute-command * Add shell script for ssh-ing into staging/prod * Clean up * Update README describing the best way to access dev console on staging/prod * Fix typos * Clean up * Update brakeman * Changes based on PR review
1 parent 633fef1 commit 3bae3af

2 files changed

Lines changed: 177 additions & 2 deletions

File tree

README.md

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,68 @@ Locally, you can use `bin/rails console`
7979

8080
On Heroku, you can use `heroku run rails c -a <review-app-name>`
8181

82-
On Staging and Production, you'll have to utilize AWS Query Editor or `aws rds-data` commands to access the database.
82+
On Staging and Production, use the `aws ecs execute-command`. You must have `awscli` isntalled on your machine already (check with `aws --version`).
83+
If not, `brew install awscli` on your local machine ([AWS instructions here](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)).
84+
Please download the [AWS Session Manager as well following AWS instructions](https://docs.aws.amazon.com/systems-manager/latest/userguide/install-plugin-macos-overview.html)
85+
86+
You also need `AWS_PROFILE` for Prior Year Access (for both Prod and Non-Prod AWS accounts). [Follow AWS Identity Center: Configuring SSO instructions](https://www.notion.so/cfa/AWS-Identity-Center-e8a28122b2f44595a2ef56b46788ce2c?source=copy_link#ef1c6c77703b4215bbe1953de4692054) to configure your profile correctly.
87+
Name the Prior Year Access - Prod profile as `pya-prod` and Prior Year Access - Non-prod profile as `pya-nonprod`. You can rename your aws profile by editing your `~/.aws/config` and `~/.aws/credentials`.
88+
89+
### Use bin/ecs_exec script (recommended in most cases)
90+
91+
1. Make sure you're logged into aws: `aws sso login`. This should open up an AWS console and have you sign in (if you aren't signed in already). After verification, it'll return you to the terminal
92+
2. For staging, you can use `bin/ecs_exec`
93+
3. For production, you can pass in `bin/ecs_exec --environment production`
94+
4. You can pass in other parameters like:
95+
1. `--desired-status`: `RUNNING` by default, but can specify `STOPPED`. See documentation for [list-tasks](https://docs.aws.amazon.com/cli/latest/reference/ecs/list-tasks.html).
96+
2. `--command`: if you want to run something other than `bin/sh`
97+
3. There are other commands that the aws ecs can call. The options can be passed manually into the `list-tasks` ([doc](https://docs.aws.amazon.com/cli/latest/reference/ecs/list-tasks.html)) and `execute-command`([doc](https://docs.aws.amazon.com/cli/latest/reference/ecs/execute-command.html)) commands. See linked documentation.
98+
5. Type in `bin/rails c --sandbox` (remove `--sandbox` if you must perform operations that will write/modify data in the db; please pair/try to be loud as possible when performing a write operation)
99+
1. When you start rails console, it will say `Loading production environment (Rails <version>)` for both staging AND production. This is because we don't explicitly set a `staging` environment for the RAILS_ENV in our app, to make sure that the environments are similar as possible (We use `REVIEW_APP` to specify heroku/staging environments against the production environment).
100+
101+
---
102+
103+
### Ssh into AWS ECS Manually (if you need to pass in more parameters than the script supports)
104+
105+
1. Find your `task ARN`
106+
```
107+
AWS_PROFILE=<aws profile name> \
108+
aws ecs list-tasks --cluster pya-staging-web \
109+
--query "taskArns[0]" --output text
110+
```
111+
This will return the RUNNING task.
112+
113+
Note that if the newest deploy ran into trouble starting the task, it will be in the STOPPED state. In order to try to debug tasks that have not started successfully or have died/finished, you can add in `--desired-status STOPPED`
114+
See [AWS CLI list-tasks docs for more information and options](https://docs.aws.amazon.com/cli/latest/reference/ecs/list-tasks.html#options)
115+
116+
2. Run the `aws ecs execute-command` ([AWS ECS Execute-Command Docs](https://docs.aws.amazon.com/cli/latest/reference/ecs/execute-command.html))
117+
```
118+
AWS_PROFILE=<aws profile name> \
119+
aws ecs execute-command --cluster pya-<environment>-web \
120+
--task <task ARN; from above> \
121+
--container pya-<environment>-web \
122+
--interactive \
123+
--command "/bin/sh"
124+
```
125+
then when you successfully connect, you'll see:
126+
127+
```
128+
The Session Manager plugin was installed successfully. Use the AWS CLI to start a session.
129+
130+
131+
Starting session with SessionId: ecs-execute-command-<some random string>
132+
#
133+
```
134+
3. `bin/rails c --sandbox` (omit the `--sandbox` if you have to perform a write operation)
135+
136+
---
137+
138+
### (Not recommended) Direct DB access via SQL Statements
139+
140+
You can also utilize AWS Query Editor or `aws rds-data` commands to directly access the staging/production database via psql.
83141

84142
```
85-
AWS_PROFILE=<aws profile> \
143+
AWS_PROFILE=<aws profile name> \
86144
aws rds-data execute-statement \
87145
--resource-arn "arn:aws:rds:us-east-1:<account_id>:cluster:pya-<environment>-web" \
88146
--secret-arn "arn:aws:secretsmanager:us-east-1:<account_id>:secret:rds\!cluster-<secret>" \

bin/ecs_exec

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
#!/bin/bash
2+
3+
# Script to connect to the first task in the pya-<environment>-web cluster
4+
5+
# --- Default Configuration ---
6+
ENVIRONMENT="staging"
7+
DESIRED_STATUS="RUNNING"
8+
COMMAND="/bin/sh" # Default shell
9+
10+
# --- Function to display usage ---
11+
usage() {
12+
echo "Usage: $(basename "$0") [OPTIONS]"
13+
echo "Connects to the first running ECS task in a specified environment."
14+
echo ""
15+
echo "Options:"
16+
echo " --env <environment> Specify the environment (e.g., staging, production). Determines cluster and container names. Defaults to '$ENVIRONMENT'"
17+
echo " --desired-status <status> Task status to search for (e.g., RUNNING, STOPPED). Defaults to '$DESIRED_STATUS'."
18+
echo " Can set to STOPPED for debugging tasks failing to start or for connecting to finished/dead tasks"
19+
echo " --command <command> Command to execute on the container (e.g., \"/bin/bash\", \"ls -la\")."
20+
echo " Defaults to \"$COMMAND\"."
21+
echo " -h, --help Display this help message."
22+
echo ""
23+
echo "Examples:"
24+
echo " $(basename "$0"): to connect to staging"
25+
echo " $(basename "$0") --env production: to connect to production"
26+
echo " $(basename "$0") --desired-status STOPPED: to connect to staging but view the last stopped task"
27+
exit 1
28+
}
29+
30+
# --- Parse Command Line Arguments ---
31+
while [[ "$#" -gt 0 ]]; do
32+
case "$1" in
33+
--env)
34+
ENVIRONMENT="$2"
35+
shift # past argument
36+
shift # past value
37+
;;
38+
--desired-status)
39+
DESIRED_STATUS="$2"
40+
shift
41+
shift
42+
;;
43+
--command)
44+
COMMAND="$2"
45+
shift
46+
shift
47+
;;
48+
-h|--help)
49+
usage
50+
;;
51+
*)
52+
echo "Unknown parameter passed: $1"
53+
usage
54+
;;
55+
esac
56+
done
57+
58+
# --- Set environment-specific variables ---
59+
case "$ENVIRONMENT" in
60+
staging)
61+
PROFILE="pya-nonprod"
62+
CLUSTER_NAME="pya-staging-web"
63+
CONTAINER_NAME="pya-staging-web"
64+
;;
65+
production)
66+
PROFILE="pya-prod"
67+
CLUSTER_NAME="pya-production-web"
68+
CONTAINER_NAME="pya-production-web"
69+
;;
70+
# Add more environments here as needed
71+
*)
72+
echo "Error: Unknown environment '$ENVIRONMENT'. Please specify 'staging' or 'production'."
73+
usage
74+
;;
75+
esac
76+
77+
echo "Attempting to connect to an ECS task in cluster: $CLUSTER_NAME (Env: $ENVIRONMENT) using profile: $(echo $PROFILE | cut -d' ' -f2)"
78+
79+
# --- Find the first running task ---
80+
TASK_ARN=$(aws ecs list-tasks \
81+
--cluster "$CLUSTER_NAME" \
82+
--desired-status "$DESIRED_STATUS" \
83+
--query "taskArns[0]" \
84+
--output text \
85+
--profile "$PROFILE")
86+
87+
if [ -z "$TASK_ARN" ]; then
88+
echo "Error: No tasks found in cluster '$CLUSTER_NAME' with status '$DESIRED_STATUS' using the specified profile."
89+
exit 1
90+
fi
91+
92+
echo "Found task: $TASK_ARN (Status: $DESIRED_STATUS)"
93+
94+
# --- Execute the command ---
95+
echo "Executing command '$COMMAND' on container: $CONTAINER_NAME..."
96+
echo "!!!! ----- YOU ARE CURRENTLY ON $ENVIRONMENT ----- !!!!"
97+
aws ecs execute-command \
98+
--cluster "$CLUSTER_NAME" \
99+
--task "$TASK_ARN" \
100+
--container "$CONTAINER_NAME" \
101+
--interactive \
102+
--command "$COMMAND" \
103+
--profile "$PROFILE"
104+
105+
if [ $? -ne 0 ]; then
106+
echo "Error: Failed to execute command on the task."
107+
echo "Please check:"
108+
echo " - Your AWS CLI credentials for profile $(echo $PROFILE | cut -d' ' -f2)."
109+
echo " Your aws profile name needs to be pya-prod (production) or pya-nonprod (staging)"
110+
echo " - Network connectivity from your machine"
111+
echo " - ECS execute-command permissions for your account"
112+
echo " - That the container has the specified command available (e.g., /bin/sh, /bin/bash)"
113+
echo " - That the task itself is healthy and not restarting."
114+
exit 1
115+
fi
116+
117+
echo "Session ended."

0 commit comments

Comments
 (0)