Skip to content

Commit 37b1494

Browse files
committed
wip
1 parent b16c319 commit 37b1494

File tree

357 files changed

+153946
-295
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

357 files changed

+153946
-295
lines changed

Makefile

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
TEST?=$$(go list ./... | grep -v 'vendor')
22
HOSTNAME=github.com
3-
NAMESPACE=DavidGOrtega
3+
NAMESPACE=iterative
44
NAME=iterative
5-
VERSION=0.3
5+
VERSION=0.6
66
#OS_ARCH=linux_amd64
77
OS_ARCH=darwin_amd64
88
BINARY=terraform-provider-${NAME}
9-
VERSION2=0.3.3
109

1110
default: install
1211

go.mod

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,13 @@ module terraform-provider-iterative
33
go 1.14
44

55
require (
6+
github.com/Azure-Samples/azure-sdk-for-go-samples v0.0.0-20201110054206-ffcdafe9818d // indirect
7+
github.com/Azure/azure-sdk-for-go v49.0.0+incompatible
8+
github.com/Azure/go-autorest/autorest v0.11.13 // indirect
9+
github.com/Azure/go-autorest/autorest/azure/auth v0.5.3
10+
github.com/Azure/go-autorest/autorest/to v0.4.0
611
github.com/aws/aws-sdk-go v1.34.13
712
github.com/hashicorp/terraform-plugin-sdk/v2 v2.0.1
813
github.com/teris-io/shortid v0.0.0-20171029131806-771a37caa5cf
14+
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0
915
)

go.sum

Lines changed: 142 additions & 0 deletions
Large diffs are not rendered by default.

iterative/aws/provider.go

Lines changed: 284 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,284 @@
1+
package aws
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"sort"
7+
"time"
8+
9+
"github.com/aws/aws-sdk-go/aws"
10+
"github.com/aws/aws-sdk-go/aws/session"
11+
"github.com/aws/aws-sdk-go/service/ec2"
12+
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
13+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
14+
)
15+
16+
//ResourceMachineCreate creates AWS instance
17+
func ResourceMachineCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
18+
var diags diag.Diagnostics
19+
20+
instanceName := d.Get("instance_name").(string)
21+
hddSize := d.Get("instance_hdd_size").(int)
22+
region := getRegion(d)
23+
instanceType := getInstanceType(d)
24+
25+
svc, errClient := awsClient(region)
26+
if errClient != nil {
27+
return diag.FromErr(errClient)
28+
}
29+
30+
// Image
31+
ami := d.Get("ami").(string)
32+
imagesRes, imagesErr := svc.DescribeImages(&ec2.DescribeImagesInput{
33+
Filters: []*ec2.Filter{
34+
{
35+
Name: aws.String("name"),
36+
Values: []*string{aws.String(ami)},
37+
},
38+
{
39+
Name: aws.String("architecture"),
40+
Values: []*string{aws.String("x86_64")},
41+
},
42+
},
43+
})
44+
if imagesErr != nil {
45+
return diag.FromErr(imagesErr)
46+
}
47+
if len(imagesRes.Images) == 0 {
48+
diags = append(diags, diag.Diagnostic{
49+
Severity: diag.Error,
50+
Summary: ami + " ami not found in region",
51+
})
52+
53+
return diags
54+
}
55+
56+
sort.Slice(imagesRes.Images, func(i, j int) bool {
57+
itime, _ := time.Parse(time.RFC3339, aws.StringValue(imagesRes.Images[i].CreationDate))
58+
jtime, _ := time.Parse(time.RFC3339, aws.StringValue(imagesRes.Images[j].CreationDate))
59+
return itime.Unix() > jtime.Unix()
60+
})
61+
62+
instanceAmi := *imagesRes.Images[0].ImageId
63+
pairName := instanceName
64+
65+
// key-pair
66+
keyPublic := d.Get("key_public").(string)
67+
svc.ImportKeyPair(&ec2.ImportKeyPairInput{
68+
KeyName: aws.String(pairName),
69+
PublicKeyMaterial: []byte(keyPublic),
70+
})
71+
72+
// securityGroup
73+
var vpcID, sgID string
74+
75+
securityGroup := d.Get("aws_security_group").(string)
76+
if len(securityGroup) == 0 {
77+
securityGroup = "cml"
78+
79+
vpcsDesc, _ := svc.DescribeVpcs(&ec2.DescribeVpcsInput{})
80+
vpcID = *vpcsDesc.Vpcs[0].VpcId
81+
82+
gpResult, ee := svc.CreateSecurityGroup(&ec2.CreateSecurityGroupInput{
83+
GroupName: aws.String(securityGroup),
84+
Description: aws.String("CML security group"),
85+
VpcId: aws.String(vpcID),
86+
})
87+
88+
if ee == nil {
89+
ipPermissions := []*ec2.IpPermission{
90+
(&ec2.IpPermission{}).
91+
SetIpProtocol("-1").
92+
SetFromPort(-1).
93+
SetToPort(-1).
94+
SetIpRanges([]*ec2.IpRange{
95+
{CidrIp: aws.String("0.0.0.0/0")},
96+
}),
97+
}
98+
99+
svc.AuthorizeSecurityGroupIngress(&ec2.AuthorizeSecurityGroupIngressInput{
100+
GroupId: aws.String(*gpResult.GroupId),
101+
IpPermissions: ipPermissions,
102+
})
103+
104+
svc.AuthorizeSecurityGroupEgress(&ec2.AuthorizeSecurityGroupEgressInput{
105+
GroupId: aws.String(*gpResult.GroupId),
106+
IpPermissions: ipPermissions,
107+
})
108+
}
109+
}
110+
111+
sgDesc, sgDescErr := svc.DescribeSecurityGroupsWithContext(ctx, &ec2.DescribeSecurityGroupsInput{
112+
Filters: []*ec2.Filter{
113+
{
114+
Name: aws.String("group-name"),
115+
Values: []*string{aws.String(securityGroup)},
116+
},
117+
},
118+
})
119+
if sgDescErr != nil {
120+
return diag.FromErr(sgDescErr)
121+
}
122+
123+
sgID = *sgDesc.SecurityGroups[0].GroupId
124+
vpcID = *sgDesc.SecurityGroups[0].VpcId
125+
126+
subDesc, _ := svc.DescribeSubnetsWithContext(ctx, &ec2.DescribeSubnetsInput{
127+
Filters: []*ec2.Filter{
128+
{
129+
Name: aws.String("vpc-id"),
130+
Values: []*string{aws.String(vpcID)},
131+
},
132+
},
133+
})
134+
135+
//launch instance
136+
runResult, err := svc.RunInstancesWithContext(ctx, &ec2.RunInstancesInput{
137+
ImageId: aws.String(instanceAmi),
138+
KeyName: aws.String(pairName),
139+
InstanceType: aws.String(instanceType),
140+
MinCount: aws.Int64(1),
141+
MaxCount: aws.Int64(1),
142+
SecurityGroupIds: []*string{aws.String(sgID)},
143+
SubnetId: aws.String(*subDesc.Subnets[0].SubnetId),
144+
BlockDeviceMappings: []*ec2.BlockDeviceMapping{
145+
{
146+
//VirtualName: aws.String("Root"),
147+
DeviceName: aws.String("/dev/sda1"),
148+
Ebs: &ec2.EbsBlockDevice{
149+
DeleteOnTermination: aws.Bool(true),
150+
Encrypted: aws.Bool(false),
151+
//Iops: aws.Int64(0),
152+
VolumeSize: aws.Int64(int64(hddSize)),
153+
VolumeType: aws.String("gp2"),
154+
},
155+
},
156+
},
157+
})
158+
if err != nil {
159+
diags = append(diags, diag.Diagnostic{
160+
Severity: diag.Error,
161+
Summary: "Unable to create instance",
162+
Detail: fmt.Sprintf("[ERROR] Instance %s of type %s at region %s", instanceName, instanceType, region),
163+
})
164+
165+
diags = append(diags, diag.FromErr(err)[0])
166+
167+
return diags
168+
}
169+
170+
instanceID := *runResult.Instances[0].InstanceId
171+
172+
// Add name to the created instance
173+
_, errTag := svc.CreateTags(&ec2.CreateTagsInput{
174+
Resources: []*string{aws.String(instanceID)},
175+
Tags: []*ec2.Tag{
176+
{
177+
Key: aws.String("Name"),
178+
Value: aws.String(instanceName),
179+
},
180+
},
181+
})
182+
if errTag != nil {
183+
return diag.FromErr(errTag)
184+
}
185+
186+
statusInput := ec2.DescribeInstancesInput{
187+
InstanceIds: []*string{aws.String(instanceID)},
188+
Filters: []*ec2.Filter{
189+
{
190+
Name: aws.String("instance-state-name"),
191+
Values: []*string{aws.String("running")},
192+
},
193+
},
194+
}
195+
196+
svc.WaitUntilInstanceExistsWithContext(ctx, &statusInput)
197+
198+
descResult, _ := svc.DescribeInstancesWithContext(ctx, &statusInput)
199+
instanceDesc := descResult.Reservations[0].Instances[0]
200+
201+
d.SetId(instanceID)
202+
d.Set("instance_id", instanceID)
203+
d.Set("key_name", pairName)
204+
205+
d.Set("instance_name", instanceName)
206+
d.Set("instance_ip", instanceDesc.PublicIpAddress)
207+
d.Set("instance_launch_time", instanceDesc.LaunchTime.Format(time.RFC3339))
208+
209+
return diags
210+
}
211+
212+
//ResourceMachineDelete deletes AWS instance
213+
func ResourceMachineDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
214+
var diags diag.Diagnostics
215+
216+
svc, _ := awsClient(getRegion(d))
217+
218+
pairName := d.Get("key_name").(string)
219+
instanceID := d.Get("instance_id").(string)
220+
221+
svc.DeleteKeyPair(&ec2.DeleteKeyPairInput{
222+
KeyName: aws.String(pairName),
223+
})
224+
225+
input := &ec2.TerminateInstancesInput{
226+
InstanceIds: []*string{
227+
aws.String(instanceID),
228+
},
229+
DryRun: aws.Bool(false),
230+
}
231+
232+
_, err := svc.TerminateInstances(input)
233+
234+
if err != nil {
235+
return diag.FromErr(err)
236+
}
237+
238+
return diags
239+
}
240+
241+
func awsClient(region string) (*ec2.EC2, error) {
242+
sess, err := session.NewSession(&aws.Config{
243+
Region: aws.String(region),
244+
//Credentials: credentials.NewStaticCredentials(conf.AWS_ACCESS_KEY_ID, conf.AWS_SECRET_ACCESS_KEY, ""),
245+
})
246+
247+
svc := ec2.New(sess)
248+
return svc, err
249+
}
250+
251+
func getRegion(d *schema.ResourceData) string {
252+
instanceRegions := make(map[string]string)
253+
instanceRegions["us-east"] = "us-east-1"
254+
instanceRegions["us-west"] = "us-west-1"
255+
instanceRegions["eu-north"] = "eu-north-1"
256+
instanceRegions["eu-west"] = "eu-west-1"
257+
258+
region := d.Get("region").(string)
259+
if val, ok := instanceRegions[region]; ok {
260+
region = val
261+
}
262+
263+
return region
264+
}
265+
266+
func getInstanceType(d *schema.ResourceData) string {
267+
instanceTypes := make(map[string]string)
268+
instanceTypes["m"] = "m5.2xlarge"
269+
instanceTypes["l"] = "m5.8xlarge"
270+
instanceTypes["xl"] = "m5.16xlarge"
271+
instanceTypes["mk80"] = "p2.xlarge"
272+
instanceTypes["lk80"] = "p2.8xlarge"
273+
instanceTypes["xlk80"] = "p2.16xlarge"
274+
instanceTypes["mtesla"] = "p3.xlarge"
275+
instanceTypes["ltesla"] = "p3.8xlarge"
276+
instanceTypes["xltesla"] = "p3.16xlarge"
277+
278+
instanceType := d.Get("instance_type").(string)
279+
if val, ok := instanceTypes[instanceType+d.Get("instance_gpu").(string)]; ok {
280+
instanceType = val
281+
}
282+
283+
return instanceType
284+
}

0 commit comments

Comments
 (0)