README.md
  1  # cdk-assets
  2  <!--BEGIN STABILITY BANNER-->
  3  
  4  ---
  5  
  6  ![cdk-constructs: Experimental](https://img.shields.io/badge/cdk--constructs-experimental-important.svg?style=for-the-badge)
  7  
  8  > The APIs of higher level constructs in this module are experimental and under active development.
  9  > They are subject to non-backward compatible changes or removal in any future version. These are
 10  > not subject to the [Semantic Versioning](https://semver.org/) model and breaking changes will be
 11  > announced in the release notes. This means that while you may use them, you may need to update
 12  > your source code when upgrading to a newer version of this package.
 13  
 14  ---
 15  
 16  <!--END STABILITY BANNER-->
 17  
 18  A tool for publishing CDK assets to AWS environments.
 19  
 20  ## Overview
 21  
 22  `cdk-assets` requires an asset manifest file called `assets.json`, in a CDK
 23  CloudAssembly (`cdk.out/assets.json`). It will take the assets listed in the
 24  manifest, prepare them as required and upload them to the locations indicated in
 25  the manifest.
 26  
 27  Currently the following asset types are supported:
 28  
 29  * Files and archives, uploaded to S3
 30  * Docker Images, uploaded to ECR
 31  * Files, archives, and Docker images built by external utilities
 32  
 33  S3 buckets and ECR repositories to upload to are expected to exist already.
 34  
 35  We expect assets to be immutable, and we expect that immutability to be
 36  reflected both in the asset ID and in the destination location. This reflects
 37  itself in the following behaviors:
 38  
 39  * If the indicated asset already exists in the given destination location, it
 40    will not be packaged and uploaded.
 41  * If some locally cached artifact (depending on the asset type a file or an
 42    image in the local Docker cache) already exists named after the asset's ID, it
 43    will not be packaged, but will be uploaded directly to the destination
 44    location.
 45  
 46  For assets build by external utilities, the contract is such that cdk-assets
 47  expects the utility to manage dedupe detection as well as path/image tag generation.
 48  This means that cdk-assets will call the external utility every time generation
 49  is warranted, and it is up to the utility to a) determine whether to do a
 50  full rebuild; and b) to return only one thing on stdout: the path to the file/archive
 51  asset, or the name of the local Docker image.
 52  
 53  ## Usage
 54  
 55  The `cdk-asset` tool can be used programmatically and via the CLI. Use
 56  programmatic access if you need more control over authentication than the
 57  default [`aws-sdk`](https://github.com/aws/aws-sdk-js) implementation allows.
 58  
 59  Command-line use looks like this:
 60  
 61  ```console
 62  $ cdk-assets /path/to/cdk.out [ASSET:DEST] [ASSET] [:DEST] [...]
 63  ```
 64  
 65  Credentials will be taken from the `AWS_ACCESS_KEY...` environment variables
 66  or the `default` profile (or another profile if `AWS_PROFILE` is set).
 67  
 68  A subset of the assets and destinations can be uploaded by specifying their
 69  asset IDs or destination IDs.
 70  
 71  ## Manifest Example
 72  
 73  An asset manifest looks like this:
 74  
 75  ```json
 76  {
 77    "version": "1.22.0",
 78    "files": {
 79      "7aac5b80b050e7e4e168f84feffa5893": {
 80        "source": {
 81          "path": "some_directory",
 82          "packaging": "zip"
 83        },
 84        "destinations": {
 85          "us-east-1": {
 86            "region": "us-east-1",
 87            "assumeRoleArn": "arn:aws:iam::12345789012:role/my-account",
 88            "bucketName": "MyBucket",
 89            "objectKey": "7aac5b80b050e7e4e168f84feffa5893.zip"
 90          }
 91        }
 92      },
 93      "3dfe2b80b050e7e4e168f84feff678d4": {
 94        "source": {
 95          "executable": ["myzip"]
 96        },
 97        "destinations": {
 98          "us-east-1": {
 99            "region": "us-east-1",
100            "assumeRoleArn": "arn:aws:iam::12345789012:role/my-account",
101            "bucketName": "MySpecialBucket",
102            "objectKey": "3dfe2b80b050e7e4e168f84feff678d4.zip"
103          }
104        }
105      },
106    },
107    "dockerImages": {
108      "b48783c58a86f7b8c68a4591c4f9be31": {
109        "source": {
110          "directory": "dockerdir",
111        },
112        "destinations": {
113          "us-east-1": {
114            "region": "us-east-1",
115            "assumeRoleArn": "arn:aws:iam::12345789012:role/my-account",
116            "repositoryName": "MyRepository",
117            "imageTag": "b48783c58a86f7b8c68a4591c4f9be31",
118            "imageUri": "123456789012.dkr.ecr.us-east-1.amazonaws.com/MyRepository:1234567891b48783c58a86f7b8c68a4591c4f9be31",
119          }
120        }
121      },
122      "d92753c58a86f7b8c68a4591c4f9cf28": {
123        "source": {
124          "executable": ["mytool", "package", "dockerdir"],
125        },
126        "destinations": {
127          "us-east-1": {
128            "region": "us-east-1",
129            "assumeRoleArn": "arn:aws:iam::12345789012:role/my-account",
130            "repositoryName": "MyRepository2",
131            "imageTag": "d92753c58a86f7b8c68a4591c4f9cf28",
132            "imageUri": "123456789987.dkr.ecr.us-east-1.amazonaws.com/MyRepository2:1234567891b48783c58a86f7b8c68a4591c4f9be31",
133          }
134        }
135      }
136    }
137  }
138  ```
139  
140  ### Placeholders
141  
142  The `destination` block of an asset manifest may contain the following region
143  and account placeholders:
144  
145  * `${AWS::Region}`
146  * `${AWS::AccountId}`
147  
148  These will be substituted with the region and account IDs currently configured
149  on the AWS SDK (through environment variables or `~/.aws/...` config files).
150  
151  * The `${AWS::AccountId}` placeholder will *not* be re-evaluated after
152    performing the `AssumeRole` call.
153  * If `${AWS::Region}` is used, it will principally be replaced with the value
154    in the `region` key. If the default region is intended, leave the `region`
155    key out of the manifest at all.
156  
157  ## Docker image credentials
158  
159  For Docker image asset publishing, `cdk-assets` will `docker login` with
160  credentials from ECR GetAuthorizationToken prior to building and publishing, so
161  that the Dockerfile can reference images in the account's ECR repo.
162  
163  `cdk-assets` can also be configured to read credentials from both ECR and
164  SecretsManager prior to build by creating a credential configuration at
165  '~/.cdk/cdk-docker-creds.json' (override this location by setting the
166  CDK_DOCKER_CREDS_FILE environment variable). The credentials file has the
167  following format:
168  
169  ```json
170  {
171    "version": "1.0",
172    "domainCredentials": {
173      "domain1.example.com": {
174        "secretsManagerSecretId": "mySecret", // Can be the secret ID or full ARN
175        "roleArn": "arn:aws:iam::0123456789012:role/my-role" // (Optional) role with permissions to the secret
176      },
177      "domain2.example.com": {
178        "ecrRepository": true,
179        "roleArn": "arn:aws:iam::0123456789012:role/my-role" // (Optional) role with permissions to the repo
180      }
181    }
182  }
183  ```
184  
185  If the credentials file is present, `docker` will be configured to use the
186  `docker-credential-cdk-assets` credential helper for each of the domains listed
187  in the file. This helper will assume the role provided (if present), and then fetch
188  the login credentials from either SecretsManager or ECR.