Help us understand the problem. What is going on with this article?

AWS CodeArtifactをTerraformで構築する(+Mavenから利用)

What's

というわけで、TerraformでAWS CodeArtifactを構築してみたいと思います。

以前に書いたこちらの内容を、Terraformで行ってみようかな、と。

AWS CodeArtifactをMavenから使ってみる

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から使ってみましょう。

Using CodeArtifact with 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
charon
"CROSS THE RUBICON”
https://github.com/charon-r13b
tis
創業40年超のSIerです。
https://www.tis.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away