Skip to content

Commit

Permalink
Merge pull request #442 from fujiwara/layer_arn-func
Browse files Browse the repository at this point in the history
Add layer_arn function.
  • Loading branch information
fujiwara authored Jan 7, 2025
2 parents 0271603 + b04447b commit f8f8154
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 0 deletions.
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,31 @@ The `caller_identity` function returns an object containing the following fields

This object is the same as the result of [GetCallerIdentity](https://docs.aws.amazon.com/STS/latest/APIReference/API_GetCallerIdentity.html) API.

#### Resolve Lambda layer ARN

The `layer_arn` template/Jsonnet function resolves the Lambda layer ARN.

```json
{
"Layers": [
"{{ layer_arn `my-layer` `latest` }}"
]
}
```

```jsonnet
local layer_arn = std.native('layer_arn');
{
Layers: [
layer_arn('my-layer', 'latest'),
],
}
```

The `layer_arn` function takes two string arguments: `LayerName` and `Version`.
- `LayerName` is the name of the Lambda layer.
- `Version` is the version of the Lambda layer. If `Version` is empty or `latest`, the latest version is used. Otherwise, the specified version is used.

#### Lookup resource attributes in tfstate ([Terraform state](https://www.terraform.io/docs/state/index.html))

When `--tfstate` option set to an URL to `terraform.tfstate`, tfstate template function enabled.
Expand Down
6 changes: 6 additions & 0 deletions lambroll.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,10 +191,16 @@ func New(ctx context.Context, opt *Option) (*App, error) {
loader.Funcs(prefixedFuncs)
}

// load caller identity functions
callerIdentity := newCallerIdentity(v2cfg)
nativeFuncs = append(nativeFuncs, callerIdentity.JsonnetNativeFuncs(ctx)...)
loader.Funcs(callerIdentity.FuncMap(ctx))

// load layer functions
layerArnResolver := newLayerArnResolver(v2cfg)
nativeFuncs = append(nativeFuncs, layerArnResolver.JsonnetNativeFuncs(ctx)...)
loader.Funcs(layerArnResolver.FuncMap(ctx))

app := &App{
callerIdentity: callerIdentity,
profile: profile,
Expand Down
84 changes: 84 additions & 0 deletions layer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package lambroll

import (
"context"
"fmt"
"strconv"
"text/template"

"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/lambda"
"github.com/google/go-jsonnet"
"github.com/google/go-jsonnet/ast"
)

type LayerArnResolver struct {
svc *lambda.Client
}

func newLayerArnResolver(cfg aws.Config) *LayerArnResolver {
return &LayerArnResolver{
svc: lambda.NewFromConfig(cfg),
}
}

func (r *LayerArnResolver) resolve(ctx context.Context, name, version string) (string, error) {
switch version {
case "latest", "":
out, err := r.svc.ListLayerVersions(ctx, &lambda.ListLayerVersionsInput{
LayerName: &name,
MaxItems: aws.Int32(1),
})
if err != nil {
return "", fmt.Errorf("failed to list layer versions: %w", err)
}
if len(out.LayerVersions) == 0 {
return "", fmt.Errorf("layer_arn: layer %s not found", name)
}
return *out.LayerVersions[0].LayerVersionArn, nil
default:
v, err := strconv.ParseInt(version, 10, 64)
if err != nil {
return "", fmt.Errorf("layer_arn: version must be a string of number or 'latest'")
}
out, err := r.svc.GetLayerVersion(ctx, &lambda.GetLayerVersionInput{
LayerName: &name,
VersionNumber: &v,
})
if err != nil {
return "", fmt.Errorf("failed to get layer version %s:%s %w", name, version, err)
}
return *out.LayerVersionArn, nil
}
}

func (r *LayerArnResolver) JsonnetNativeFuncs(ctx context.Context) []*jsonnet.NativeFunction {
return []*jsonnet.NativeFunction{
{
Name: "layer_arn",
Params: []ast.Identifier{"name", "version"},
Func: func(params []any) (any, error) {
if len(params) != 2 {
return nil, fmt.Errorf("layer_arn: invalid number of arguments")
}
name, ok := params[0].(string)
if !ok {
return nil, fmt.Errorf("layer_arn: name must be a string")
}
version, ok := params[1].(string)
if !ok {
return nil, fmt.Errorf("layer_arn: version must be a string")
}
return r.resolve(ctx, name, version)
},
},
}
}

func (r *LayerArnResolver) FuncMap(ctx context.Context) template.FuncMap {
return template.FuncMap{
"layer_arn": func(name, version string) (string, error) {
return r.resolve(ctx, name, version)
},
}
}

0 comments on commit f8f8154

Please sign in to comment.