What's
- Terraform AWS Providerが3.9.0からAWS CodeArtifactに対応した
- https://github.com/terraform-providers/terraform-provider-aws/releases/tag/v3.9.0
- 3.9.0でドメイン、リポジトリ、ドメインパーミッション
- 3.10.0でリポジトリパーミッションポリシー、認証トークン
- 3.11.0でエンドポイント
- と対応の幅も広がり中
というわけで、TerraformでAWS CodeArtifactを構築してみたいと思います。
以前に書いたこちらの内容を、Terraformで行ってみようかな、と。
AWS CodeArtifactの基本的な説明はこちらの記事にそこそこ書いたので、今回はそのあたりは簡単にしておきます。
AWS CodeArtifactとは?
AWSの提供する、マネージドなアーティファクトリポジトリサービスです。
現時点でサポートしているパッケージフォーマットは、npm、PyPI、Mavenです。
始め方
ざっくり言うと、
- AWS KMS CMKを作る(AWS管理のものでも可)
- ドメインを作る
- ドメイン内にリポジトリを作る
という感じです。
現時点(3.11.0)のTerraform AWS Providerでは、外部リポジトリへの接続はできません。
r/codeartifact_repository - support external connection #15569
前回の記事に加えて、Maven Centralへの接続も試そうかと思ったのですが、今回は諦めました…。
リポジトリを構築してみる
では、リポジトリを構築してみましょう。今回の環境は、こちらです。
$ terraform version
Terraform v0.13.4
+ provider registry.terraform.io/hashicorp/aws v3.11.0
$ aws --version
aws-cli/2.0.58 Python/3.7.3 Linux/5.4.0-52-generic exe/x86_64.ubuntu.20
AWSのクレデンシャルは、環境変数で設定しているものとします。
$ export AWS_ACCESS_KEY_ID=.....
$ export AWS_SECRET_ACCESS_KEY=.....
$ export AWS_DEFAULT_REGION=.....
リソース定義。
main.tf
terraform {
required_version = "0.13.4"
required_providers {
aws = {
version = "3.11.0"
source = "hashicorp/aws"
}
}
}
provider "aws" {}
resource "aws_kms_key" "codeartifact_key" {
description = "CMK for My CodeArtifact Domain"
deletion_window_in_days = 7
}
resource "aws_kms_alias" "codeartifact_key" {
name = "alias/my-codeartifact-key"
target_key_id = aws_kms_key.codeartifact_key.key_id
}
resource "aws_codeartifact_domain" "domain" {
domain = "my-domain"
encryption_key = aws_kms_alias.codeartifact_key.arn
}
resource "aws_codeartifact_repository" "my_repository" {
repository = "my-repo"
domain = aws_codeartifact_domain.domain.domain
}
AWS KMS CMK。エイリアスも、なんとなく作っておきました。
resource "aws_kms_key" "codeartifact_key" {
description = "CMK for My CodeArtifact Domain"
deletion_window_in_days = 7
}
resource "aws_kms_alias" "codeartifact_key" {
name = "alias/my-codeartifact-key"
target_key_id = aws_kms_key.codeartifact_key.key_id
}
AWS CodeArtifactのドメインとリポジトリ。ドメイン内に、リポジトリが含まれる形になります。
Resource: aws_codeartifact_domain
Resource: aws_codeartifact_repository
resource "aws_codeartifact_domain" "domain" {
domain = "my-domain"
encryption_key = aws_kms_alias.codeartifact_key.arn
}
resource "aws_codeartifact_repository" "my_repository" {
repository = "my-repo"
domain = aws_codeartifact_domain.domain.domain
}
CMKは、ドメインに対して設定します。
権限まわりの設定も可能なようですが、今回はいったんパス。
Resource: aws_codeartifact_domain_permissions_policy
Resource: aws_codeartifact_repository_permissions_policy
では、apply
してみます。
$ terraform init
$ terraform apply
確認してみましょう。
$ aws codeartifact describe-domain --domain my-domain
{
"domain": {
"name": "my-domain",
"owner": "[AWSアカウントID]",
"arn": "arn:aws:codeartifact:ap-northeast-1:[AWSアカウントID]:domain/my-domain",
"status": "Active",
"createdTime": "2020-10-21T17:04:12.372000+09:00",
"encryptionKey": "arn:aws:kms:ap-northeast-1:[AWSアカウントID]:key/fa1a0cf2-5534-467e-bd56-f034a3318d3c",
"repositoryCount": 1,
"assetSizeBytes": 0
}
}
$ aws codeartifact describe-repository --domain my-domain --repository my-repo
{
"repository": {
"name": "my-repo",
"administratorAccount": "[AWSアカウントID]",
"domainName": "my-domain",
"domainOwner": "[AWSアカウントID]",
"arn": "arn:aws:codeartifact:ap-northeast-1:[AWSアカウントID]:repository/my-domain/my-repo",
"upstreams": [],
"externalConnections": []
}
}
OKですね。とても簡単にできました。
Mavenから使う
最後に、Apache Mavenから使ってみましょう。
内容は、前回の記事と同様に
- ライブラリを作って、AWS CodeArtifactリポジトリにアップロード
- ライブラリを使うアプリケーションを作って、依存ライブラリをAWS CodeArtifactリポジトリからダウンロード
という感じでやってみます。
環境については、こちら。
$ java --version
openjdk 11.0.8 2020-07-14
OpenJDK Runtime Environment (build 11.0.8+10-post-Ubuntu-0ubuntu120.04)
OpenJDK 64-Bit Server VM (build 11.0.8+10-post-Ubuntu-0ubuntu120.04, mixed mode, sharing)
$ mvn --version
Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f)
Maven home: $HOME/.sdkman/candidates/maven/current
Java version: 11.0.8, vendor: Ubuntu, runtime: /usr/lib/jvm/java-11-openjdk-amd64
Default locale: ja_JP, platform encoding: UTF-8
OS name: "linux", version: "5.4.0-52-generic", arch: "amd64", family: "unix"
ライブラリ側
まずは、ライブラリを作ります。
AWS CodeArtifactリポジトリへのアップロードが必要になるので、ドキュメントに従いsettings.xml
を作成しましょう。
settings.xml
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
https://maven.apache.org/xsd/settings-1.0.0.xsd">
<servers>
<server>
<id>codeartifact</id>
<username>aws</username>
<password>${env.CODEARTIFACT_TOKEN}</password>
</server>
</servers>
</settings>
次に、認証トークンを取得します。
$ export CODEARTIFACT_TOKEN=`aws codeartifact get-authorization-token --domain my-domain --query authorizationToken --output text`
認証トークンはTerraformでも取得可能なようですが、環境変数に設定しなくてはいけないので、ここはAWS CLIでよいでしょう。
参考までに、Terraformで扱う場合はこちらですね。
Data Source: aws_codeartifact_authorization_token
認証トークンの有効期限は、12時間です。
AWS CodeArtifact authentication and tokens
アーティファクトをリポジトリにアップロードする
ここまで揃ったら、ライブラリを作成してアーティファクトをAWS CodeArtifactリポジトリにアップロードします。
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.github.charon.r13b</groupId>
<artifactId>library</artifactId>
<version>0.0.1</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<repositories>
<repository>
<id>codeartifact</id>
<name>codeartifact</name>
<url>https://my-domain-[AWSアカウントID].d.codeartifact.ap-northeast-1.amazonaws.com/maven/my-repo/</url>
</repository>
</repositories>
<distributionManagement>
<repository>
<id>codeartifact</id>
<name>codeartifact</name>
<url>https://my-domain-[AWSアカウントID].d.codeartifact.ap-northeast-1.amazonaws.com/maven/my-repo</url>
</repository>
</distributionManagement>
<dependencies>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.11</version>
</dependency>
</dependencies>
</project>
今回の使い方だと、少なくともdistributionManagement
にリポジトリ指定があればOKです。
一応、Maven Centralから取得するライブラリも含めています。
ソースコード。
src/main/java/com/github/charon/r13b/library/MessageService.java
package com.github.charon.r13b.library;
import org.apache.commons.lang3.StringUtils;
public class MessageService {
String prefix;
String suffix;
public MessageService(String prefix, String suffix) {
this.prefix = prefix;
this.suffix = suffix;
}
public String decorate(String word) {
return StringUtils.join(prefix, word, suffix);
}
}
ビルドして、アップロードしてみます。
$ mvn deploy -s settings.xml
OKです。
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 9.789 s
[INFO] Finished at: 2020-10-21T17:32:55+09:00
[INFO] ------------------------------------------------------------------------
呼び出し側を作る
アップロードされたアーティファクトを使用する、アプリケーションを作成します。
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.github.charon.r13b</groupId>
<artifactId>app</artifactId>
<version>0.0.1</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<repositories>
<repository>
<id>codeartifact</id>
<name>codeartifact</name>
<url>https://my-domain-[AWSアカウントID].d.codeartifact.ap-northeast-1.amazonaws.com/maven/my-repo/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>com.github.charon.r13b</groupId>
<artifactId>library</artifactId>
<version>0.0.1</version>
</dependency>
</dependencies>
</project>
こちらは、repositories / repository
に、構築したAWS CodeArtifactリポジトリを指定すればOKです。
なお、リポジトリの利用にも認証トークンは必要となります。
アプリケーションのソースコード。
src/main/java/com/github/charon/r13b/app/App.java
package com.github.charon.r13b.app;
import com.github.charon.r13b.library.MessageService;
public class App {
public static void main(String... args) {
MessageService messageService = new MessageService("★★★", "★★★");
System.out.println(messageService.decorate("Hello World!!"));
}
}
実行。-s
で指定しているのは、アーティファクトをアップロードした時に使ったものと同じ、AWS CodeArtifactへの認証情報を書いたものです。
mvn compile exec:java -s settings.xml -Dexec.mainClass=com.github.charon.r13b.app.App
結果。
[INFO] --- exec-maven-plugin:1.6.0:java (default-cli) @ app ---
★★★Hello World!!★★★
OKですね。
これで確認完了です。
最後に、リソースを破棄しておしましです。
$ terraform destroy