mirror of https://github.com/docker/compose.git
Create CloudWatch LogGroup and IAM TaskExecutionRole
As part of the CloudFormation template, create a LogGroup and configure task with awslogs log-driver. Also create a dedicated IAM Role, with AmazonECSTaskExecutionRolePolicy. This one will later be fine-tuned to grant access to secrets/config and other AWS resources according to custom extensions close #42 Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
This commit is contained in:
parent
99b4ed0bfd
commit
3e30f2cd1a
|
@ -6,15 +6,17 @@ import (
|
|||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/compose-spec/compose-go/types"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/awslabs/goformation/v4/cloudformation/logs"
|
||||
|
||||
ecsapi "github.com/aws/aws-sdk-go/service/ecs"
|
||||
"github.com/awslabs/goformation/v4/cloudformation"
|
||||
"github.com/awslabs/goformation/v4/cloudformation/ec2"
|
||||
"github.com/awslabs/goformation/v4/cloudformation/ecs"
|
||||
"github.com/awslabs/goformation/v4/cloudformation/iam"
|
||||
"github.com/compose-spec/compose-go/types"
|
||||
"github.com/docker/ecs-plugin/pkg/compose"
|
||||
"github.com/docker/ecs-plugin/pkg/convert"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func (c client) Convert(ctx context.Context, project *compose.Project) (*cloudformation.Template, error) {
|
||||
|
@ -50,22 +52,32 @@ func (c client) Convert(ctx context.Context, project *compose.Project) (*cloudfo
|
|||
VpcId: vpc,
|
||||
}
|
||||
|
||||
logGroup := fmt.Sprintf("/docker-compose/%s", project.Name)
|
||||
template.Resources["LogGroup"] = &logs.LogGroup{
|
||||
LogGroupName: logGroup,
|
||||
}
|
||||
|
||||
for _, service := range project.Services {
|
||||
definition, err := convert.Convert(project, service)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
role, err := c.GetEcsTaskExecutionRole(ctx, service)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
taskExecutionRole := fmt.Sprintf("%sTaskExecutionRole", service.Name)
|
||||
template.Resources[taskExecutionRole] = &iam.Role{
|
||||
AssumeRolePolicyDocument: assumeRolePolicyDocument,
|
||||
// Here we can grant access to secrets/configs using a Policy { Allow,ssm:GetParameters,secret|config ARN}
|
||||
ManagedPolicyArns: []string{
|
||||
ECSTaskExecutionPolicy,
|
||||
},
|
||||
}
|
||||
definition.TaskRoleArn = role
|
||||
definition.ExecutionRoleArn = cloudformation.Ref(taskExecutionRole)
|
||||
// FIXME definition.TaskRoleArn = ?
|
||||
|
||||
taskDefinition := fmt.Sprintf("%sTaskDefinition", service.Name)
|
||||
template.Resources[taskDefinition] = definition
|
||||
|
||||
template.Resources[service.Name] = &ecs.Service{
|
||||
template.Resources[fmt.Sprintf("%sService", service.Name)] = &ecs.Service{
|
||||
Cluster: c.Cluster,
|
||||
DesiredCount: 1,
|
||||
LaunchType: ecsapi.LaunchTypeFargate,
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
package amazon
|
||||
|
||||
var assumeRolePolicyDocument = PolicyDocument{
|
||||
Version: "2012-10-17", // https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_version.html
|
||||
Statement: []PolicyStatement{
|
||||
{
|
||||
Effect: "Allow",
|
||||
Principal: PolicyPrincipal{
|
||||
Service: "ecs-tasks.amazonaws.com",
|
||||
},
|
||||
Action: []string{"sts:AssumeRole"},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// could alternatively depend on https://github.com/kubernetes-sigs/cluster-api-provider-aws/blob/master/pkg/cloud/services/iam/types.go#L52
|
||||
type PolicyDocument struct {
|
||||
Version string `json:",omitempty"`
|
||||
Statement []PolicyStatement `json:",omitempty"`
|
||||
}
|
||||
|
||||
type PolicyStatement struct {
|
||||
Effect string `json:",omitempty"`
|
||||
Action []string `json:",omitempty"`
|
||||
Principal PolicyPrincipal `json:",omitempty"`
|
||||
Resource []string `json:",omitempty"`
|
||||
}
|
||||
|
||||
type PolicyPrincipal struct {
|
||||
Service string `json:",omitempty"`
|
||||
}
|
|
@ -180,6 +180,9 @@ func (s sdk) CreateStack(ctx context.Context, name string, template *cf.Template
|
|||
StackName: aws.String(name),
|
||||
TemplateBody: aws.String(string(json)),
|
||||
TimeoutInMinutes: aws.Int64(10),
|
||||
Capabilities: []*string{
|
||||
aws.String(cloudformation.CapabilityCapabilityIam),
|
||||
},
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"time"
|
||||
|
||||
ecsapi "github.com/aws/aws-sdk-go/service/ecs"
|
||||
"github.com/awslabs/goformation/v4/cloudformation"
|
||||
"github.com/awslabs/goformation/v4/cloudformation/ecs"
|
||||
"github.com/compose-spec/compose-go/types"
|
||||
"github.com/docker/cli/opts"
|
||||
|
@ -21,24 +22,32 @@ func Convert(project *compose.Project, service types.ServiceConfig) (*ecs.TaskDe
|
|||
ContainerDefinitions: []ecs.TaskDefinition_ContainerDefinition{
|
||||
// Here we can declare sidecars and init-containers using https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html#container_definition_dependson
|
||||
{
|
||||
Command: service.Command,
|
||||
Cpu: 256,
|
||||
DisableNetworking: service.NetworkMode == "none",
|
||||
DnsSearchDomains: service.DNSSearch,
|
||||
DnsServers: service.DNS,
|
||||
DockerLabels: nil,
|
||||
DockerSecurityOptions: service.SecurityOpt,
|
||||
EntryPoint: service.Entrypoint,
|
||||
Environment: toKeyValuePair(service.Environment),
|
||||
Essential: true,
|
||||
ExtraHosts: toHostEntryPtr(service.ExtraHosts),
|
||||
FirelensConfiguration: nil,
|
||||
HealthCheck: toHealthCheck(service.HealthCheck),
|
||||
Hostname: service.Hostname,
|
||||
Image: service.Image,
|
||||
Interactive: false,
|
||||
Links: nil,
|
||||
LinuxParameters: toLinuxParameters(service),
|
||||
Command: service.Command,
|
||||
Cpu: 256,
|
||||
DisableNetworking: service.NetworkMode == "none",
|
||||
DnsSearchDomains: service.DNSSearch,
|
||||
DnsServers: service.DNS,
|
||||
DockerLabels: nil,
|
||||
DockerSecurityOptions: service.SecurityOpt,
|
||||
EntryPoint: service.Entrypoint,
|
||||
Environment: toKeyValuePair(service.Environment),
|
||||
Essential: true,
|
||||
ExtraHosts: toHostEntryPtr(service.ExtraHosts),
|
||||
FirelensConfiguration: nil,
|
||||
HealthCheck: toHealthCheck(service.HealthCheck),
|
||||
Hostname: service.Hostname,
|
||||
Image: service.Image,
|
||||
Interactive: false,
|
||||
Links: nil,
|
||||
LinuxParameters: toLinuxParameters(service),
|
||||
LogConfiguration: &ecs.TaskDefinition_LogConfiguration{
|
||||
LogDriver: ecsapi.LogDriverAwslogs,
|
||||
Options: map[string]string{
|
||||
"awslogs-region": cloudformation.Ref("AWS::Region"),
|
||||
"awslogs-group": cloudformation.Ref("LogGroup"),
|
||||
"awslogs-stream-prefix": service.Name,
|
||||
},
|
||||
},
|
||||
Memory: toMemoryLimits(service.Deploy),
|
||||
MemoryReservation: toMemoryReservation(service.Deploy),
|
||||
MountPoints: nil,
|
||||
|
|
Loading…
Reference in New Issue