Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cherry-pick #23344 to 7.x: Provide more ways to set AWS credentials in Functionbeat #23386

Merged
merged 1 commit into from
Jan 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.next.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -646,6 +646,7 @@ port. {pull}19209[19209]

*Functionbeat*

- Provide more ways to set AWS credentials. {issue}12464[12464] {pull}23344[23344]

*Winlogbeat*

Expand Down
12 changes: 12 additions & 0 deletions x-pack/functionbeat/_meta/config/beat.reference.yml.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,18 @@ functionbeat.provider.aws.endpoint: "s3.amazonaws.com"
# Configure which S3 bucket we should upload the lambda artifact.
functionbeat.provider.aws.deploy_bucket: "functionbeat-deploy"

# Configure credentials of Functionbeat while deploying to AWS.
# Available options:
# * access_key_id, secret_access_key and/or session_token
#functionbeat.provider.aws.access_key_id: '${AWS_ACCESS_KEY_ID:""}'
#functionbeat.provider.aws.secret_access_key: '${AWS_SECRET_ACCESS_KEY:""}'
#functionbeat.provider.aws.session_token: '${AWS_SESSION_TOKEN:""}'
# * role_arn
#functionbeat.provider.aws.role_arn: arn:aws:iam::123456789012:role/test-fnb
# * credential_profile_name and/or shared_credential_file
#functionbeat.provider.aws.credential_profile_name: fnb-aws
#functionbeat.provider.aws.shared_credential_file: /etc/functionbeat/aws_credentials

functionbeat.provider.aws.functions:
# Define the list of function availables, each function required to have a unique name.
# Create a function that accepts events coming from cloudwatchlogs.
Expand Down
17 changes: 11 additions & 6 deletions x-pack/functionbeat/docs/config-options-aws.asciidoc
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
[id="configuration-{beatname_lc}-options"]
[role="xpack"]

:libbeat-xpack-dir: ../../../x-pack/libbeat

== Configure AWS functions

++++
Expand All @@ -15,6 +18,11 @@ You configure the functions in the the +{beatname_lc}.yml+ configuration file.
When you're done, you can <<deploy-to-cloud-provider,deploy the functions>>
to your serverless environment.

The `aws` functions require AWS credentials configuration in order to make AWS API calls.
Users can either use `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY` and/or
`AWS_SESSION_TOKEN`, or use shared AWS credentials file.
Please see <<aws-credentials-config,AWS credentials options>> for more details.

The following example configures two functions: `cloudwatch` and `sqs`. The
`cloudwatch` function collects events from CloudWatch Logs. The `sqs` function
collects messages from Amazon Simple Queue Service (SQS). Both functions forward
Expand Down Expand Up @@ -56,12 +64,6 @@ to deploy.
TIP: If you change the configuration after deploying the function, use
the <<update-command,`update` command>> to update your deployment.

[float]
[id="{beatname_lc}-endpoint"]
==== `provider.aws.endpoint`

AWS endpoint to use in the URL template to load functions.

[float]
[id="{beatname_lc}-deploy-bucket"]
==== `provider.aws.deploy_bucket`
Expand Down Expand Up @@ -212,3 +214,6 @@ version and the event timestamp; for access to dynamic fields, use

Example value: `"%{[agent.name]}-myindex-%{+yyyy.MM.dd}"` might
expand to `"functionbeat-myindex-2019.12.13"`.

[id="aws-credentials-config"]
include::{libbeat-xpack-dir}/docs/aws-credentials-config.asciidoc[]
12 changes: 12 additions & 0 deletions x-pack/functionbeat/functionbeat.reference.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,18 @@ functionbeat.provider.aws.endpoint: "s3.amazonaws.com"
# Configure which S3 bucket we should upload the lambda artifact.
functionbeat.provider.aws.deploy_bucket: "functionbeat-deploy"

# Configure credentials of Functionbeat while deploying to AWS.
# Available options:
# * access_key_id, secret_access_key and/or session_token
#functionbeat.provider.aws.access_key_id: '${AWS_ACCESS_KEY_ID:""}'
#functionbeat.provider.aws.secret_access_key: '${AWS_SECRET_ACCESS_KEY:""}'
#functionbeat.provider.aws.session_token: '${AWS_SESSION_TOKEN:""}'
# * role_arn
#functionbeat.provider.aws.role_arn: arn:aws:iam::123456789012:role/test-fnb
# * credential_profile_name and/or shared_credential_file
#functionbeat.provider.aws.credential_profile_name: fnb-aws
#functionbeat.provider.aws.shared_credential_file: /etc/functionbeat/aws_credentials

functionbeat.provider.aws.functions:
# Define the list of function availables, each function required to have a unique name.
# Create a function that accepts events coming from cloudwatchlogs.
Expand Down
24 changes: 17 additions & 7 deletions x-pack/functionbeat/manager/aws/cli_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
"strings"

"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/aws/external"
cf "github.com/aws/aws-sdk-go-v2/service/cloudformation"
"github.com/awslabs/goformation/v4/cloudformation"
"github.com/awslabs/goformation/v4/cloudformation/iam"
Expand All @@ -24,6 +23,7 @@ import (
"github.com/elastic/beats/v7/x-pack/functionbeat/manager/core"
"github.com/elastic/beats/v7/x-pack/functionbeat/manager/executor"
fnaws "github.com/elastic/beats/v7/x-pack/functionbeat/provider/aws/aws"
awscommon "github.com/elastic/beats/v7/x-pack/libbeat/common/aws"
)

const (
Expand Down Expand Up @@ -67,6 +67,12 @@ func (c *CLIManager) deployTemplate(update bool, name string) error {
}

c.log.Debugf("Using cloudformation template:\n%s", templateData.json)

_, err = c.awsCfg.Credentials.Retrieve()
if err != nil {
return fmt.Errorf("failed to retrieve aws credentials, please check AWS credential in config: %+v", err)
}

svcCF := cf.New(c.awsCfg)

executer := executor.NewExecutor(c.log)
Expand Down Expand Up @@ -144,6 +150,11 @@ func (c *CLIManager) Remove(name string) error {
c.log.Debugf("Removing function: %s", name)
defer c.log.Debugf("Removal of function '%s' complete", name)

_, err := c.awsCfg.Credentials.Retrieve()
if err != nil {
return fmt.Errorf("failed to retrieve aws credentials, please check AWS credential in config: %+v", err)
}

svc := cf.New(c.awsCfg)
executer := executor.NewExecutor(c.log)
executer.Add(newOpDeleteCloudFormation(c.log, svc, c.stackName(name)))
Expand Down Expand Up @@ -199,15 +210,14 @@ func NewCLI(
cfg *common.Config,
provider provider.Provider,
) (provider.CLIManager, error) {
awsCfg, err := external.LoadDefaultAWSConfig()
if err != nil {
return nil, err
}

config := &fnaws.Config{}
config := fnaws.DefaultConfig()
if err := cfg.Unpack(config); err != nil {
return nil, err
}
awsCfg, err := awscommon.GetAWSCredentials(config.Credentials)
if err != nil {
return nil, fmt.Errorf("failed to get aws credentials, please check AWS credential in config: %+v", err)
}

builder, err := provider.TemplateBuilder()
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion x-pack/functionbeat/manager/aws/template_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ func NewTemplateBuilder(log *logp.Logger, cfg *common.Config, p provider.Provide
return &defaultTemplateBuilder{
provider: p,
log: log,
endpoint: config.Endpoint,
endpoint: config.Credentials.Endpoint,
bucket: string(config.DeployBucket),
}, nil
}
Expand Down
20 changes: 18 additions & 2 deletions x-pack/functionbeat/provider/aws/aws/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,28 @@ import (
"github.com/dustin/go-humanize"

"github.com/elastic/beats/v7/libbeat/common/cfgwarn"
awscommon "github.com/elastic/beats/v7/x-pack/libbeat/common/aws"
)

// Config expose the configuration option the AWS provider.
type Config struct {
Endpoint string `config:"endpoint" validate:"nonzero,required"`
DeployBucket bucket `config:"deploy_bucket" validate:"nonzero,required"`
DeployBucket bucket `config:"deploy_bucket" validate:"nonzero,required"`
Credentials awscommon.ConfigAWS `config:",inline"`
}

func DefaultConfig() *Config {
return &Config{
Credentials: awscommon.ConfigAWS{
Endpoint: "s3.amazonaws.com",
},
}
}

func (c *Config) Validate() error {
if c.Credentials.Endpoint == "" {
return fmt.Errorf("functionbeat.providers.aws.enpoint cannot be empty")
}
return nil
}

// maxMegabytes maximums memory that a lambda can use.
Expand Down
18 changes: 16 additions & 2 deletions x-pack/libbeat/docs/aws-credentials-config.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,26 @@ given, the default profile will be used.
`shared_credential_file` is optional to specify the directory of your shared
credentials file. If it's empty, the default directory will be used.
In Windows, shared credentials file is at `C:\Users\<yourUserName>\.aws\credentials`.
For Linux, macOS or Unix, the file is located at `~/.aws/credentials`. When running as a service,
For Linux, macOS or Unix, the file is located at `~/.aws/credentials`. When running as a service,
the home path depends on the user that manages the service, so the `shared_credential_file` parameter can be used to avoid ambiguity. Please see
https://docs.aws.amazon.com/ses/latest/DeveloperGuide/create-shared-credentials-file.html[Create Shared Credentials File]
for more details.

include::../../../{beatname_lc}/docs/aws-credentials-examples.asciidoc[]
ifeval::["{beatname_lc}"=="filebeat"]
include::../../../filebeat/docs/aws-credentials-examples.asciidoc[]
endif::[]

ifeval::["{beatname_lc}"=="heartbeat"]
include::../../../heartbeat/docs/aws-credentials-examples.asciidoc[]
endif::[]

ifeval::["{beatname_lc}"=="metricbeat"]
include::../../../metricbeat/docs/aws-credentials-examples.asciidoc[]
endif::[]

ifeval::["{beatname_lc}"=="functionbeat"]
include::../../../filebeat/docs/aws-credentials-examples.asciidoc[]
endif::[]

[float]
==== AWS Credentials Types
Expand Down