From 7d839717994f8b482010beee3fc89be3394cd1e8 Mon Sep 17 00:00:00 2001 From: Noah Spannbauer Date: Fri, 29 Nov 2024 22:31:51 -0600 Subject: [PATCH] changing api to azure container app --- .github/workflows/api.yaml | 39 +++++++-- app/src/App.tsx | 46 +++++------ infrastructure/.terraform.lock.hcl | 26 +++--- infrastructure/api.tf | 47 ----------- infrastructure/container_app.tf | 91 +++++++++++++++++++++ infrastructure/container_app_environment.tf | 14 ++++ infrastructure/main.tf | 8 +- infrastructure/variables.tf | 64 ++++++++++----- 8 files changed, 220 insertions(+), 115 deletions(-) delete mode 100644 infrastructure/api.tf create mode 100644 infrastructure/container_app.tf create mode 100644 infrastructure/container_app_environment.tf diff --git a/.github/workflows/api.yaml b/.github/workflows/api.yaml index ad2ad6e..82d56d3 100644 --- a/.github/workflows/api.yaml +++ b/.github/workflows/api.yaml @@ -7,11 +7,12 @@ on: type: string jobs: - build-and-deploy: + build: runs-on: ubuntu-latest environment: ${{ inputs.calling_workflow }} steps: - - uses: actions/checkout@v4 + - name: Checkout + uses: actions/checkout@v4 with: submodules: true @@ -29,9 +30,33 @@ jobs: run: | npm run build -w api - - name: Deploy - uses: Azure/functions-action@v1 + - name: Setup Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log into Docker Hub + uses: docker/login-action@v3 with: - app-name: ${{ vars.API_FUNCTION_APP_NAME }} - package: ${{ vars.API_FUNCTION_APP_PACKAGE_PATH }} - publish-profile: ${{ secrets.API_FUNCTION_APP_PUBLISH_PROFILE }} + username: ${{ vars.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Build and push to registry + uses: docker/build-push-action@v6 + with: + push: true + tags: noahspan/flying-api:${{ github.run_id }} + file: ./api/Dockerfile + context: ./api + + deploy: + runs-on: ubuntu-latest + environment: ${{ inputs.calling_workflow }} + needs: build + steps: + - name: Log in to Azure + uses: azure/login@v2 + with: + creds: ${{ secrets.AZURE_CREDENTIALS }} + + - name: Update Container App + run: | + az container app update --name flying-api --resource-group noahspan --image noahspan-flying:${{ github.run_id }} diff --git a/app/src/App.tsx b/app/src/App.tsx index b1a4034..39743c8 100644 --- a/app/src/App.tsx +++ b/app/src/App.tsx @@ -12,36 +12,36 @@ const App: React.FC = () => { const httpClient: AxiosInstance = useHttpClient(); const appContext = useAppContext(); - useEffect(() => { - const getFeatureFlags = async () => { - try { - const featureFlagKeys: string = 'flying-pilots'; - const response: AxiosResponse = await httpClient.get( - `api/featureFlags?keys=${featureFlagKeys}&label=${import.meta.env.MODE}` - ); - const featureFlags: { key: string; enabled: boolean }[] = response.data; + // useEffect(() => { + // const getFeatureFlags = async () => { + // try { + // const featureFlagKeys: string = 'flying-pilots'; + // const response: AxiosResponse = await httpClient.get( + // `api/featureFlags?keys=${featureFlagKeys}&label=${import.meta.env.MODE}` + // ); + // const featureFlags: { key: string; enabled: boolean }[] = response.data; - if (featureFlags.length > 0) { - appContext.dispatch({ - type: 'SET_FEATURE_FLAGS', - payload: featureFlags - }); - } - } catch (error) { - console.log(error); - } - }; + // if (featureFlags.length > 0) { + // appContext.dispatch({ + // type: 'SET_FEATURE_FLAGS', + // payload: featureFlags + // }); + // } + // } catch (error) { + // console.log(error); + // } + // }; - getFeatureFlags(); - }, []); + // getFeatureFlags(); + // }, []); return (
- {useFeatureFlag('flying-pilots')?.enabled && ( - } /> - )} + {/* {useFeatureFlag('flying-pilots')?.enabled && ( */} + } /> + {/* )} */} } />
diff --git a/infrastructure/.terraform.lock.hcl b/infrastructure/.terraform.lock.hcl index 28e1a7f..bab3b56 100644 --- a/infrastructure/.terraform.lock.hcl +++ b/infrastructure/.terraform.lock.hcl @@ -2,20 +2,20 @@ # Manual edits may be lost in future updates. provider "registry.terraform.io/hashicorp/azurerm" { - version = "3.104.2" + version = "4.11.0" hashes = [ - "h1:1J+ajk1s1qfjViKYSOYDb8HLOh2RIn/TAK/2s3orPuE=", - "zh:05b4a3572ce2b881fef5ec64756b060e8ce6c24c260182acf4adec38a6b29204", - "zh:0d5118f6ad64278a52b720cdbf1a6b7ab7ea1ad5bd3d9607cb558d8d25280906", - "zh:2196f49d73bf862a046b24e143f5d658bbb01bfb4e8582a88eb3907ff4f69730", - "zh:285c1a65bf3b70859110c2bbafefa4483d450840282a57f349b81b17367bbb26", - "zh:2efbd00970952761d60043c41e983dc6930678ef179de2b27ed00437fa711703", - "zh:6b7e26e6ba3a639e2a26b2e64f4629e28a44a9572f4203c30cb1c611f37ddb21", - "zh:8149b7aada49cac3ef49d7595d2fc2e3a573f4c01d272a6a4111efa089f2e44f", - "zh:9674f741d7be268778a0f0a59174130800f8977747ef16a1dd6446031c7ae8d4", - "zh:aed0e78df3c5de8eaa8c8cacb4e3c48ec26683f2e35dd42eabc1242592fad247", - "zh:c0c97188d9a5a26c5ce2dbcc1c6b31fb73469bb2e422e64a1dda25c9355c341c", - "zh:e883eca472593e34f2f93282973c148114eab19fceb8348fc82e91293b247118", + "h1:2YQgcxXJ7ZpJyo7bcKhhMrUEg4s/kUA1lcbYoFuN/qM=", + "zh:026808a5ff8bce161518d503bfc57c4a95637d67e923a94382c8e878c96aaf00", + "zh:13473ebb56ed701fdd8c288a220cef3ec6ee170fb1ac45c6ce5a612848e64690", + "zh:36667374d31509456fd928f651fc1ccc7438c53bc99cf9ec3b6ec6e7f791394e", + "zh:5f44e16aab36a93391ce81b9a93b694fecf11f71615f2414ee40bb5e211d3dbb", + "zh:9310e860f9236d0f7171e05444ca85e239f0938b9fb08ec3bfd9712a14013308", + "zh:aaf6ea1f68526a175e84424710b06dd6cf8987b404206cc581692560c1530810", + "zh:b6d1965af0aed85f3eccaaec5dae90f59632bf07e2bf5b7473359a7c761872a5", + "zh:c642675ea2d8e1f1bb440016238ab25fa4270cb155b01e90598161488df47128", + "zh:d22d07834c2a5da6ce7054699d4f708277fccb63436cfbf6c90c58cddddba408", + "zh:eceb91d652ea9145531129c7da50603e9415812f639acbf1720d51f878798fb8", + "zh:f26bf55ce68c1ed6e316ee70652bc3cc357987ea4b3caf6f835405850c6897e0", "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", ] } diff --git a/infrastructure/api.tf b/infrastructure/api.tf deleted file mode 100644 index 85191e2..0000000 --- a/infrastructure/api.tf +++ /dev/null @@ -1,47 +0,0 @@ -resource "azurerm_service_plan" "service_plan" { - name = "noahspan-flying-api-service-plan" - resource_group_name = data.azurerm_resource_group.resource_group.name - location = data.azurerm_resource_group.resource_group.location - os_type = "Linux" - sku_name = "Y1" -} - -resource "azurerm_linux_function_app" "function_app_dev" { - name = "noahspanflyingapidev" - resource_group_name = data.azurerm_resource_group.resource_group.name - location = data.azurerm_resource_group.resource_group.location - service_plan_id = azurerm_service_plan.service_plan.id - storage_account_name = azurerm_storage_account.storage_account_dev.name - storage_account_access_key = azurerm_storage_account.storage_account_dev.primary_access_key - - app_settings = { - "CLIENT_ID" = "${var.CLIENT_ID}" - "CLIENT_SECRET" = "${var.CLIENT_SECRET}" - "TENANT_ID" = "${var.TENANT_ID}" - "AZURE_STORAGE_ACCOUNT_NAME" = azurerm_storage_account.storage_account_dev.name - "AZURE_STORAGE_ACCOUNT_KEY" = azurerm_storage_account.storage_account_dev.primary_access_key - "AZURE_STORAGE_ACCOUNT_URL" = azurerm_storage_account.storage_account_dev.primary_table_host - } - - auth_settings_v2 { - active_directory_v2 { - client_id = var.CLIENT_ID - tenant_auth_endpoint = "https://login.microsoftonline.com/${var.TENANT_ID}/v2.0/" - client_secret_setting_name = "CLIENT_SECRET" - } - - login { - - } - } - - site_config { - application_stack { - node_version = 20 - } - - cors { - allowed_origins = [ azurerm_static_web_app.static_web_app.default_host_name ] - } - } -} \ No newline at end of file diff --git a/infrastructure/container_app.tf b/infrastructure/container_app.tf new file mode 100644 index 0000000..1f3aa3d --- /dev/null +++ b/infrastructure/container_app.tf @@ -0,0 +1,91 @@ +resource "azurerm_container_app" "container_app_dev" { + name = "flying-api" + container_app_environment_id = azurerm_container_app_environment.container_app_environment_dev.id + resource_group_name = data.azurerm_resource_group.resource_group.name + revision_mode = "Single" + + registry { + server = "index.docker.io" + username = var.DOCKER_IO_USERNAME + password_secret_name = "docker-io-password" + } + + template { + min_replicas = 0 + max_replicas = 1 + + container { + name = "flying-api-dev" + image = "noahspan/flying-api:v0.0.1" + cpu = 0.25 + memory = "0.5Gi" + + env { + name = "APP_CONFIG_URL" + value = "https://noahspann-appconfig.azconfig.io" + } + + env { + name = "AZURE_STORAGE_ACCOUNT_KEY" + secret_name = "azure-storage-account-key" + } + + env { + name = "AZURE_STORAGE_ACCOUNT_NAME" + value = "noahspanflyingdev" + } + + env { + name = "AZURE_STROAGE_ACCOUNT_URL" + value = "https://noahspanflyingdev.table.core.windows.net/" + } + + env { + name = "CLIENT_ID" + secret_name = "client-id" + } + + env { + name = "CLIENT_SECRET" + secret_name = "client-secret" + } + + env { + name = "TENANT_ID" + value = "0f23652e-4b15-420f-991e-3d6fc769a31d" + } + } + } + + ingress { + allow_insecure_connections = false + external_enabled = true + target_port = 80 + transport = "auto" + + traffic_weight { + latest_revision = true + percentage = 100 + } + } + + secret { + name = "azure-storage-account-key" + value = var.AZURE_STORAGE_ACCOUNT_KEY + } + + secret { + name = "client-id" + value = var.CLIENT_ID + } + + secret { + name = "client-secret" + value = var.CLIENT_SECRET + } + + secret { + name = "docker-io-password" + value = var.DOCKER_IO_PASSWORD + } +} diff --git a/infrastructure/container_app_environment.tf b/infrastructure/container_app_environment.tf new file mode 100644 index 0000000..71572fd --- /dev/null +++ b/infrastructure/container_app_environment.tf @@ -0,0 +1,14 @@ +resource "azurerm_log_analytics_workspace" "log_analytics_workspace" { + name = "noahspan-flying-log-analytics-workspace" + location = data.azurerm_resource_group.resource_group.location + resource_group_name = data.azurerm_resource_group.resource_group.name + sku = "PerGB2018" + retention_in_days = 30 +} + +resource "azurerm_container_app_environment" "container_app_environment_dev" { + name = "flying-dev" + location = data.azurerm_resource_group.resource_group.location + resource_group_name = data.azurerm_resource_group.resource_group.name + log_analytics_workspace_id = azurerm_log_analytics_workspace.log_analytics_workspace.id +} \ No newline at end of file diff --git a/infrastructure/main.tf b/infrastructure/main.tf index e517c24..7ebca69 100644 --- a/infrastructure/main.tf +++ b/infrastructure/main.tf @@ -6,8 +6,8 @@ resource "azurerm_static_web_app" "static_web_app" { sku_tier = "Free" } -resource "azurerm_dns_cname_record" "dns_cname_record" { - name = var.SUBDOMAIN_NAME +resource "azurerm_dns_cname_record" "dns_cname_record_app" { + name = var.APP_SUBDOMAIN_NAME zone_name = data.azurerm_dns_zone.dns_zone.name resource_group_name = data.azurerm_resource_group.resource_group.name ttl = 14400 @@ -16,8 +16,8 @@ resource "azurerm_dns_cname_record" "dns_cname_record" { resource "azurerm_static_web_app_custom_domain" "static_web_app_custom_domain" { static_web_app_id = azurerm_static_web_app.static_web_app.id - domain_name = "${var.SUBDOMAIN_NAME}.${var.DOMAIN_NAME}" + domain_name = "${var.APP_SUBDOMAIN_NAME}.${var.DOMAIN_NAME}" validation_type = "cname-delegation" - depends_on = [ azurerm_dns_cname_record.dns_cname_record ] + depends_on = [ azurerm_dns_cname_record.dns_cname_record_app ] } \ No newline at end of file diff --git a/infrastructure/variables.tf b/infrastructure/variables.tf index 04765a9..e3a5f4f 100644 --- a/infrastructure/variables.tf +++ b/infrastructure/variables.tf @@ -1,3 +1,42 @@ +variable "API_SUBDOMAIN_NAME" { + type = string +} + +variable "APP_SUBDOMAIN_NAME" { + type = string +} + +variable "AZURE_STORAGE_ACCOUNT_KEY" { + type = string + sensitive = true +} + +variable "CLIENT_ID" { + type = string +} + +variable "CLIENT_SECRET" { + type = string + sensitive = true +} + +variable "DOCKER_IO_PASSWORD" { + type = string + sensitive = true +} + +variable "DOCKER_IO_USERNAME" { + type = string +} + +variable "DOMAIN_NAME" { + type = string +} + +variable "CUSTOM_DOMAIN_NAME_COUNT" { + type = number +} + variable "REGION" { type = string } @@ -10,32 +49,15 @@ variable "STATIC_WEB_APP_NAME" { type = string } -variable "DOMAIN_NAME" { - type = string -} - -variable "SUBDOMAIN_NAME" { - type = string -} - -variable "CUSTOM_DOMAIN_NAME_COUNT" { - type = number -} - variable "STORAGE_ACCOUNT_NAME" { type = string } -variable "CLIENT_ID" { - type = string -} - -variable "CLIENT_SECRET" { - type = string - sensitive = true -} - variable "TENANT_ID" { type = string } +variable "WORKSPACE" { + type = string +} +