2020-06-06 01:52:00 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
|
2022-10-11 10:56:29 +00:00
|
|
|
"github.com/pulumi/pulumi-aws/sdk/v5/go/aws/ec2"
|
|
|
|
"github.com/pulumi/pulumi-aws/sdk/v5/go/aws/ecs"
|
|
|
|
"github.com/pulumi/pulumi-aws/sdk/v5/go/aws/elasticloadbalancingv2"
|
|
|
|
"github.com/pulumi/pulumi-aws/sdk/v5/go/aws/iam"
|
2021-03-17 13:20:05 +00:00
|
|
|
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
|
2020-06-06 01:52:00 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
pulumi.Run(func(ctx *pulumi.Context) error {
|
2024-02-11 17:02:12 +00:00
|
|
|
// Read the default VPC and public subnets, which we will use.
|
2020-06-06 01:52:00 +00:00
|
|
|
vpc, err := ec2.LookupVpc(ctx, &ec2.LookupVpcArgs{
|
[codegen/go] Improve optional params in invoke
As described in #8821, docs generated for helper functions can be incorrect because optional arguments to parameter objects are not correctly handled.
Previously, code would be generated like so:
```go
policyDocument, err := iam.GetPolicyDocument(ctx, &iam.GetPolicyDocumentArgs{
Statements: []iam.GetPolicyDocumentStatement{
iam.GetPolicyDocumentStatement{
Sid: "1",
//...
```
However "Sid" is of type `*string`.
This four helper conversion functions, to handle the primitive types we lower from, and modifies codegen to recursively apply these functions inside of an invoke call.
In the new code generation, the above is instead rendered as:
```go
policyDocument, err := iam.GetPolicyDocument(ctx, &iam.GetPolicyDocumentArgs{
Statements: []iam.GetPolicyDocumentStatement{
iam.GetPolicyDocumentStatement{
Sid: pulumi.StringRef("1"),
//...
```
2022-02-01 03:18:15 +00:00
|
|
|
Default: pulumi.BoolRef(true),
|
2020-06-06 01:52:00 +00:00
|
|
|
}, nil)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2020-06-18 20:34:22 +00:00
|
|
|
subnets, err := ec2.GetSubnetIds(ctx, &ec2.GetSubnetIdsArgs{
|
2020-06-06 01:52:00 +00:00
|
|
|
VpcId: vpc.Id,
|
|
|
|
}, nil)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2024-02-11 17:02:12 +00:00
|
|
|
// Create a security group that permits HTTP ingress and unrestricted egress.
|
2020-06-06 01:52:00 +00:00
|
|
|
webSecurityGroup, err := ec2.NewSecurityGroup(ctx, "webSecurityGroup", &ec2.SecurityGroupArgs{
|
|
|
|
VpcId: pulumi.String(vpc.Id),
|
|
|
|
Egress: ec2.SecurityGroupEgressArray{
|
|
|
|
&ec2.SecurityGroupEgressArgs{
|
|
|
|
Protocol: pulumi.String("-1"),
|
|
|
|
FromPort: pulumi.Int(0),
|
|
|
|
ToPort: pulumi.Int(0),
|
|
|
|
CidrBlocks: pulumi.StringArray{
|
|
|
|
pulumi.String("0.0.0.0/0"),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Ingress: ec2.SecurityGroupIngressArray{
|
|
|
|
&ec2.SecurityGroupIngressArgs{
|
|
|
|
Protocol: pulumi.String("tcp"),
|
|
|
|
FromPort: pulumi.Int(80),
|
|
|
|
ToPort: pulumi.Int(80),
|
|
|
|
CidrBlocks: pulumi.StringArray{
|
|
|
|
pulumi.String("0.0.0.0/0"),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2024-02-11 17:02:12 +00:00
|
|
|
// Create an ECS cluster to run a container-based service.
|
2020-06-06 01:52:00 +00:00
|
|
|
cluster, err := ecs.NewCluster(ctx, "cluster", nil)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
tmpJSON0, err := json.Marshal(map[string]interface{}{
|
|
|
|
"Version": "2008-10-17",
|
|
|
|
"Statement": []map[string]interface{}{
|
|
|
|
map[string]interface{}{
|
|
|
|
"Sid": "",
|
|
|
|
"Effect": "Allow",
|
|
|
|
"Principal": map[string]interface{}{
|
|
|
|
"Service": "ecs-tasks.amazonaws.com",
|
|
|
|
},
|
|
|
|
"Action": "sts:AssumeRole",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
json0 := string(tmpJSON0)
|
2024-02-11 17:02:12 +00:00
|
|
|
// Create an IAM role that can be used by our service's task.
|
2020-06-06 01:52:00 +00:00
|
|
|
taskExecRole, err := iam.NewRole(ctx, "taskExecRole", &iam.RoleArgs{
|
|
|
|
AssumeRolePolicy: pulumi.String(json0),
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2020-06-16 06:00:02 +00:00
|
|
|
_, err = iam.NewRolePolicyAttachment(ctx, "taskExecRolePolicyAttachment", &iam.RolePolicyAttachmentArgs{
|
2020-06-06 01:52:00 +00:00
|
|
|
Role: taskExecRole.Name,
|
|
|
|
PolicyArn: pulumi.String("arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"),
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2024-02-11 17:02:12 +00:00
|
|
|
// Create a load balancer to listen for HTTP traffic on port 80.
|
2020-06-06 01:52:00 +00:00
|
|
|
webLoadBalancer, err := elasticloadbalancingv2.NewLoadBalancer(ctx, "webLoadBalancer", &elasticloadbalancingv2.LoadBalancerArgs{
|
2022-11-29 00:14:07 +00:00
|
|
|
Subnets: toPulumiStringArray(subnets.Ids),
|
2020-06-06 01:52:00 +00:00
|
|
|
SecurityGroups: pulumi.StringArray{
|
|
|
|
webSecurityGroup.ID(),
|
|
|
|
},
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
webTargetGroup, err := elasticloadbalancingv2.NewTargetGroup(ctx, "webTargetGroup", &elasticloadbalancingv2.TargetGroupArgs{
|
|
|
|
Port: pulumi.Int(80),
|
|
|
|
Protocol: pulumi.String("HTTP"),
|
|
|
|
TargetType: pulumi.String("ip"),
|
|
|
|
VpcId: pulumi.String(vpc.Id),
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
webListener, err := elasticloadbalancingv2.NewListener(ctx, "webListener", &elasticloadbalancingv2.ListenerArgs{
|
|
|
|
LoadBalancerArn: webLoadBalancer.Arn,
|
|
|
|
Port: pulumi.Int(80),
|
|
|
|
DefaultActions: elasticloadbalancingv2.ListenerDefaultActionArray{
|
|
|
|
&elasticloadbalancingv2.ListenerDefaultActionArgs{
|
|
|
|
Type: pulumi.String("forward"),
|
|
|
|
TargetGroupArn: webTargetGroup.Arn,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
tmpJSON1, err := json.Marshal([]map[string]interface{}{
|
|
|
|
map[string]interface{}{
|
|
|
|
"name": "my-app",
|
|
|
|
"image": "nginx",
|
|
|
|
"portMappings": []map[string]interface{}{
|
|
|
|
map[string]interface{}{
|
|
|
|
"containerPort": 80,
|
|
|
|
"hostPort": 80,
|
|
|
|
"protocol": "tcp",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
json1 := string(tmpJSON1)
|
2024-02-11 17:02:12 +00:00
|
|
|
// Spin up a load balanced service running NGINX
|
2020-06-06 01:52:00 +00:00
|
|
|
appTask, err := ecs.NewTaskDefinition(ctx, "appTask", &ecs.TaskDefinitionArgs{
|
|
|
|
Family: pulumi.String("fargate-task-definition"),
|
|
|
|
Cpu: pulumi.String("256"),
|
|
|
|
Memory: pulumi.String("512"),
|
|
|
|
NetworkMode: pulumi.String("awsvpc"),
|
|
|
|
RequiresCompatibilities: pulumi.StringArray{
|
|
|
|
pulumi.String("FARGATE"),
|
|
|
|
},
|
|
|
|
ExecutionRoleArn: taskExecRole.Arn,
|
|
|
|
ContainerDefinitions: pulumi.String(json1),
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2020-06-16 06:00:02 +00:00
|
|
|
_, err = ecs.NewService(ctx, "appService", &ecs.ServiceArgs{
|
2020-06-06 01:52:00 +00:00
|
|
|
Cluster: cluster.Arn,
|
|
|
|
DesiredCount: pulumi.Int(5),
|
|
|
|
LaunchType: pulumi.String("FARGATE"),
|
|
|
|
TaskDefinition: appTask.Arn,
|
|
|
|
NetworkConfiguration: &ecs.ServiceNetworkConfigurationArgs{
|
|
|
|
AssignPublicIp: pulumi.Bool(true),
|
2022-11-29 00:14:07 +00:00
|
|
|
Subnets: toPulumiStringArray(subnets.Ids),
|
2020-06-06 01:52:00 +00:00
|
|
|
SecurityGroups: pulumi.StringArray{
|
|
|
|
webSecurityGroup.ID(),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
LoadBalancers: ecs.ServiceLoadBalancerArray{
|
|
|
|
&ecs.ServiceLoadBalancerArgs{
|
|
|
|
TargetGroupArn: webTargetGroup.Arn,
|
|
|
|
ContainerName: pulumi.String("my-app"),
|
|
|
|
ContainerPort: pulumi.Int(80),
|
|
|
|
},
|
|
|
|
},
|
2020-06-29 23:33:52 +00:00
|
|
|
}, pulumi.DependsOn([]pulumi.Resource{
|
|
|
|
webListener,
|
|
|
|
}))
|
2020-06-06 01:52:00 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
ctx.Export("url", webLoadBalancer.DnsName)
|
|
|
|
return nil
|
|
|
|
})
|
|
|
|
}
|
2022-11-29 00:14:07 +00:00
|
|
|
func toPulumiStringArray(arr []string) pulumi.StringArray {
|
|
|
|
var pulumiArr pulumi.StringArray
|
|
|
|
for _, v := range arr {
|
|
|
|
pulumiArr = append(pulumiArr, pulumi.String(v))
|
|
|
|
}
|
|
|
|
return pulumiArr
|
|
|
|
}
|