연습 - 비밀을 사용하는 Java 애플리케이션 코딩

완료됨

데이터베이스에 연결하는 Spring Boot을 사용하여 Java 웹 애플리케이션을 코딩하려고 합니다.

보안상의 이유로 나중에 해당 데이터베이스 액세스를 보호해야 합니다. 하지만 먼저 애플리케이션 인프라를 만든 다음, 해당 인프라를 사용하도록 Java 애플리케이션을 구성해 보겠습니다.

애플리케이션 인프라 만들기

이 연습에서는 Azure CLI를 사용하여 다음 리소스를 만듭니다.

  • 애플리케이션에 필요한 모든 리소스를 포함하는 Azure 리소스 그룹.
  • PostgreSQL 데이터베이스 서버
  • Azure Spring Apps 클러스터 및 이 클러스터 내에서 실행되는 Spring Boot 애플리케이션.

스크립트의 시작 부분에 Azure에서 고유한 몇 가지 환경 변수를 제공해야 합니다.

로컬 컴퓨터에서 데이터베이스에 액세스하려면 로컬 IP 주소도 제공해야 합니다. 이 IP 주소는 IPv4 주소여야 합니다. 로컬 IP 주소를 모르는 경우 웹 사이트 https://www.whatismyip.com/으로 이동할 수 있습니다.

다음 환경 변수를 설정합니다.

AZ_RESOURCE_GROUP=<YOUR_UNIQUE_RESOURCE_GROUP_NAME>
AZ_DATABASE_USERNAME=<YOUR_POSTGRESQL_USERNAME>
AZ_DATABASE_PASSWORD=<YOUR_POSTGRESQL_PASSWORD>
AZ_LOCAL_IP_ADDRESS=<YOUR_LOCAL_IP_ADDRESS>

이러한 환경 변수를 설정한 후에는 다음 명령을 실행하여 리소스를 만들 수 있습니다.

AZ_LOCATION=eastus
# Must be all lowercase
AZ_SPRING_CLOUD=spring-${AZ_RESOURCE_GROUP,,}

AZ_DATABASE_NAME=pgsql-${AZ_RESOURCE_GROUP}
AZ_DATABASE_USERNAME=${AZ_DATABASE_USERNAME}

az group create \
    --name $AZ_RESOURCE_GROUP \
    --location $AZ_LOCATION

이 명령을 완료하는 데 몇 분 정도 걸릴 수 있습니다.

az postgres server create \
    --resource-group $AZ_RESOURCE_GROUP \
    --name $AZ_DATABASE_NAME \
    --location $AZ_LOCATION \
    --sku-name B_Gen5_1 \
    --storage-size 5120 \
    --admin-user $AZ_DATABASE_USERNAME \
    --admin-password $AZ_DATABASE_PASSWORD
az postgres server firewall-rule create \
    --resource-group $AZ_RESOURCE_GROUP \
    --name $AZ_DATABASE_NAME-database-allow-local-ip \
    --server $AZ_DATABASE_NAME \
    --start-ip-address $AZ_LOCAL_IP_ADDRESS \
    --end-ip-address $AZ_LOCAL_IP_ADDRESS

az postgres server firewall-rule create \
    --resource-group $AZ_RESOURCE_GROUP \
    --name $AZ_DATABASE_NAME-database-allow-azure-ip \
    --server $AZ_DATABASE_NAME \
    --start-ip-address 0.0.0.0 \
    --end-ip-address 0.0.0.0
az postgres db create \
    --resource-group $AZ_RESOURCE_GROUP \
    --name demo \
    --server-name $AZ_DATABASE_NAME

이 명령을 완료하는 데 몇 분 정도 걸릴 수 있습니다.

az extension add --name spring

az spring create \
   --name $AZ_SPRING_CLOUD \
   --resource-group $AZ_RESOURCE_GROUP \
   --location $AZ_LOCATION \
   --sku Basic

이 명령을 완료하는 데 몇 분 정도 걸릴 수 있습니다.

az spring app create \
   --resource-group $AZ_RESOURCE_GROUP \
   --service $AZ_SPRING_CLOUD \
   --name application \
   --runtime-version Java_11 \
   --assign-endpoint true

이러한 스크립트를 실행하는 데 시간이 걸리므로, 스크립트를 백그라운드에서 실행하고 그 사이에 애플리케이션 코딩을 시작할 수 있습니다.

Java 애플리케이션 구성

git clone 명령을 사용하여 https://github.com/Azure-Samples/manage-secrets-in-java-applications GitHub 리포지토리에서 애플리케이션 구조를 가져옵니다.

git clone https://github.com/Azure-Samples/manage-secrets-in-java-applications.git

이 애플리케이션은 Spring Data JPA를 사용하여 데이터베이스에 액세스합니다. CRUD 리포지토리 인터페이스를 살펴볼 수 있습니다.

package com.example.demo;

import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface ItemRepository extends CrudRepository<Item, Integer> {
}

그러면 데이터베이스에 저장되는 데이터는 Spring MVC REST Controller를 사용하여 웹에 노출됩니다.

package com.example.demo;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ItemController {

    private final ItemRepository itemRepository;

    public ItemController(ItemRepository itemRepository) {
        this.itemRepository = itemRepository;
    }

    @GetMapping("/")
    String welcome() {
        return "Here are all the database items: " + itemRepository.findAll();
    }
}

이 데이터는 src/main/resources/data.sql 파일을 사용하여 시작 시 데이터베이스에 삽입됩니다.

insert into item (details) values ('This is a item from the database');

더 많은 데이터를 원하는 경우 또는 사용자 지정하려는 경우 이 파일에 더 많은 줄을 추가할 수 있습니다.

데이터베이스에 액세스하려면 src/main/resources/application.properties 파일을 구성해야 합니다.

logging.level.org.springframework.jdbc.core=DEBUG

spring.datasource.url=jdbc:postgresql://${azureDatabaseName}.postgres.database.azure.com:5432/demo
spring.datasource.username=${azureDatabaseUsername}@${azureDatabaseName}
spring.datasource.password=${azureDatabasePassword}

spring.sql.init.mode=always

이 구성 파일에는 구성해야 하는 다음과 같은 세 개의 변수가 있습니다.

  • ${azureDatabaseName}AZ_DATABASE_NAME 환경 변수에서 이전에 구성한 PostgreSQL 데이터베이스의 이름입니다. 확인하려면 echo $AZ_DATABASE_NAME을 입력합니다.
  • ${azureDatabaseUsername}AZ_DATABASE_USERNAME 환경 변수에서 이전에 구성한 데이터베이스 사용자의 이름입니다. 확인하려면 echo $AZ_DATABASE_USERNAME을 입력합니다.
  • ${azureDatabasePassword}AZ_DATABASE_PASSWORD 환경 변수에서 이전에 구성한 데이터베이스 암호입니다. 확인하려면 echo $AZ_DATABASE_PASSWORD를 입력합니다.

이전 단원에서 살펴본 것처럼 이러한 값을 애플리케이션 소스 코드에 하드 코딩하는 것은 좋지 않은 사례입니다. 그러나 애플리케이션을 테스트하기 위해 임시로 작성하고 애플리케이션을 실행할 수 있습니다.

./mvnw spring-boot:run

다음 명령을 사용하거나 웹 브라우저를 통해 Spring MVC Controller에 액세스하여 데이터베이스 콘텐츠를 읽을 수 있습니다.

curl http://localhost:8080

Azure에 Java 애플리케이션 배포

애플리케이션을 배포하려면 먼저 Jar 파일로 패키지해야 합니다.

./mvnw clean package

이 명령은 Azure CLI를 사용하여 배포하는 target 디렉터리에 실행 가능한 Jar 파일을 생성합니다.

az spring app deploy \
   --resource-group $AZ_RESOURCE_GROUP \
   --service $AZ_SPRING_CLOUD \
   --name application \
   --artifact-path target/*.jar

오류가 발생하면 다음 명령을 입력하여 애플리케이션 로그를 확인할 수 있습니다.

az spring app logs \
   --resource-group $AZ_RESOURCE_GROUP \
   --service $AZ_SPRING_CLOUD \
   --name application

그러면 클라우드에서 애플리케이션을 사용할 수 있으며 cURL 명령을 사용하여 해당 데이터에 액세스할 수 있습니다.

curl https://$AZ_SPRING_CLOUD-application.azuremicroservices.io

# Expected output:
#
# Here are all the database items: [Secret{Id=1, details='This is a item from the database'}]
#

축하합니다! 데이터베이스에 연결하는 Java 애플리케이션을 성공적으로 만들었습니다. 이제 다음 단원에서는 데이터베이스 자격 증명을 보호해야 합니다.