Skip to content

Commit e721346

Browse files
authored
SRE-197, SRE-198, BE-233: Add reusable GitHub Action for ECS service redeployment (#8169)
1 parent d464a54 commit e721346

File tree

8 files changed

+276
-65
lines changed

8 files changed

+276
-65
lines changed
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
name: Redeploy ECS service
2+
description: Force a new ECS service deployment with optional role assumption
3+
4+
inputs:
5+
AWS_ACCESS_KEY_ID:
6+
description: AWS access key id
7+
required: true
8+
AWS_SECRET_ACCESS_KEY:
9+
description: AWS secret access key
10+
required: true
11+
AWS_SESSION_TOKEN:
12+
description: AWS session token
13+
required: true
14+
AWS_REGION:
15+
description: AWS region
16+
required: true
17+
ECS_CLUSTER_NAME:
18+
description: ECS cluster name
19+
required: true
20+
ECS_SERVICE_NAME:
21+
description: ECS service name
22+
required: true
23+
ROLE_ARN:
24+
description: IAM role ARN to assume for deployment (cross-account)
25+
required: false
26+
27+
runs:
28+
using: composite
29+
steps:
30+
- name: Configure AWS credentials
31+
uses: aws-actions/configure-aws-credentials@7474bc4690e29a8392af63c5b98e7449536d5c3a # v4.3.1
32+
with:
33+
aws-access-key-id: ${{ inputs.AWS_ACCESS_KEY_ID }}
34+
aws-secret-access-key: ${{ inputs.AWS_SECRET_ACCESS_KEY }}
35+
aws-session-token: ${{ inputs.AWS_SESSION_TOKEN }}
36+
aws-region: ${{ inputs.AWS_REGION }}
37+
role-to-assume: ${{ inputs.ROLE_ARN }}
38+
39+
- name: Redeploy ECS service
40+
env:
41+
ECS_CLUSTER_NAME: ${{ inputs.ECS_CLUSTER_NAME }}
42+
ECS_SERVICE_NAME: ${{ inputs.ECS_SERVICE_NAME }}
43+
shell: bash
44+
run: |
45+
aws ecs update-service \
46+
--cluster "${ECS_CLUSTER_NAME}" \
47+
--service "${ECS_SERVICE_NAME}" \
48+
--force-new-deployment 1> /dev/null

.github/workflows/hash-backend-cd.yml

Lines changed: 211 additions & 53 deletions
Large diffs are not rendered by default.

apps/hash-graph/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
"private": true,
55
"license": "AGPL-3",
66
"scripts": {
7-
"build:docker": "docker buildx build --build-arg PROFILE=production --tag hash-graph --file docker/Dockerfile ../../ --load",
8-
"build:docker:dev": "docker buildx build --build-arg PROFILE=dev --tag hash-graph --file docker/Dockerfile ../../ --load",
7+
"build:docker": "docker buildx build --build-arg PROFILE=production --build-arg ENABLE_TEST_SERVER=yes --tag hash-graph --file docker/Dockerfile ../../ --load",
8+
"build:docker:dev": "docker buildx build --build-arg PROFILE=dev --build-arg ENABLE_TEST_SERVER=yes --tag hash-graph --file docker/Dockerfile ../../ --load",
99
"compile": "cargo build --bin hash-graph --all-features",
1010
"compile:release": "cargo build --bin hash-graph --all-features --release",
1111
"doc:dependency-diagram": "cargo run -p hash-repo-chores -- dependency-diagram --output docs/dependency-diagram.mmd --root hash-graph --root-deps-and-dependents --link-mode non-roots --include-dev-deps --include-build-deps --logging-console-level info",

apps/hash-graph/src/subcommand/server.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ pub async fn server(args: ServerArgs) -> Result<(), Report<GraphError>> {
376376
}
377377

378378
pub async fn healthcheck(address: HttpAddress) -> Result<(), Report<HealthcheckError>> {
379-
let request_url = format!("http://{address}/api-doc/openapi.json");
379+
let request_url = format!("http://{address}/health");
380380

381381
timeout(
382382
Duration::from_secs(10),

apps/hash-graph/src/subcommand/test_server.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ pub async fn test_server(args: TestServerArgs) -> Result<(), Report<GraphError>>
9191
}
9292

9393
pub async fn healthcheck(address: HttpAddress) -> Result<(), Report<HealthcheckError>> {
94-
let request_url = format!("http://{address}/snapshot");
94+
let request_url = format!("http://{address}/health");
9595

9696
timeout(
9797
Duration::from_secs(10),

libs/@local/graph/api/src/rest/mod.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -336,12 +336,14 @@ where
336336
pub fn openapi_only_router() -> Router {
337337
let open_api_doc = OpenApiDocumentation::openapi();
338338

339-
Router::new().nest(
340-
"/api-doc",
341-
Router::new()
342-
.route("/openapi.json", get(|| async { Json(open_api_doc) }))
343-
.route("/models/{*path}", get(serve_static_schema)),
344-
)
339+
Router::new()
340+
.route("/health", get(async || "Healthy".into_response()))
341+
.nest(
342+
"/api-doc",
343+
Router::new()
344+
.route("/openapi.json", get(|| async { Json(open_api_doc) }))
345+
.route("/models/{*path}", get(serve_static_schema)),
346+
)
345347
}
346348

347349
/// A [`Router`] that serves all of the REST API routes, and the `OpenAPI` specification.

libs/@local/graph/test-server/src/lib.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ use std::collections::HashMap;
1212
use axum::{
1313
Extension, Router,
1414
body::Body,
15-
response::Response,
16-
routing::{delete, post},
15+
response::{IntoResponse as _, Response},
16+
routing::{delete, get, post},
1717
};
1818
use error_stack::Report;
1919
use futures::TryStreamExt as _;
@@ -32,6 +32,7 @@ use uuid::Uuid;
3232
pub fn routes(store_pool: PostgresStorePool) -> Router {
3333
Router::new()
3434
.layer(http_tracing_layer::HttpTracingLayer)
35+
.route("/health", get(async || "Healthy".into_response()))
3536
.route("/snapshot", post(restore_snapshot))
3637
.route("/accounts", delete(delete_accounts))
3738
.route("/data-types", delete(delete_data_types))

libs/@local/telemetry/src/traces/sentry.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,15 @@ use tracing_subscriber::{Layer, registry::LookupSpan};
2828
pub enum SentryEnvironment {
2929
#[default]
3030
Development,
31+
Staging,
3132
Production,
3233
}
3334

3435
impl fmt::Display for SentryEnvironment {
3536
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
3637
match self {
3738
Self::Development => fmt.write_str("development"),
39+
Self::Staging => fmt.write_str("staging"),
3840
Self::Production => fmt.write_str("production"),
3941
}
4042
}

0 commit comments

Comments
 (0)