Amazon Web Services 한국 블로그

AWS CodeArtifact, Cargo와 함께 Rust 패키지에 대한 지원 추가

오늘부터 Rust 개발자는 라이브러리(Rust에서는 상자(crate)라고 함)를 AWS CodeArtifact에 저장하고 액세스할 수 있습니다.

최신 소프트웨어 개발은 개발 속도를 높이기 위해 미리 작성된 코드 패키지에 크게 의존합니다. 이러한 패키지는 단일 애플리케이션으로는 수백 개에 달할 수 있으며, 일반적인 프로그래밍 작업을 처리하고 내부에서 만들거나 외부 소스에서 가져올 수 있습니다. 이러한 패키지는 개발 속도를 높이는 데 큰 도움이 되지만, 이러한 패키지를 사용하는 조직은 법률 및 보안 문제라는 두 가지 주요 과제를 안고 있습니다.

법적 측면에서 조직은 이러한 타사 패키지에 대해 호환되는 라이선스를 보유하고 있는지, 지적 재산권을 침해하지 않는지 확인해야 합니다. 이러한 패키지의 취약점을 악용하여 애플리케이션을 손상시킬 수 있으므로 보안은 또 다른 위험 요소입니다. 알려진 전술인 공급망 공격은 인기 있는 오픈 소스 프로젝트에 취약점을 주입하는 것입니다.

이러한 문제를 해결하기 위해 조직은 비공개 패키지 리포지토리를 설정할 수 있습니다. 이러한 리포지토리에는 보안 및 법무팀의 심사를 거친 사전 승인된 패키지가 저장되므로 법률 또는 보안 노출 위험이 제한됩니다. 여기에서 CodeArtifact가 필요합니다.

AWS CodeArtifact는 애플리케이션 개발에 사용되는 소프트웨어 패키지를 안전하게 저장, 게시 및 공유하도록 설계된 완전 관리형 아티팩트 리포지토리 서비스입니다. npm, PyPI, Maven, NuGet, SwiftPM, Rubygem 등 널리 사용되는 패키지 관리자 및 형식을 지원하므로 기존 개발 워크플로에 쉽게 통합할 수 있습니다. 액세스 제어를 통해 보안을 강화하고 팀 간 협업을 촉진하는 데 도움이 됩니다. CodeArtifact는 AWS Identity and Access Management(IAM) 및 지속적 통합 및 지속적 배포(CI/CD) 도구와 통합하여 일관되고 안전하며 효율적인 소프트웨어 개발 수명 주기를 유지하도록 도와줍니다.

RustStack Overflow의 연례 개발자 설문조사에서 8년 연속 ‘가장 선호하는 프로그래밍 언어’로 1위를 차지했으며, 80% 이상의 개발자가 내년에도 이 언어를 사용하고 싶다고 답했습니다. Rust의 인기가 높아지는 이유는 C++와 같은 시스템 언어의 성능 및 메모리 안전성과 안정적인 동시 코드 작성을 더 쉽게 해주는 기능을 결합할 수 있기 때문입니다. 이는 풍성한 생태계와 커뮤니티 협업에 중점을 두어 고성능 시스템 및 애플리케이션을 개발하는 개발자에게 매력적인 옵션입니다.

Rust 개발자는 패키지 종속성을 관리하기 위해 공식 패키지 관리자인 Cargo를 사용합니다. Cargo는 미리 작성된 상자(라이브러리)를 찾고, 다운로드하고, 프로젝트에 통합하는 과정을 간소화합니다. 이렇게 하면 수동 종속성 관리가 필요 없어져 시간이 절약될 뿐만 아니라 호환성과 보안도 보장됩니다. Cargo의 강력한 종속성 해결 시스템은 서로 다른 상자 버전 간의 잠재적인 충돌을 해결하며, 많은 상자가 선별된 레지스트리에서 제공되므로 개발자는 코드의 품질과 안전성에 대해 더욱 확신을 가질 수 있습니다. 효율성과 안정성에 중점을 둔 Cargo는 Rust 애플리케이션을 구축하는 데 필수적인 도구입니다.

내 상자에 대한 CodeArtifact 리포지토리를 만들어 보겠습니다
이 데모에서는 AWS Command Line Interface(AWS CLI)AWS Management Console을 사용하여 두 개의 리포지토리를 생성합니다. 첫 번째 리포지토리는 공식 crates.io 리포지토리에서 공개 패키지를 다운로드하도록 구성합니다. 두 번째 리포지토리는 첫 번째 리포지토리에서만 패키지를 다운로드하도록 구성합니다. 이 이중 리포지토리 구성은 리포지토리와 외부 연결을 관리하는 데 권장되는 방법이며, 외부 연결 관리에 대한 CodeArtifact 설명서를 참조하세요. 설명서 인용 방법:

“특정 공용 리포지토리에 대한 외부 연결이 있는 도메인당 하나의 리포지토리를 사용하는 것이 좋습니다. 다른 리포지토리를 공용 리포지토리에 연결하려면 외부 연결이 있는 리포지토리를 업스트림으로 추가하세요.”

설정을 설명하기 위해 이 다이어그램을 대략적으로 그려보았습니다.

Cargo용 Code Artifact 리포지토리

도메인과 리포지토리는 명령줄 또는 콘솔에서 만들 수 있습니다. 명령줄을 선택합니다. 쉘 터미널에 다음을 입력합니다:

CODEARTIFACT_DOMAIN=stormacq-test

# 내부 리포지토리 만들기: crates-io-store
aws codeartifact create-repository \
   --domain $CODEARTIFACT_DOMAIN   \
   --repository crates-io-store

# 내부 리포지토리 crates-io-store를 퍼블릭 crates-io에 연결합니다.
aws codeartifact associate-external-connection \
--domain $CODEARTIFACT_DOMAIN \
--repository crates-io-store  \
--external-connection public:crates-io

# 두 번째 내부 리포지토리 cargo-repo를 생성합니다 
# 그리고 방금 생성한 업스트림 크레이트-io-store에 연결합니다
aws codeartifact create-repository \
   --domain $CODEARTIFACT_DOMAIN   \
   --repository cargo-repo         \
   --upstreams '{"repositoryName":"crates-io-store"}'	 

다음으로, 개발자로서 로컬 머신이 방금 만든 내부 저장소(cargo-repo)에서 상자를 가져오기를 원합니다.

퍼블릭 crates.io 대신 내부 리포지토리에서 라이브러리를 가져오도록 cargo를 구성했습니다. 이를 위해 CodeArtifact 내부 리포지토리를 가리키는 config.toml 파일을 생성합니다.

# 먼저, 리포지토리의 URI를 검색합니다.
REPO_ENDPOINT=$(aws codeartifact get-repository-endpoint \
                           --domain $CODEARTIFACT_DOMAIN \ 
                           --repository cargo-repo       \
                           --format cargo                \
                           --output text)

# 이 단계에서 REPO_ENDPOINT는 https://stormacq-test-012345678912.d.codeartifact.us-west-2.amazonaws.com/cargo/cargo-repo/ 입니다.

# 다음으로, Cargo 구성 파일을 생성합니다
cat << EOF > ~/.cargo/config.toml
[registries.cargo-repo]
index = "sparse+$REPO_ENDPOINT"
credential-provider = "cargo:token-from-stdout aws codeartifact get-authorization-token --domain $CODEARTIFACT_DOMAIN --query authorizationToken --output text"

[registry]
default = "cargo-repo"

[source.crates-io]
replace-with = "cargo-repo"
EOF

구성 파일을 만들 때 두 개의 환경 변수가 대체됩니다. Cargo는 구성에서 환경 변수를 지원하지 않습니다.

이제부터 이 머신에서 Cargo를 호출하여 상자를 추가할 때마다 Cargo는 내부 Cargo-repo 리포지토리와 통신하기 위해 CodeArtifact로부터 인증 토큰을 받습니다. 사용하는 명령에 따라 패키지 읽기/게시 권한과 함께 get-authorization-token CodeArtifact API를 호출할 수 있는 IAM 권한이 있어야 합니다. 지속적 통합(CI) 파이프라인을 위해 빌드 머신에서 이 설정을 실행하는 경우, 빌드 머신에 적절한 권한이 있어야 합니다.

이제 이 설정을 테스트하고 로컬 프로젝트에 상자를 추가할 수 있습니다.

$ cargo add regex
    Updating `codeartifact` index
      Adding regex v1.10.4 to dependencies
             Features:
             + perf
             + perf-backtrack
             + perf-cache
             + perf-dfa
             + perf-inline
             + perf-literal
             + perf-onepass
             + std
             + unicode
             + unicode-age
             + unicode-bool
             + unicode-case
             + unicode-gencat
             + unicode-perl
             + unicode-script
             + unicode-segment
             - logging
             - pattern
             - perf-dfa-full
             - unstable
             - use_std
    Updating `cargo-repo` index

# 상자 다운로드를 트리거하도록 프로젝트 빌드하기
$ cargo build
  Downloaded memchr v2.7.2 (registry `cargo-repo`)
  Downloaded regex-syntax v0.8.3 (registry `cargo-repo`)
  Downloaded regex v1.10.4 (registry `cargo-repo`)
  Downloaded aho-corasick v1.1.3 (registry `cargo-repo`)
  Downloaded regex-automata v0.4.6 (registry `cargo-repo`)
  Downloaded 5 crates (1.5 MB) in 1.99s
   Compiling memchr v2.7.2 (registry `cargo-repo`)
   Compiling regex-syntax v0.8.3 (registry `cargo-repo`)
   Compiling aho-corasick v1.1.3 (registry `cargo-repo`)
   Compiling regex-automata v0.4.6 (registry `cargo-repo`)
   Compiling regex v1.10.4 (registry `cargo-repo`)
   Compiling hello_world v0.1.0 (/home/ec2-user/hello_world)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 16.60s

업스트림 퍼블릭 리포지토리에서 CodeArtifact가 상자와 해당 종속성을 다운로드한 것을 확인할 수 있습니다. CodeArtifact 콘솔에 연결하여 내가 만든 리포지토리에서 사용 가능한 패키지 목록을 확인합니다. 이 단계에서 패키지 목록은 두 리포지토리에서 동일해야 합니다.

CodeArtifact Cargo 패키지 목록

프라이빗 패키지를 리포지토리에 게시하기
이제 업스트림 링크가 의도한 대로 작동한다는 것을 알았으니, 조직의 다른 팀에서 사용할 수 있도록 프라이빗 패키지를 cargo-repo 리포지토리에 게시해 보겠습니다.

이를 위해 평소와 마찬가지로 표준 Rust 도구 Cargo를 사용합니다. 그 전에 프로젝트 파일을 git 리포지토리에 추가하고 커밋합니다.

$  git add . && git commit -m "initial commit"
 5 files changed, 1855 insertions(+)
create mode 100644 .gitignore
create mode 100644 Cargo.lock
create mode 100644 Cargo.toml
create mode 100644 commands.sh
create mode 100644 src/main.rs

$  cargo publish 
    Updating `codeartifact` index
   Packaging hello_world v0.1.0 (/home/ec2-user/hello_world)
    Updating crates.io index
    Updating `codeartifact` index
   Verifying hello_world v0.1.0 (/home/ec2-user/hello_world)
   Compiling libc v0.2.155
... (redacted for brevity) ....
   Compiling hello_world v0.1.0 (/home/ec2-user/hello_world/target/package/hello_world-0.1.0)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 1m 03s
    Packaged 5 files, 44.1KiB (11.5KiB compressed)
   Uploading hello_world v0.1.0 (/home/ec2-user/hello_world)
    Uploaded hello_world v0.1.0 to registry `cargo-repo`
note: waiting for `hello_world v0.1.0` to be available at registry `cargo-repo`.
You may press ctrl-c to skip waiting; the crate should be available shortly.
   Published hello_world v0.1.0 at registry `cargo-repo`

마지막으로 콘솔을 사용하여 hello_world 상자가 이제 cargo-repo에서 사용할 수 있는지 확인합니다.

CodeArtifact cargo 패키지 hello world

요금 및 가용성
이제 CodeArtifact를 사용할 수 있는 13개 AWS 리전에 Rust 라이브러리를 저장할 수 있습니다. Rust 패키지에는 추가 비용이 없습니다. 세 가지 청구 기준은 스토리지(월별 GB 단위), 요청 수, 인터넷 또는 다른 AWS 리전으로의 데이터 전송입니다. 동일한 리전의 AWS 서비스로의 데이터 전송에는 요금이 부과되지 않습니다. 예를 들어, CodeArtifact 데이터 전송 요금 부과 없이 Amazon Elastic Compute Cloud(Amazon EC2) 또는 AWS CodeBuild에서 지속적 통합 및 배포(CI/CD) 작업을 실행할 수 있습니다. 평소처럼 세부 정보는 요금 페이지에서 확인할 수 있습니다.

이제 Rust 애플리케이션을 구축하고 비공개 상자를 CodeArtifact에 업로드하세요!

– seb